Tutorial: Implemente uma aplicação de exemplo e teste a sua resiliência de zonas com o Chaos Studio

Neste tutorial, implementa uma aplicação de retalho de exemplo para um cluster redundante do Azure Kubernetes Service (AKS) e depois usa um espaço de trabalho do Azure Chaos Studio para simular duas vezes uma falha na zona de disponibilidade. A primeira execução expõe uma falha real de resiliência: o front-end da aplicação está deliberadamente associado a uma única zona, pelo que a frente de loja fica indisponível quando essa zona falha. Depois corrige a implementação, executa o mesmo cenário novamente e observa a aplicação a passar pela falha. Ao longo do caminho, inicia um monitor baseado no navegador que mostra a falha e a correção à medida que acontecem, e percebe porque é que a disponibilidade da loja e o estado do nó do cluster não mudam ao mesmo tempo.

Este tutorial é um bom primeiro exemplo e reutiliza a aplicação de exemplo AKS store demo dos guias de início rápido do AKS, pelo que não é necessário nenhum registo de contentores nem qualquer passo de compilação. Reserve cerca de uma hora: criação do cluster e duas execuções de cenário de cerca de 5 minutos cada.

Importante

Os Espaços de Trabalho e Cenários do Chaos Studio estão em pré-visualização pública. A Microsoft disponibiliza esta pré-visualização "tal qual" e "conforme disponível", e não está coberta por acordos de nível de serviço nem garantia limitada. A Microsoft fornece suporte ao cliente para a versão preliminar na medida do possível. Esta pré-visualização não é para uso em produção. Para obter mais informações, consulte os seguintes artigos:

Neste tutorial, aprenderás como:

  • Crie um cluster AKS cujos nós abrangem três zonas de disponibilidade.
  • Implemente a aplicação de exemplo de demonstração da loja AKS e fixe a sua interface numa zona para uma demonstração determinística.
  • Inicie um monitor no navegador que acompanha a loja, o nó de destino e o posicionamento do pod em tempo real.
  • Crie um espaço de trabalho no âmbito do grupo de recursos de infraestrutura do cluster.
  • Execute o cenário Compute Zone Down e observe a falha da aplicação.
  • Corrige a implantação com um contrato rígido de colocação por zona, verifica-a e executa novamente o cenário.
  • Compare os dois relatórios de cenários.

Este tutorial privilegia uma demonstração funcional. Para conhecer os conceitos subjacentes a cada passo, as advertências sobre a interrupção da infraestrutura que o AKS gere por si e como interpretar os resultados numa carga de trabalho real, consulte Testar a resiliência da carga de trabalho no AKS com o Chaos Studio.

Pré-requisitos

  • Uma assinatura do Azure. Se não tiver uma conta do Azure, crie uma conta gratuita antes de começar.
  • CLI do Azure, kubectl, kubelogin, e Python 3 (apenas biblioteca padrão - sem pacotes para instalar). O Azure Cloud Shell tem os quatro pré-instalados. Se trabalhares localmente, instala kubectl com az aks install-cli e kubelogin separadamente.
  • Microsoft.Chaos fornecedor de recursos registado na sua subscrição. Para o registar pela primeira vez, consulte Registar o fornecedor de recursos do Chaos Studio.

Criar um cluster AKS redundante por zonas

Um teste de falha de zona só tem sentido contra um cluster construído para sobreviver a um, por isso cria um cluster com três nós distribuídos por três zonas de disponibilidade. Este exemplo utiliza o East US 2; qualquer região com zonas de disponibilidade funciona.

  1. Crie um grupo de recursos e o cluster:

    az group create --name chaos-demo-rg --location eastus2
    
    az aks create \
      --resource-group chaos-demo-rg \
      --name chaos-demo-aks \
      --node-count 3 \
      --zones 1 2 3 \
      --generate-ssh-keys
    

    A criação do cluster demora alguns minutos.

  2. Numa sessão nova do Cloud Shell, kubectl ainda não está ligado a nenhum cluster. Defina a sua subscrição, obtenha credenciais e converta o kubeconfig para autenticação Microsoft Entra antes de executar qualquer kubectl comando:

    az account set --subscription <SUBSCRIPTION_ID>
    az aks get-credentials --resource-group chaos-demo-rg --name chaos-demo-aks
    kubelogin convert-kubeconfig -l azurecli
    

    Substitua o seu ID de subscrição por <SUBSCRIPTION_ID>. Ignora az account set se a subscrição já for a tua ativa. O kubelogin passo é necessário mesmo numa sessão Cloud Shell nova – sem ele, o primeiro kubectl comando contra um cluster autenticado pelo Entra falha com um erro de autenticação.

  3. Verifique se os nós abrangem três zonas:

    kubectl get nodes -L topology.kubernetes.io/zone
    

    A coluna ZONE mostra um nó em cada zona, como eastus2-1, eastus2-2 e eastus2-3. O número da zona após o nome da região é o que se direciona mais tarde na configuração do cenário.

