Introdução
Agora você já sabe descrever o estado desejado usando manifestos e criar Pods e Deployments. A próxima habilidade essencial é entender o que fazer quando o Kubernetes não consegue concretizar esse estado desejado.
Neste laboratório, você trabalhará com dois Deployments pequenos: um saudável e outro com um erro proposital na tag da imagem. Você seguirá um caminho reproduzível, partindo de sintomas gerais até chegar a evidências específicas, corrigirá o manifesto em vez de alterar apenas o objeto em execução e, depois, inspecionará a aplicação recuperada por meio de logs e comandos executados dentro do contêiner.
O objetivo não é memorizar todas as falhas possíveis, mas desenvolver um hábito tranquilo de resolução de problemas: observar, delimitar, analisar as evidências, corrigir o estado desejado e verificar a recuperação.
Criar uma falha controlada
Inicialização do ambiente: Este laboratório inicia um cluster Kubernetes completo para você. A configuração do plano de controle, do nó e dos componentes de rede normalmente leva 2–3 minutos. Aguarde pacientemente até que o ambiente termine de carregar antes de começar.
A resolução de problemas começa com um sintoma. Nesta etapa, você implantará uma carga de trabalho saudável e outra deliberadamente quebrada, para compará-las sob condições idênticas no cluster.
Acesse o diretório de trabalho preparado e liste os arquivos. cd altera o diretório atual; ls lista os nomes contidos nele. Os comandos estão em linhas separadas e serão executados na ordem apresentada:
cd /home/labex/project/debug-lab
ls
Você deverá ver healthy-web.yaml e broken-web.yaml. Ambos definem Deployments com uma réplica, mas um deles contém um erro sutil de configuração que será diagnosticado mais adiante.
Aplique os dois manifestos. kubectl apply envia o estado desejado ao servidor da API, e cada opção -f indica um arquivo de entrada. Um único comando pode aceitar várias opções -f:
kubectl apply -f healthy-web.yaml -f broken-web.yaml
Aguarde primeiro o Deployment conhecido como saudável:
kubectl rollout status deployment/healthy-web --timeout=60s
A mensagem deployment "healthy-web" successfully rolled out estabelece uma referência importante: o cluster consegue agendar Pods e executar a imagem NGINX armazenada em cache.
Agora dê ao outro Deployment uma breve oportunidade de concluir o rollout:
kubectl rollout status deployment/broken-web --timeout=15s || true
O tempo limite é esperado. || true instrui o shell a continuar, pois essa falha é uma evidência para o exercício, não um motivo para interromper o laboratório.
Compare o resumo dos Deployments:
kubectl get deployments
healthy-web deverá mostrar 1/1 pronto, enquanto broken-web mostrará 0/1. Assim, você estabeleceu que o problema é específico da carga de trabalho, e não uma falha total do cluster.
Delimitar o problema com resumos dos recursos
Nesta etapa, você começará com uma visão geral antes de analisar os detalhes. Os controladores do Kubernetes criam uma cadeia de objetos, por isso um problema no Deployment costuma aparecer primeiro no ReplicaSet e no Pod.
Liste juntos os tipos de objetos relacionados. As vírgulas permitem que uma única solicitação kubectl get consulte vários tipos de recursos, enquanto -o wide adiciona colunas úteis, como informações sobre o nó e o IP:
kubectl get deployments,replicasets,pods -o wide
Leia a saída de cima para baixo:
- Um Deployment informa as quantidades desejada e disponível de réplicas.
- Um ReplicaSet leva essa quantidade desejada até mais perto dos Pods.
- Um Pod informa se o contêiner está pronto e apresenta um breve motivo para seu estado.
Restrinja a visualização à aplicação com problemas usando seu rótulo:
kubectl get pods -l app=broken-web -o wide
O nome do Pod contém um sufixo gerado automaticamente, portanto os rótulos são mais seguros do que copiar um nome variável para scripts.
Consulte apenas os campos relevantes nesta etapa. -o custom-columns='...' cria uma tabela a partir de campos explícitos do objeto. Cada entrada tem um cabeçalho, como NAME, seguido pelo caminho do campo JSON que fornece seu valor. A barra invertida no final une as duas linhas exibidas do shell em um único comando:
kubectl get pods -l app=broken-web \
-o custom-columns='NAME:.metadata.name,READY:.status.containerStatuses[0].ready,WAITING_REASON:.status.containerStatuses[0].state.waiting.reason,NODE:.spec.nodeName'
O motivo da espera pode ser inicialmente ErrImagePull e depois mudar para ImagePullBackOff. Ambos indicam que o contêiner nunca foi iniciado porque o Kubernetes não conseguiu obter sua imagem. Isso é mais preciso do que simplesmente dizer que “o Pod está inativo”.
Inspecionar o Pod com describe
Nesta etapa, você usará describe para descobrir por que o contêiner está aguardando. O resumo mostrou o que está errado; agora você reunirá a explicação.
Armazene o nome gerado do Pod em uma variável do shell. $(...) é uma substituição de comando: o shell executa o comando kubectl interno e atribui sua saída a BROKEN_POD. O JSONPath seleciona o nome do primeiro Pod correspondente, e echo exibe o valor armazenado:
BROKEN_POD=$(kubectl get pods -l app=broken-web -o jsonpath='{.items[0].metadata.name}')
echo "$BROKEN_POD"
Descreva esse Pod:
kubectl describe pod "$BROKEN_POD"
describe combina campos úteis com eventos recentes. Concentre-se em três áreas:
- Containers → Image mostra a imagem exata solicitada.
- State → Waiting → Reason descreve o estado atual do contêiner.
- Events registra as tentativas do kubelet e as mensagens de erro.
Neste cenário, a mensagem do evento informa que a tag 1.27-alpine-missing não foi encontrada. O cluster está fazendo exatamente o que o manifesto solicitou; o próprio estado desejado está incorreto.
Confirme diretamente a imagem usando JSONPath:
kubectl get pod "$BROKEN_POD" -o jsonpath='Image: {.spec.containers[0].image}{"\n"}'
O JSONPath é útil quando uma saída extensa em YAML ou de describe contém mais informações do que você precisa. Aqui, ele isola o campo que deverá ser corrigido.
Ler os eventos como uma linha do tempo
Nesta etapa, você lerá os eventos como uma linha do tempo das atividades do Kubernetes. Eventos são registros diagnósticos de curta duração que ajudam a explicar o agendamento, o download de imagens, o início de contêineres, as reinicializações e muitas outras transições de estado.
Liste os eventos recentes do namespace em ordem cronológica. --sort-by ordena os objetos pelo campo de metadados indicado; as aspas mantêm o caminho do campo no estilo JSON unido como um único argumento:
kubectl get events --sort-by='.metadata.creationTimestamp'
As últimas linhas geralmente são as mais recentes. Procure entradas cuja coluna OBJECT faça referência ao Pod com problemas e cuja coluna REASON contenha valores como Pulling, Failed ou BackOff.
Você pode reduzir o ruído filtrando os eventos pelo nome gerado do Pod. --field-selector filtra campos dos objetos no servidor, e não rótulos. A vírgula significa que as duas condições devem ser atendidas, enquanto as barras invertidas permitem continuar um único comando em várias linhas legíveis:
BROKEN_POD=$(kubectl get pods -l app=broken-web -o jsonpath='{.items[0].metadata.name}')
kubectl get events \
--field-selector involvedObject.kind=Pod,involvedObject.name="$BROKEN_POD" \
--sort-by='.metadata.creationTimestamp'
Pense em get, describe e events como visões complementares:
getlocaliza rapidamente o objeto que não está saudável.describecombina configuração, estado e eventos relacionados de um único objeto.eventsfornece uma visão ordenada no tempo, capaz de revelar tentativas repetidas.
As entradas repetidas de BackOff não significam que o Kubernetes abandonou o Pod. Elas indicam que o sistema está espaçando as novas tentativas de download após as falhas.
Corrigir o estado desejado e verificar a recuperação
Nesta etapa, você corrigirá o estado desejado e verificará a recuperação. Já há evidências suficientes para agir: o manifesto solicita uma tag de imagem inexistente. Corrija primeiro o manifesto salvo e, depois, aplique-o para manter o arquivo e o cluster em execução consistentes.
Mostre as linhas de imagem dos dois manifestos para compará-las. grep pesquisa texto, -n acrescenta o número da linha a cada ocorrência, e os dois nomes de arquivo são pesquisados em um único comando:
grep -n 'image:' healthy-web.yaml broken-web.yaml
O manifesto saudável usa nginx:1.27-alpine; o manifesto com problemas acrescenta o sufixo inexistente -missing.
Substitua apenas esse sufixo. sed realiza uma substituição de texto escrita como s/old/new/; -i edita o arquivo indicado diretamente, em vez de apenas imprimir o texto alterado:
sed -i 's/nginx:1.27-alpine-missing/nginx:1.27-alpine/' broken-web.yaml
Valide localmente o arquivo corrigido:
kubectl apply --dry-run=client -f broken-web.yaml
Visualize a diferença entre o arquivo e o objeto em execução:
kubectl diff -f broken-web.yaml || true
kubectl diff termina com o código 1 quando encontra uma diferença, por isso || true permite que a sequência de aprendizagem continue. No diff, uma linha iniciada por - contém a imagem antiga, enquanto uma linha iniciada por + contém a imagem corrigida.
Aplique a correção e aguarde a recuperação:
kubectl apply -f broken-web.yaml
kubectl rollout status deployment/broken-web --timeout=60s
Confirme que ambos os Deployments estão saudáveis:
kubectl get deployments
Ambos deverão informar 1/1 pronto. O Kubernetes criou um novo ReplicaSet e um novo Pod a partir do modelo de Pod corrigido; não foi necessário reparar manualmente o Pod que falhou.
Ler os logs da aplicação
Nesta etapa, você usará os logs da aplicação como uma nova fonte de evidências, agora que o contêiner é iniciado. kubectl logs recupera os fluxos de saída padrão e de erro padrão do contêiner.
Selecione o novo Pod saudável gerenciado por broken-web. Isso repete a substituição de comandos e o JSONPath usados anteriormente. --field-selector=status.phase=Running acrescenta um requisito no servidor para que o Pod selecionado esteja em execução:
WEB_POD=$(kubectl get pods -l app=broken-web \
--field-selector=status.phase=Running \
-o jsonpath='{.items[0].metadata.name}')
echo "$WEB_POD"
O NGINX pode ainda não ter uma entrada no log de acesso, pois ninguém solicitou uma página. Gere uma requisição de dentro do Pod. Em kubectl exec POD -- COMMAND, -- separa as opções do kubectl do comando executado dentro do contêiner. wget -qO- faz o download silenciosamente e envia a página para a saída padrão; o pipe | encaminha essa saída para head, que mostra apenas o início:
kubectl exec "$WEB_POD" -- wget -qO- http://127.0.0.1 | head
O HTML começa com <!DOCTYPE html>, comprovando que o NGINX respondeu localmente na porta 80.
Agora leia os logs recentes. --tail=10 limita a saída às dez linhas mais recentes, evitando que mensagens de inicialização encubram a entrada útil da requisição:
kubectl logs "$WEB_POD" --tail=10
Procure uma requisição HTTP contendo GET / HTTP/1.1 e o código de resposta 200. Os logs são mais úteis quando o contêiner está em execução, mas a aplicação se comporta incorretamente. Em geral, eles não ajudam a diagnosticar uma falha no download da imagem, pois o contêiner nunca chegou a ser iniciado.
Inspecionar de dentro do contêiner
Nesta etapa, você inspecionará a aplicação recuperada a partir de dentro do contêiner. kubectl exec executa um comando em um contêiner já em execução e permite verificar seu sistema de arquivos, processos, ambiente, visão de DNS ou comportamento da rede local.
Reuse o nome do Pod em execução:
WEB_POD=$(kubectl get pods -l app=broken-web \
--field-selector=status.phase=Running \
-o jsonpath='{.items[0].metadata.name}')
Consulte o nome de host do contêiner:
kubectl exec "$WEB_POD" -- hostname
A saída corresponde ao nome do Pod porque, por padrão, o Kubernetes define o nome de host do Pod dessa forma.
Verifique a sintaxe da configuração do NGINX dentro do contêiner:
kubectl exec "$WEB_POD" -- nginx -t
As mensagens syntax is ok e test is successful mostram que a configuração interna da aplicação é válida.
Por fim, faça uma verificação compacta de integridade, de dentro para fora. >/dev/null descarta o HTML baixado, e && executa echo somente se wget for bem-sucedido. Portanto, a mensagem de sucesso só aparecerá depois que uma resposta HTTP for recebida:
kubectl exec "$WEB_POD" -- wget -qO- http://127.0.0.1 >/dev/null && echo "NGINX responded inside the Pod"
Use exec com critério. Ele exige um contêiner em execução, portanto não poderia diagnosticar a falha anterior no download da imagem. A sequência de evidências deste incidente foi:
get -> describe -> events -> repair manifest -> rollout status -> logs -> exec
Falhas diferentes podem interromper a investigação em níveis diferentes, mas avançar de resumos simples para inspeções mais profundas mantém a resolução de problemas focada.
Resumo
Você praticou um ciclo completo de depuração para iniciantes no Kubernetes v1.35. Comparou cargas de trabalho saudáveis e com falhas, delimitou o problema usando rótulos e campos concisos, utilizou describe e eventos para identificar uma tag de imagem inválida, corrigiu a fonte declarativa de verdade e verificou a recuperação com o status do rollout, logs e comandos executados dentro do contêiner.
A principal lição é escolher evidências compatíveis com a etapa atual do ciclo de vida da carga de trabalho. Quando um contêiner ainda não foi iniciado, examine o estado e os eventos. Depois que ele estiver em execução, os logs e exec poderão revelar o comportamento no nível da aplicação. No próximo desafio, você usará esse fluxo de trabalho de forma independente.


