Laboratório de Troubleshooting: Provision a container by using Azure Container Apps
Cenários de Diagnóstico
Cenário 1 — Causa Raiz
A equipe de plataforma implantou um container app em produção utilizando o plano de consumo. O ambiente foi criado há três semanas e hospeda outras quatro aplicações sem problemas. A nova aplicação processa webhooks recebidos de um parceiro externo e precisa de ingress externo habilitado.
Após o deploy, os logs de sistema mostram a revisão como ativa e saudável. O time de integração do parceiro reporta que todas as requisições enviadas ao endpoint público retornam connection refused. A equipe verifica no portal que a URL foi gerada corretamente e que o contêiner está em execução com uma réplica ativa.
O engenheiro responsável nota que, por economia, a aplicação foi configurada com réplicas mínimas igual a zero. Ele também observa que o ambiente usa uma rede virtual personalizada criada há seis meses, e que o grupo de segurança de rede associado à subnet do Container Apps tem as seguintes regras de entrada:
Prioridade Nome Porta Protocolo Ação
100 Allow-HTTPS-Internet 443 TCP Allow
200 Allow-HTTP-Internal 80 TCP Allow
300 Deny-All-Inbound * * Deny
A aplicação expõe a porta 3000 internamente e o --target-port foi configurado corretamente como 3000. O ingress está configurado como external com transporte http.
Qual é a causa raiz do comportamento observado?
A) As réplicas mínimas configuradas como zero fazem a aplicação escalar para zero durante períodos de baixa demanda; como nenhuma requisição anterior aqueceu a instância, a primeira conexão do parceiro chega antes da réplica ser provisionada e é recusada.
B) O NSG associado à subnet bloqueia o tráfego de entrada na porta usada pelo plano de dados do Container Apps para rotear requisições externas ao contêiner, pois nenhuma regra permite tráfego nas portas do infrastructure subnet.
C) O ingress configurado como http não suporta webhooks do tipo POST com payload acima de 1 MB; o parceiro externo provavelmente está enviando payloads grandes que são rejeitados na camada de ingress antes de chegar ao contêiner.
D) A URL pública gerada para o container app é válida por apenas 24 horas após o primeiro deploy; após esse período, é necessário reemitir o certificado TLS gerenciado antes que o endpoint volte a responder.
Cenário 2 — Decisão de Ação
A equipe identificou que um container app em produção está travado em estado de degradação. A causa foi identificada: a nova revisão implantada há 20 minutos contém um erro de configuração em uma variável de ambiente que aponta para uma string de conexão inválida. O contêiner inicia, falha ao tentar conectar ao banco de dados e reinicia em loop.
O ambiente opera em modo de revisão multiple. A revisão anterior está saudável e ainda existe no ambiente. O contrato de SLA com o cliente exige que o serviço seja restaurado em no máximo 15 minutos a partir da abertura do incidente, que foi aberto há 8 minutos.
A aplicação recebe 100% do tráfego na revisão com defeito porque a equipe não configurou regras de divisão de tráfego durante o deploy. O banco de dados está acessível e saudável. A equipe tem acesso de Contributor ao resource group.
Qual é a ação correta a tomar neste momento?
A) Corrigir a variável de ambiente diretamente na revisão com defeito via portal ou CLI, forçando um restart da revisão para que ela releia as configurações e reconecte ao banco de dados.
B) Redirecionar 100% do tráfego para a revisão anterior saudável imediatamente, restaurando o serviço dentro do SLA, e tratar a correção da variável de ambiente em uma janela separada sem pressão de tempo.
C) Implantar uma nova revisão com a variável de ambiente corrigida e aguardar que ela fique saudável antes de transferir o tráfego, garantindo que a correção seja validada antes de ser exposta ao cliente.
D) Desativar a revisão com defeito no portal para que o Container Apps redistribua automaticamente o tráfego para a revisão anterior saudável, sem necessidade de configurar regras de tráfego manualmente.
Cenário 3 — Causa Raiz
Um time de desenvolvimento utiliza o Azure Container Apps para hospedar uma API de autenticação interna. A aplicação usa Dapr habilitado para comunicação com outros serviços no mesmo ambiente. O ambiente não possui rede virtual personalizada.
Após uma atualização de infraestrutura feita pelo time de plataforma, a API começa a retornar 500 Internal Server Error em todas as chamadas que dependem de comunicação com outro serviço no ambiente. Chamadas diretas à API que não envolvem Dapr continuam funcionando normalmente.
Os logs da aplicação mostram:
[2025-03-15 14:32:11] ERROR Dapr sidecar not reachable at localhost:3500
[2025-03-15 14:32:11] ERROR connection refused: 127.0.0.1:3500
[2025-03-15 14:32:14] ERROR Dapr sidecar not reachable at localhost:3500
O time de plataforma informa que durante a atualização foram realizadas as seguintes mudanças na definição do container app:
- A imagem foi atualizada para a versão
v2.1.3 - O número mínimo de réplicas foi reduzido de 2 para 1
- O campo
daprEnabledfoi alterado detrueparafalsepara "economizar recursos durante testes de carga" - Uma variável de ambiente
LOG_LEVELfoi adicionada com valordebug
A aplicação está em modo de revisão single. O ambiente tem 6 outras aplicações com Dapr habilitado funcionando normalmente.
Qual é a causa raiz do problema observado?
A) A redução de réplicas mínimas de 2 para 1 causou uma condição de corrida onde o sidecar do Dapr não consegue se registrar no plano de controle quando há apenas uma réplica disponível.
B) A atualização da imagem para v2.1.3 introduziu uma incompatibilidade com a versão do runtime do Dapr utilizada pelo ambiente, causando falha na comunicação entre a aplicação e o sidecar.
C) O campo daprEnabled foi definido como false na nova revisão, removendo o sidecar do Dapr do contêiner; sem o sidecar, a aplicação não consegue alcançar a porta 3500 que usa para comunicação via Dapr.
D) A adição da variável LOG_LEVEL=debug conflita com configurações internas do Dapr que usam a mesma variável de ambiente, corrompendo a inicialização do sidecar na nova revisão.
Cenário 4 — Sequência de Diagnóstico
Um container app que processa eventos do Azure Event Hubs parou de consumir mensagens. O ambiente está saudável, outras aplicações funcionam normalmente, e o Event Hub tem mensagens acumuladas crescendo continuamente. O contêiner está em execução com réplicas ativas.
Um engenheiro precisa diagnosticar o problema. Os passos de investigação disponíveis são:
P — Verificar os logs do contêiner em busca de erros de conexão ou autenticação com o Event Hub.
Q — Confirmar se a scaling rule baseada em Event Hub está configurada e se o connection string secret referenciado existe e está acessível no container app.
R — Verificar se o número atual de réplicas está dentro dos limites configurados de mínimo e máximo e se o scaler KEDA está ativo.
S — Confirmar se o consumer group configurado na scaling rule corresponde ao consumer group que a aplicação usa internamente para consumir mensagens.
T — Checar o System Logs do ambiente no Log Analytics para identificar se há erros de provisionamento ou falhas no plano de controle.
Qual sequência de diagnóstico é a mais lógica e eficiente?
A) T, Q, P, R, S
B) R, P, T, Q, S
C) P, T, Q, S, R
D) Q, P, R, S, T
Gabarito e Explicações
Gabarito — Cenário 1
Resposta: B
O NSG bloqueia o tráfego que o plano de dados do Container Apps precisa para rotear requisições externas até o contêiner. Em ambientes com rede virtual personalizada, o Container Apps exige que regras específicas de entrada sejam configuradas no NSG para permitir tráfego de gerenciamento e de dados. O tráfego externo que chega ao endpoint público não percorre diretamente a porta 443 até o contêiner: ele passa pela infraestrutura do ambiente, que usa um range de portas interno para comunicação com as aplicações hospedadas. O NSG neste cenário permite apenas as portas 443 e 80, bloqueando todo o restante com Deny-All-Inbound, o que impede esse roteamento interno.
A pista definitiva no enunciado é a combinação de rede virtual personalizada com NSG com regra de negação genérica, enquanto o contêiner aparece saudável e a URL foi gerada. Se o problema fosse de cold start (alternativa A), a conexão seria recusada apenas na primeira chamada após inatividade, não em todas. O payload do webhook (alternativa C) é completamente irrelevante para um erro de connection refused, que ocorre antes mesmo de qualquer dado ser transmitido. A validade da URL (alternativa D) é uma informação falsa: URLs de container apps não expiram.
O distrator mais perigoso é A, pois as réplicas mínimas zero aparecem destacadas no enunciado como detalhe chamativo, induzindo o leitor a focar em cold start em vez de examinar a configuração de rede.
Gabarito — Cenário 2
Resposta: B
A restrição crítica do cenário é o SLA de 15 minutos com 8 já consumidos: restam 7 minutos. A ação correta é redirecionar o tráfego imediatamente para a revisão anterior saudável, que já existe no ambiente porque o modo de revisão é multiple. Essa ação restaura o serviço em segundos sem nenhum risco, pois a revisão anterior está validada em produção.
A alternativa C seria tecnicamente correta em um contexto sem pressão de tempo, mas implanta uma nova revisão e aguarda validação, o que consome tempo que não existe dentro do SLA. A alternativa A não funcionaria porque revisões no Container Apps são imutáveis: não é possível editar variáveis de ambiente de uma revisão existente; uma edição sempre gera uma nova revisão. A alternativa D seria atraente, mas desativar uma revisão no Container Apps não redistribui tráfego automaticamente para outras revisões ativas; o tráfego seria simplesmente abandonado, piorando o incidente.
O distrator mais perigoso é C, pois a lógica de "validar antes de expor" é saudável em condições normais, mas ignora completamente a restrição de tempo declarada no enunciado.
Gabarito — Cenário 3
Resposta: C
O log é direto: connection refused: 127.0.0.1:3500. A porta 3500 é a porta local do sidecar do Dapr. Quando daprEnabled é false, o Container Apps não injeta o sidecar no pod do contêiner, e qualquer chamada da aplicação para localhost:3500 resulta em connection refused porque o processo simplesmente não existe. Como o modo de revisão é single, a nova configuração substituiu completamente a revisão anterior, removendo o Dapr de toda a aplicação.
A pista definitiva está na lista de mudanças fornecida pelo time de plataforma: o item 3 é a causa direta, e o log confirma exatamente o comportamento esperado quando o sidecar não está presente.
A informação irrelevante no enunciado é a redução de réplicas mínimas de 2 para 1 (alternativa A). Ela é tecnicamente visível e plausível como causa, mas o comportamento de connection refused em localhost não tem relação com quantidade de réplicas. A atualização de imagem (alternativa B) e a variável LOG_LEVEL (alternativa D) são ruídos intencionais que representam o erro de diagnóstico de focar na mudança mais técnica ou mais recente em vez de examinar cada alteração individualmente contra o sintoma observado.
Gabarito — Cenário 4
Resposta: A
A sequência correta é T, Q, P, R, S.
O raciocínio progressivo começa pelo plano de controle do ambiente (T), pois uma falha de infraestrutura descartaria imediatamente a maioria das hipóteses restantes sem necessidade de investigar a aplicação. Confirmado que o ambiente está saudável, o próximo passo é verificar a configuração da scaling rule e o secret de conexão (Q), pois sem uma regra válida ou sem credenciais acessíveis, o KEDA nunca acionará o scaler. Com a configuração validada, examinar os logs do contêiner (P) revela erros de aplicação que poderiam indicar problemas de autenticação ou lógica de consumo. Em seguida, verificar o estado atual das réplicas e do scaler (R) mostra se o KEDA está detectando mensagens e tentando escalar. Por último, validar o consumer group (S) é o passo mais específico e só faz sentido após confirmar que toda a infraestrutura de scaling está operacional.
A sequência B começa por réplicas (R) antes de verificar se a configuração que controla o scaler está correta, o que é ineficiente. A sequência C começa pelos logs da aplicação (P) antes de confirmar que a infraestrutura de scaling e as credenciais estão íntegras, diagnosticando a camada errada primeiro. A sequência D começa pela scaling rule (Q), que é razoável, mas pula o plano de controle do ambiente, que poderia revelar a causa mais rapidamente se fosse uma falha de infraestrutura.
Árvore de Troubleshooting: Provision a container by using Azure Container Apps
Legenda
| Cor | Tipo de nó |
|---|---|
| Azul escuro | Sintoma inicial (ponto de entrada) |
| Azul | Pergunta diagnóstica |
| Vermelho | Causa identificada |
| Verde | Ação recomendada ou resolução |
| Laranja | Validação ou verificação intermediária |
Para usar esta árvore diante de um problema real, comece pelo nó raiz e responda cada pergunta com base no que é diretamente observável no ambiente: o portal, os logs do Log Analytics e a saída de comandos CLI. A cada bifurcação, escolha o caminho que corresponde ao que você vê, não ao que você suspeita. O objetivo é eliminar hipóteses por evidência antes de executar qualquer ação corretiva. Chegando a um nó de causa identificada, execute a ação correspondente e valide o resultado no nó de verificação associado antes de encerrar o diagnóstico.