Implementar o exemplo de aplicação

A demo da loja AKS é uma pequena loja de retalho com uma interface web, um serviço de produto, um serviço de encomendas e uma fila RabbitMQ. As imagens dos contentores são públicas, por isso podes implementá-las com um único comando.

  1. Implante o aplicativo:

    kubectl apply -f https://raw.githubusercontent.com/Azure-Samples/aks-store-demo/2.2.0/aks-store-quickstart.yaml
    

    O manifesto implanta cada componente com uma única réplica. O cluster é redundante em zonas, mas a aplicação não é. Este tutorial expõe e depois corrige esta lacuna de resiliência.

  2. Espere que o front-end obtenha um endereço IP público:

    kubectl get service store-front --watch
    

    Quando o EXTERNAL-IP valor mudar de <pending> para um endereço IP público, pressione Ctrl+C para parar o relógio.

  3. Abra http://<EXTERNAL-IP> num navegador e confirme que a loja carrega. Mantenha este separador aberto. É uma visão secundária do estado da aplicação durante o teste – o monitor que lanças mais tarde é o principal.

Para saber como a própria aplicação é construída e implementada, consulte a série de tutoriais do AKS.

Fixe o frontend a uma única zona para uma demo determinística

Note

Fixar uma única réplica numa zona é uma configuração de ensino deliberada para esta demonstração, não uma recomendação de produção. Uma implementação em produção nunca deve restringir uma única réplica a uma única zona – isso remove a redundância para a qual o cluster foi construído. Este tutorial faz isso de propósito para que a falha na primeira execução seja fiável e repetível, em vez de depender da zona escolhida pelo agendador.

Sem um pin deliberado, o agendador pode colocar a réplica única do front end em qualquer zona, e um reagendamento simples pode acontecer rapidamente o suficiente para que o impacto seja fácil de ignorar. Fixar a réplica numa zona conhecida torna o alvo previsível e a falha observável sempre que executas a demonstração.

  1. Encontre o nó onde o pod store-front está atualmente em execução e leia o rótulo de zona desse nó:

    STORE_NODE="$(kubectl get pods -l app=store-front -o jsonpath='{.items[0].spec.nodeName}')"
    PIN_ZONE="$(kubectl get node "$STORE_NODE" -o jsonpath="{.metadata.labels['topology\.kubernetes\.io/zone']}")"
    echo "$PIN_ZONE"
    

    PIN_ZONE é a etiqueta de zona completa, como eastus2-1. Mantém esta sessão de shell aberta – reutilizas este valor para o monitor, e mais tarde para a configuração do cenário (que pede apenas o número, a parte após o último hífen – por exemplo, 1 em eastus2-1).

  2. Aplique um patch à implantação store-front para exigir a calendarização nessa zona e adicione uma anotação que assinale o patch como um padrão destinado apenas a demonstração:

    kubectl patch deployment store-front --patch "$(cat <<EOF
    {
      "metadata": {
        "annotations": {
          "chaos-demo.aks-zone-down-demo/deliberate-anti-pattern": "Pins the single front-end replica to zone ${PIN_ZONE} so run 1 is deterministic. Removed as part of the fix later in this tutorial - do not carry this pin into a real deployment."
        }
      },
      "spec": {
        "template": {
          "spec": {
            "affinity": {
              "nodeAffinity": {
                "requiredDuringSchedulingIgnoredDuringExecution": {
                  "nodeSelectorTerms": [
                    {
                      "matchExpressions": [
                        {"key": "topology.kubernetes.io/zone", "operator": "In", "values": ["${PIN_ZONE}"]}
                      ]
                    }
                  ]
                }
              }
            }
          }
        }
      }
    }
    EOF
    )"
    
    kubectl rollout restart deployment/store-front
    kubectl rollout status deployment/store-front --timeout=300s
    
  3. Confirme que a afixação foi mantida — a réplica deve estar novamente num nó em $PIN_ZONE:

    STORE_NODE="$(kubectl get pods -l app=store-front -o jsonpath='{.items[0].spec.nodeName}')"
    STORE_ZONE="$(kubectl get node "$STORE_NODE" -o jsonpath="{.metadata.labels['topology\.kubernetes\.io/zone']}")"
    echo "Pod is in zone: $STORE_ZONE (expected $PIN_ZONE)"
    

    Se os dois valores não corresponderem, repita o passo anterior — a execução 1 não será determinística até que correspondam.

Descarregue e inicie o monitor de demonstração

Um relógio apenas kubectl com terminal é demasiado lento e fácil de perder durante uma demonstração ao vivo. O sinal da própria loja não se move em sintonia com o do cluster. Este tutorial utiliza um pequeno script de monitor em Python do repositório de samples do Chaos Studio como principal forma de ver a execução.

  1. Descarregue o monitor e o script de verificação de correções:

    curl -O https://raw.githubusercontent.com/microsoft/chaos-studio/f9573c943694e88cf3aacbca38debe84fa91a62c/samples/aks-zone-down-demo/monitor.py
    curl -O https://raw.githubusercontent.com/microsoft/chaos-studio/f9573c943694e88cf3aacbca38debe84fa91a62c/samples/aks-zone-down-demo/verify-fix.sh
    chmod +x verify-fix.sh
    

    Estes links são fixados a um commit específico para continuarem a funcionar independentemente das alterações futuras à amostra. Assim que o pull request em causa for integrado, as revisões posteriores deste tutorial podem passar a usar uma versão etiquetada.

  2. Inicia o monitor, apontando-o para o IP externo da loja e para a zona que fixaste na secção anterior:

    python3 monitor.py --storefront-url http://<EXTERNAL-IP> --target-zone "$PIN_ZONE"
    

    O monitor usa apenas a biblioteca padrão Python, por isso não há mais nada para instalar. Por defeito, verifica a cada 5 segundos - configurável com --interval ou com a variável de ambiente MONITOR_INTERVAL_SECONDS. Essa predefinição ocorre com frequência suficiente para resolver a ordenação dos sinais sem consultar a API do Kubernetes nem a loja online de forma demasiado agressiva.

  3. No Cloud Shell, selecione Web Preview e defina a porta para 8787 para abrir o monitor num separador do navegador. Se estiver a correr localmente, abra http://localhost:8787 em vez disso.

    A página do monitor é agora a tua vista principal para ambas as corridas. Mostra quatro sinais:

    • Estado HTTP da loja - um pedido com erro de cache contra a loja, para que veja um estado ao vivo acessível/inacessível em vez de um sucesso em cache.
    • Estado do nó da zona-alvo - quer o nó na sua zona alvo seja Ready ou NotReady.
    • Colocação front-end dos pods - quais store-front pods estão a funcionar e em que zona cada um está.
    • Histórico de transições - uma cronologia contínua de cada alteração de estado acima, com marcas temporais, para que possas rever a sequência após o fim da execução, em vez de dependeres do que notaste em tempo real.

    Se uma sondagem contra kubectl ou a API Kubernetes falhar – por exemplo, o servidor da API ficar brevemente inacessível ou o kubeconfig ficar obsoleto – o monitor mostra um banner vermelho visível a indicar o erro, em vez de deixar o sinal afetado preso num marcador de "verificação". O resto do painel continua a mostrar o seu último estado conhecido e a sua história enquanto o banner está no ar. Trate o banner como um sinal por si só: significa que o monitor perdeu visibilidade, não que o que está a ver seja saudável.

Crie um espaço de trabalho no âmbito do grupo de recursos de infraestrutura

O AKS coloca os conjuntos de dimensionamento de máquinas virtuais dos nós do cluster num grupo de recursos de infraestrutura separado (com um nome começado por MC_ por predefinição), e não no grupo de recursos que contém o recurso de cluster. Limite o âmbito do espaço de trabalho ao grupo de recursos de infraestrutura para descobrir os nós. Para obter contexto, veja Porque é que uma área de trabalho limitada ao seu cluster do AKS não encontra destinos de computação.

  1. Encontre o nome do grupo de recursos de infraestrutura:

    az aks show --resource-group chaos-demo-rg --name chaos-demo-aks --query nodeResourceGroup -o tsv
    
  2. No portal Azure, procura Chaos Studio, seleciona Espaços de Trabalho e depois seleciona Criar.

  3. No separador Básicos , selecione o chaos-demo-rg grupo de recursos, nomeie o espaço de trabalho chaos-demo-workspacee escolha uma região suportada. A região do workspace não precisa de corresponder à região do cluster.

  4. No separador Scopo , selecione Resource group como o tipo de scope e depois selecione o infrastructure resource group a partir do passo 1.

  5. No separador Identidade , escolha Atribuído ao Sistema.

  6. Selecione Rever e criar>Criar e, em seguida, Ir para o recurso.

    Após a conclusão da descoberta, o conjunto de escala da máquina virtual de nós do cluster (nomeado como aks-nodepool1-12345678-vmss) aparece como um recurso descoberto.

  7. Se o portal mostrar um banner a indicar que a identidade não tem permissões de leitura no âmbito do espaço de trabalho, selecione Atribuir a função Leitor no âmbito do Espaço de Trabalho. Para criar atribuições de funções, precisa de direitos de Proprietário ou Administrador de Acesso ao Utilizador no grupo de recursos de infraestrutura.

Atribuis à identidade as funções de que o próprio cenário precisa na secção seguinte, onde a validação lhe indica exatamente o que está em falta. Para um percurso completo de cada etapa de criação do espaço de trabalho, consulte o início rápido do espaço de trabalho.

Executa o cenário e vê a aplicação falhar

O cenário Compute Zone Down simula uma falha numa zona de disponibilidade, desligando as instâncias do conjunto de dimensionamento de máquinas virtuais numa zona de destino durante o período configurado. As instâncias reiniciam quando termina a duração da ação.

  1. No espaço de trabalho, selecione Cenários e, em seguida, selecione Compute Zone Down na biblioteca de cenários.

  2. Configura o cenário. Para a zona de disponibilidade, introduza o número de $PIN_ZONE (a parte após o último hífen, por exemplo 1 em eastus2-1). Defina a duração para 5 minutos – tempo suficiente para que os sinais do frontend, do nó e do pod estabilizem, sem uma espera excessiva. Este valor de 5 minutos foi definido para esta demonstração específica; outros tipos de cenários têm as suas próprias orientações quanto à duração, em função do que testam. Por exemplo, um cenário construído em torno do comportamento da cache DNS precisa de uma duração suficientemente longa para exceder o TTL da cache do registo, que pode ser muito superior a 5 minutos. Selecione Salvar configuração.

  3. A validação verifica se a identidade gerida do espaço de trabalho consegue executar todas as ações necessárias pelo cenário sobre os recursos-alvo. Se a validação reportar permissões em falta, selecione Corrigir Permissões na página de configuração do cenário para atribuir à identidade as funções incorporadas recomendadas. Neste cenário, trata-se da função Virtual Machine Contributor no conjunto de dimensionamento de máquinas virtuais do nó. Para atribuir os papéis por si próprio, ou para usar papéis personalizados com privilégio mínimo em vez de papéis incorporados, consulte Permissões e identidade nos Workspaces do Chaos Studio e Use papéis personalizados com privilégio mínimo com os Workspaces do Chaos Studio.

    Se uma função obrigatória continuar em falta no momento da execução, a execução é iniciada ainda assim, mas as ações de encerramento falham com um erro de permissões no relatório do cenário.

  4. Seleciona Executar e confirma.

Pode demorar alguns minutos depois do início da corrida para o desligamento fazer efeito, por isso não se alarme se nada mudar imediatamente no monitor. Em seguida, observe a página de monitorização:

  • O sinal HTTP da loja e o estado do nó alvo não mudam ao mesmo tempo. O sinal ao nível da aplicação é aquilo que os seus utilizadores realmente sentem na prática e deve ser considerado o principal; os sinais do nó e do pod são mecanismos internos de registo do cluster que só acompanham a situação mais tarde. É de esperar que a montra apresente um estado visivelmente inacessível antes de o nó apresentar NotReady — esse intervalo é normal, devido à propagação assíncrona do sinal, e não é um problema da demonstração.
  • O estado do nó alvo muda para NotReady.
  • Como a frente está fixada nessa zona, a sua única réplica não tem outro sítio onde possa correr. A loja permanece inacessível até que o Kubernetes possa reagendar o pod – o que, com o pino no lugar, só acontece quando o nó alvo regressa ou quando mudas a restrição de posicionamento. Não dependa de um número fixo de tempo de inatividade aqui; Veja o histórico de transições do monitor para saber o que realmente aconteceu durante a sua corrida.

Este resultado é a conclusão. O cluster tinha redundância entre zonas, mas a opção de colocação da aplicação transformou uma falha de zona numa interrupção sem fim definido enquanto a restrição se mantivesse em vigor. O histórico de alterações de estado do monitor é o registo exato dos momentos em que a loja ficou indisponível e, mais tarde, em que voltou a ficar disponível.

Resolução de problemas: o impacto não é visível

Se o monitor mostrar que a loja online permanece acessível durante toda a execução 1, verifique estes itens antes de assumir que o cenário não funcionou:

  • Confirme que a afixação foi aplicada. Executa kubectl get pods -l app=store-front -o wide e verifica se o nó do pod está em $PIN_ZONE. Se o patch não se aplicava, o agendador poderia ter colocado a réplica noutro local. Um simples reagendamento durante a interrupção pode ser rápido o suficiente para que não o perca sem o PIN.
  • Confirma que o monitor está a vigiar a zona e URL corretas. Reinicia monitor.py com o valor exato --target-zone e a URL da loja do teu cluster. Um valor obsoleto ou mal digitado indica um estado "saudável" enganador.
  • Consulte o relatório de cenário para as ações Skipped. Se as ações de desligamento mostrarem Skipped em vez de Succeeded, a execução não encontrou alvos correspondentes na zona-alvo. Veja Interpretar os resultados.
  • Espera mais uns segundos. A própria ação de desligamento demora pouco tempo a produzir efeito depois de a execução ser iniciada. O histórico de transições do monitor apresenta as marcas temporais exatas depois de estas ocorrerem.

Corrige a implementação e verifica

Agora substitua a afixação deliberada a uma única zona por uma solução real, à escala de todo o cluster: três réplicas, estritamente restringidas a uma por zona.

  1. Remova o marcador da zona que adicionou anteriormente:

    kubectl patch deployment store-front --type=merge --patch '{"spec":{"template":{"spec":{"affinity":null}}}}'
    
  2. Dimensione o frontend para três réplicas e adicione uma restrição de distribuição topológica que requeira uma réplica por zona, em vez de apenas a preferir:

    kubectl patch deployment store-front --patch '{"spec":{"replicas":3,"template":{"spec":{"topologySpreadConstraints":[{"maxSkew":1,"topologyKey":"topology.kubernetes.io/zone","whenUnsatisfiable":"DoNotSchedule","labelSelector":{"matchLabels":{"app":"store-front"}}}]}}}}'
    

    whenUnsatisfiable: DoNotSchedule Torna a distribuição de uma réplica por zona um requisito rígido. Uma réplica que não consegue cumprir esse requisito permanece em Pending em vez de ser colocada numa zona que já tem uma réplica. É um compromisso deliberado — garante a cobertura das zonas de que este teste depende, à custa de uma réplica poder ficar por agendar se, temporariamente, uma zona não tiver espaço. ScheduleAnyway permitiria ao escalonador ignorar a restrição sob pressão, que é exatamente o modo de falha que esta correção elimina.

  3. Verifica a solução antes de confiares nela. Executa o script de verificação. Aguarda a conclusão da implementação para que os pods antigos da revisão anterior com uma única réplica não sejam contados e, em seguida, confirma que cada zona tem pelo menos um pod Readystore-front:

    ./verify-fix.sh
    

    Uma kubectl chamada, um pedido de API ou o JSON que devolve podem falhar temporariamente – um breve timeout, uma ligação perdida – sem significar que a correção em si falhou. O script volta a tentar quando ocorrem estas falhas transitórias até atingir o seu próprio tempo limite, em vez de terminar após a primeira falha. Só depois de decorrido esse tempo limite é que termina com um código de saída diferente de zero e uma mensagem de diagnóstico indicando qual a zona onde ainda falta uma réplica pronta. Não prossigas para executar o 2 até que este seja aprovado. Um resultado positivo é o que faz de "uma réplica por zona" um facto verificado, em vez de uma suposição herdada do comando patch.

Repete o cenário e compara

  1. No espaço de trabalho, execute novamente o cenário Compute Zone Down com a mesma zona-alvo e a mesma duração de 5 minutos.

  2. Vê o monitor. O nó de destino ainda NotReady e arrasta a store-front réplica consigo, mas a loja online continua a responder, sendo servida pelas réplicas nas zonas que permanecem ativas. A alegação em análise é disponibilidade sustentada durante a falha da zona, comprovada pelo histórico contínuo do monitor — não a ausência total de pedidos perdidos, nem que o monitor apresente um estado saudável ininterrupto durante todo o período. Ainda pode ocorrer uma breve interrupção enquanto o Balanceador de Carga do Azure converge para as restantes réplicas em bom estado; uma execução pontual mostra uma breve oscilação durante a convergência, não uma indisponibilidade que dure toda a interrupção. O tempo que essa convergência demora varia consoante o ambiente, por isso não confies num limite temporal fixo – usa o histórico de transição do monitor para distinguir um sinal transitório de uma falha prolongada.

Componentes de réplica única ainda podem sofrer uma breve perturbação. Se o nó da fila RabbitMQ estiver na zona-alvo, a submissão das encomendas fica degradada enquanto o respetivo pod recupera. Encontrar o próximo componente mais fraco, e decidir se vale a pena corrigir, é exatamente o ciclo que os testes de caos pretendem provocar.

Compare os relatórios de cenários

  1. No espaço de trabalho, selecione Histórico de Execução. Agora tens duas corridas completas do mesmo cenário.

  2. Seleciona cada execução e depois seleciona Gerar relatório. Confirme que as ações de desligamento mostram o estado Bem-sucedido em ambas, o que significa que cada execução encontrou e interrompeu instâncias na zona de destino. Se as ações aparecerem como Ignorado, a execução não encontrou alvos correspondentes. As causas habituais são um âmbito que não inclui o grupo de recursos de infraestrutura ou uma zona-alvo sem nós. Para mais informações, veja Testes sobre resiliência da carga de trabalho no AKS com Chaos Studio.

  3. Note que ambos os relatórios parecem iguais, mesmo que os resultados da candidatura tenham sido opostos. Bem-sucedido significa que a perturbação foi aplicada — não significa que a aplicação permaneceu estável. O relatório prova que perturbação aconteceu e quando; O histórico de transições do monitor é o que comprova o comportamento da aplicação em resposta. Combinar ambos é assim que transformas uma execução em evidência: o relatório regista a falha com data e hora, e o monitor mostra a diferença antes e depois introduzida pela correção.

Pode descarregar ambos os relatórios como evidências antes e depois para revisões de resiliência. Para detalhes, consulte Relatórios de Cenários.

Limpeza de recursos

Elimine o grupo de recursos para remover o cluster, a aplicação de exemplo e o espaço de trabalho. Eliminar o cluster também elimina o seu grupo de recursos de infraestrutura.

az group delete --name chaos-demo-rg --yes --no-wait

Comunicar problemas e solicitar funcionalidades

Azure Chaos Studio é desenvolvido ao ar livre. Para reportar um bug, pedir uma funcionalidade ou colocar uma questão sobre Workspaces, Cenários ou a extensão CLI do Azure, abra uma questão no repositório Chaos Studio no GitHub. Ao apresentar uma reclamação, pode acompanhar o seu progresso e ver pedidos de outros clientes.

Passos seguintes