Pular para o conteúdo principal

Solução de problemas do cluster

A solução de problemas de pods cobre falhas de cargas de trabalho. Esta página cobre falhas a nível de cluster: quando os nós, o control plane ou a própria infraestrutura é o problema.

Comece aqui​

Execute isto antes de qualquer coisa. Ele informa se o problema são os nós, o control plane ou esgotamento de recursos em menos de 30 segundos.

# Status dos nós — algum nó NotReady?
kubectl get nodes -o wide

# Saúde do kube-system — cada pod deve estar Running
kubectl get pods -n kube-system -o wide

# Eventos a nível de cluster — ordenados por tempo, mais recentes por último
kubectl get events --sort-by='.lastTimestamp' -A | tail -30

# Estado do cluster AKS no Azure
az aks show -g <rg> -n <cluster> --query "{state:provisioningState,power:powerState.code,k8s:kubernetesVersion}" -o table

Node NotReady​

Um nó mostra NotReady em kubectl get nodes. Pods naquele nó param de receber tráfego e eventualmente são despejados.

Árvore de decisão​

1. Identifique o nó NotReady e há quanto tempo ele está inativo:

kubectl get nodes -o wide
kubectl describe node <node-name> | grep -A 10 "Conditions:"

2. O que as condições indicam?

CondiçãoSignificadoCorreção
MemoryPressure=TrueNó está ficando sem memóriaDespeje pods grandes, adicione nós ou aumente o tamanho da VM
DiskPressure=TrueUso de disco acima de 85% — kubelet começa a despejar podsLimpe imagens com crictl rmi --prune, aumente o disco do SO
PIDPressure=TrueMuitos processosEncontre o pod que está criando processos excessivamente: kubectl top pods --sort-by=cpu
Ready=False, KubeletNotReadyKubelet travou ou não consegue alcançar o API serverAcesse o nó via SSH e verifique os logs do kubelet

3. Verifique o status do kubelet no nó:

# Use node-shell ou kubectl debug para acessar o nó
kubectl debug node/<node-name> -it --image=mcr.microsoft.com/cbl-mariner/busybox:2.0
# Dentro do pod de debug:
chroot /host
systemctl status kubelet
journalctl -u kubelet --no-pager --since "30 minutes ago"

4. Verifique a saúde da VM no Azure:

az vm get-instance-view \
--ids $(az vmss list-instances -g MC_<rg>_<cluster>_<region> --vmss-name <vmss-name> --query "[].id" -o tsv) \
--query "[].{name:name,status:instanceView.statuses[1].displayStatus}" -o table

5. Se o nó é irrecuperável, recrie a imagem:

# Para node pools baseados em VMSS (padrão)
az vmss reimage --resource-group MC_<rg>_<cluster>_<region> --name <vmss-name> --instance-ids <instance-id>
aviso

Não recrie a imagem de múltiplos nós simultaneamente. Recrie um nó por vez e aguarde ele reingressar no cluster como Ready antes de prosseguir para o próximo.

Prevenção​

Use o cluster autoscaler com --min-count definido para pelo menos 3 para pools de produção. Habilite a auto-reparação de nós — ela recria automaticamente a imagem de nós travados em NotReady por mais de 10 minutos:

az aks update -g <rg> -n <cluster> --enable-node-auto-repair

Falhas de upgrade​

Upgrades de cluster ou node pool ficam travados, deixam nós em estado de versão mista ou falham completamente.

Árvore de decisão​

1. Verifique o status atual do upgrade:

az aks show -g <rg> -n <cluster> --query "{state:provisioningState,k8s:kubernetesVersion}" -o table
az aks nodepool list -g <rg> --cluster-name <cluster> --query "[].{name:name,version:orchestratorVersion,state:provisioningState,count:count}" -o table

2. O que o estado de provisionamento indica?

EstadoSignificadoAção
UpgradingUpgrade em andamentoAguarde. Verifique eventos de node drain para acompanhar o progresso
FailedUpgrade falhou no meioVerifique a mensagem de erro, corrija a causa, depois tente novamente
CanceledUpgrade foi interrompido manualmenteDecida se deseja tentar novamente ou avançar

3. Se o PDB está bloqueando o node drain:

Esta é a causa mais comum de falha de upgrade. Um PodDisruptionBudget impede o nó de ser drenado, e o upgrade trava.

# Encontre PDBs que estão bloqueando
kubectl get pdb -A
kubectl describe pdb <pdb-name> -n <namespace>
dica

Defina maxUnavailable: 1 em vez de minAvailable: 100% nos PDBs. Um PDB com minAvailable igual à contagem de réplicas bloqueia todas as disrupções voluntárias, incluindo upgrades.

4. Aborte um upgrade travado:

# Pare o upgrade — nós já atualizados permanecem na nova versão
az aks upgrade -g <rg> -n <cluster> --kubernetes-version <current-version> --no-wait

5. Tente novamente após corrigir o bloqueio:

az aks upgrade -g <rg> -n <cluster> --kubernetes-version <target-version>

Prevenção​

Sempre execute az aks get-upgrades antes de atualizar. Não pule mais de uma versão minor. Teste upgrades em um cluster de desenvolvimento primeiro — não porque a documentação diz para fazer, mas porque problemas de PDB e webhook só aparecem durante drains reais.


API server inacessível​

Comandos kubectl expiram por timeout ou retornam erros de conexão. Você não consegue gerenciar o cluster de forma alguma.

Árvore de decisão​

1. Confirme que o problema é o API server, não a sua máquina:

# Verifique se você consegue alcançar o endpoint do API server
kubectl cluster-info
# Verifique o contexto do seu kubeconfig
kubectl config current-context
# Obtenha credenciais novamente
az aks get-credentials -g <rg> -n <cluster> --overwrite-existing

2. Restrinja a causa:

SintomaCausa provávelCorreção
Unable to connect to the server: dial tcp ... i/o timeoutFaixas de IP autorizadas bloqueando seu IPAdicione seu IP atual às faixas autorizadas
Unable to connect to the server: EOFCluster privado e você está fora da VNetConecte via VPN, jump box ou az aks command invoke
error: You must be logged in to the server (Unauthorized)Token expirado ou kubelogin não configuradoExecute novamente az login e depois az aks get-credentials
Unable to connect to the server: x509: certificate has expiredCertificado do cliente expiradoRotacione certificados do cluster (veja expiração de certificados abaixo)

3. Para problemas de faixa de IP autorizado:

# Verifique as faixas autorizadas atuais
az aks show -g <rg> -n <cluster> --query "apiServerAccessProfile.authorizedIpRanges"

# Adicione seu IP atual
MY_IP=$(curl -s ifconfig.me)/32
az aks update -g <rg> -n <cluster> --api-server-authorized-ip-ranges "$MY_IP"

4. Para clusters privados — use command invoke como recurso de emergência:

az aks command invoke -g <rg> -n <cluster> --command "kubectl get nodes"
informação

Use az aks command invoke apenas para emergências. É lento e tem um timeout de 60 segundos. Para acesso regular a clusters privados, configure uma VPN ou um jump box Azure Bastion dentro da VNet.

5. Para problemas com kubelogin:

# Confirme que o kubelogin está instalado
kubelogin --version

# Converta o kubeconfig para usar login via device code
kubelogin convert-kubeconfig -l devicecode

Expiração de certificados​

O AKS rotaciona certificados do cluster automaticamente, mas a rotação pode falhar silenciosamente. Quando os certificados expiram, os nós se desconectam e chamadas à API falham com erros x509.

Diagnóstico​

1. Verifique as datas de expiração dos certificados:

az aks show -g <rg> -n <cluster> --query "{certExpiry:azurePortalFqdn}" -o table

# Mais detalhado — verifique o certificado real no API server
kubectl get nodes -o wide 2>&1 | grep -i "certificate"

2. Verifique se a auto-rotação está funcionando:

az aks show -g <rg> -n <cluster> --query "autoUpgradeProfile"

Correção​

Force a rotação de certificados:

az aks rotate-certs -g <rg> -n <cluster>
aviso

az aks rotate-certs causa indisponibilidade. Ele reinicia todos os nós do cluster para captar os novos certificados. Agende isso durante uma janela de manutenção. A operação leva de 20 a 30 minutos para um cluster típico.

Prevenção​

Habilite o canal de auto-upgrade. Clusters nos canais de auto-upgrade patch ou stable têm certificados rotacionados automaticamente como parte do ciclo de upgrade.


Esgotamento de quota​

Você não consegue criar novos nós, anexar discos ou obter IPs de pod. O Azure retorna erros de quota que aparecem como falhas vagas no Kubernetes.

Árvore de decisão​

1. Identifique a quota esgotada:

# Verifique a quota de vCPU para a região
az vm list-usage --location <region> -o table | grep -i "cores"

# Verifique a quota de rede
az network list-usages --location <region> -o table

# Verifique a quota de disco
az disk list -g MC_<rg>_<cluster>_<region> --query "length(@)"

2. Falhas comuns de quota e como elas aparecem no Kubernetes:

Sintoma no KubernetesQuota do Azure atingidaComo confirmar
Nós travados em ProvisioningLimite regional de vCPUaz vm list-usage --location <region>
Pods travados em Pending com "no available addresses"Esgotamento de IP da subnetaz network vnet subnet show — verifique IPs disponíveis
PVC travado em PendingLimite de managed disk por assinaturaaz disk list --query "length(@)"
Autoscaler não adicionando nósQuota da família de VM excedidaVerifique a quota do SKU de VM específico

3. Solicite um aumento de quota:

# Use a CLI do Azure para solicitar um aumento
az quota create \
--resource-name "standardDSv3Family" \
--scope "/subscriptions/<sub-id>/providers/Microsoft.Compute/locations/<region>" \
--limit-object value=<new-limit> limit-object-type=LimitValue \
--resource-type "dedicated"
dica

Não espere até atingir o limite. Configure alertas do Azure Monitor a 80% de uso da quota. Aumentos de quota são gratuitos e geralmente aprovados em horas, mas algumas famílias de VM levam dias.

Esgotamento de pod CIDR​

Se você usa Azure CNI (não overlay), cada pod recebe um IP real da subnet. Uma subnet /24 fornece 251 IPs utilizáveis — isso é aproximadamente 8 nós com 30 pods cada.

Verifique IPs disponíveis:

az network vnet subnet show \
-g <rg> --vnet-name <vnet> -n <subnet> \
--query "{addressPrefix:addressPrefix,availableIps:ipConfigurations.length(@)}" -o table

Use Azure CNI Overlay para novos clusters. Ele desacopla IPs de pod dos IPs de subnet, dando a cada nó um /24 de um range privado. Você nunca ficará sem IPs de pod.


Erros do control plane​

Pods do kube-system estão com problemas, CoreDNS está falhando ou admission webhooks estão bloqueando deployments.

Falhas do CoreDNS​

Sintomas: Pods não conseguem resolver nomes DNS. Services retornam NXDOMAIN ou expiram por timeout nas consultas DNS.

# Verifique pods do CoreDNS
kubectl get pods -n kube-system -l k8s-app=kube-dns
kubectl logs -n kube-system -l k8s-app=kube-dns --tail=50

# Teste a resolução DNS de dentro do cluster
kubectl run dns-test --image=mcr.microsoft.com/cbl-mariner/busybox:2.0 --rm -it --restart=Never -- nslookup kubernetes.default
Mensagem de logCausaCorreção
SERVFAILDNS upstream inacessívelVerifique configurações de DNS da VNet e regras NSG
i/o timeoutPod do CoreDNS não consegue alcançar o API serverVerifique conectividade do nó e kube-proxy
REFUSEDServidor DNS customizado rejeitando consultasCorrija a configuração do servidor DNS upstream

Falhas de webhook bloqueando deployments​

Sintomas: kubectl apply retorna Internal error occurred: failed calling webhook. Deployments, pods ou namespaces não podem ser criados.

# Liste todos os webhooks
kubectl get validatingwebhookconfigurations
kubectl get mutatingwebhookconfigurations

# Verifique se o serviço do webhook está executando
kubectl get endpoints -n <webhook-namespace> <webhook-service>
aviso

Um webhook com failurePolicy: Fail e um serviço de suporte inativo bloqueia todas as chamadas de API correspondentes. Se você está bloqueado, altere o webhook para Ignore ou exclua-o:

kubectl delete validatingwebhookconfiguration <name>

Crashes de pods do kube-system​

Se qualquer pod do kube-system está em CrashLoopBackOff, o cluster está degradado. Verifique os logs imediatamente:

kubectl get pods -n kube-system | grep -v Running
kubectl logs -n kube-system <pod-name> --previous
kubectl describe pod -n kube-system <pod-name>

Não exclua pods do kube-system a menos que saiba exatamente o que está fazendo. A maioria é gerenciada pelo AKS e será recriada, mas alguns (como konnectivity-agent) requerem que o control plane esteja saudável primeiro.


Latência do etcd e lentidão do API server​

O cluster está executando mas comandos kubectl estão lentos, watches estão atrasados e controllers estão defasados da realidade.

Sintomas​

  • kubectl get pods leva mais de 5 segundos
  • Deployments levam minutos para fazer rollout
  • HPA reage lentamente a mudanças de métricas
  • Logs de auditoria do API server mostram alta latência em chamadas LIST

Diagnóstico​

# Verifique métricas do API server (se o endpoint de métricas está exposto)
kubectl get --raw /metrics | grep apiserver_request_duration_seconds

# Conte objetos — muitos objetos em um namespace é um sinal de alerta
kubectl get all -A --no-headers | wc -l

# Verifique chamadas LIST custosas (requer audit logging)
# Procure chamadas sem fieldSelector ou labelSelector
kubectl get events -A --no-headers | wc -l

Causas comuns e correções​

CausaComo confirmarCorreção
Muitos objetos Eventskubectl get events -A --no-headers | wc -l retorna 10.000+Defina TTL de eventos com --event-ttl ou limpe eventos antigos
CRDs com milhares de instânciaskubectl get <crd> -A --no-headers | wc -lPagine chamadas list, adicione índices ou arquive CRs antigos
Controllers fazendo chamadas LIST sem filtroLogs de auditoria do API serverCorrija o código do controller para usar field selectors e label selectors
Secrets ou ConfigMaps grandeskubectl get secrets -A -o json | jq '.items[].data | length'Divida secrets grandes, use stores de segredos externos
Muitos watchesUso de memória do API server crescendoReduza a cardinalidade de watches em controllers customizados
dica

Use --field-selector e --label-selector em cada chamada LIST em controllers customizados. Um LIST pods sem filtro em um cluster com 10.000 pods puxa a lista completa de pods do etcd para a memória do API server em cada chamada.

Prevenção​

Defina resource quotas por namespace para evitar que qualquer equipe crie objetos sem limite:

apiVersion: v1
kind: ResourceQuota
metadata:
name: object-limits
namespace: team-a
spec:
hard:
configmaps: "100"
secrets: "100"
services: "20"
pods: "200"

Verificação rápida de saúde do cluster​

Execute este script para obter um snapshot abrangente da saúde do cluster. Salve-o como cluster-health.sh e execute antes de abrir um chamado de suporte.

#!/usr/bin/env bash
set -euo pipefail

echo "=== Cluster info ==="
kubectl cluster-info

echo -e "\n=== Node status ==="
kubectl get nodes -o wide

echo -e "\n=== Node conditions (NotReady or pressure) ==="
kubectl get nodes -o json | jq -r '
.items[] |
select(.status.conditions[] |
select(.type != "Ready" and .status == "True") or
select(.type == "Ready" and .status != "True")
) |
.metadata.name + ": " +
([.status.conditions[] | select(.status == "True" or (.type == "Ready" and .status != "True")) | .type + "=" + .status] | join(", "))'

echo -e "\n=== kube-system pods not Running ==="
kubectl get pods -n kube-system --field-selector=status.phase!=Running 2>/dev/null || echo "All kube-system pods are Running"

echo -e "\n=== Cluster events (warnings only, last 30 min) ==="
kubectl get events -A --field-selector=type=Warning --sort-by='.lastTimestamp' | tail -20

echo -e "\n=== Resource usage ==="
kubectl top nodes 2>/dev/null || echo "Metrics server not available"

echo -e "\n=== PDBs that may block upgrades ==="
kubectl get pdb -A -o json | jq -r '
.items[] |
select(.status.disruptionsAllowed == 0) |
.metadata.namespace + "/" + .metadata.name + " — disruptionsAllowed: 0"'

echo -e "\n=== Pending PVCs ==="
kubectl get pvc -A --field-selector=status.phase=Pending 2>/dev/null || echo "No pending PVCs"

echo -e "\n=== AKS cluster state ==="
az aks show -g "${1:-myRG}" -n "${2:-myCluster}" \
--query "{state:provisioningState,power:powerState.code,k8s:kubernetesVersion,nodeRG:nodeResourceGroup}" -o table 2>/dev/null || echo "Provide resource group and cluster name as arguments"

Quando contatar o suporte Azure​

Nem todo problema requer um chamado de suporte. Use esta matriz de severidade para decidir.

Matriz de severidade​

SeveridadeQuando usarExemploResposta esperada
A / CríticoProdução fora do ar, sem solução alternativaTodos os nós NotReady, API server inacessível1 hora (com Premier/Unified)
B / AltoProdução comprometida, solução alternativa existeUpgrades falhando, um node pool inativo4 horas
C / PadrãoProblema não críticoAumento de quota necessário, degradação menor8 horas comerciais

O que coletar antes de abrir um chamado​

O Suporte Azure pedirá tudo isso. Colete antecipadamente para evitar idas e vindas:

# 1. ID do recurso do cluster
az aks show -g <rg> -n <cluster> --query id -o tsv

# 2. Estado e versão do cluster
az aks show -g <rg> -n <cluster> --query "{state:provisioningState,version:kubernetesVersion}" -o json

# 3. Detalhes dos node pools
az aks nodepool list -g <rg> --cluster-name <cluster> -o table

# 4. Operações recentes do cluster
az aks operation-abort list -g <rg> -n <cluster> 2>/dev/null
az monitor activity-log list --resource-group <rg> --offset 1h --query "[?status.value=='Failed']" -o table

# 5. Eventos e status de pods do Kubernetes
kubectl get events -A --sort-by='.lastTimestamp' > cluster-events.txt
kubectl get pods -A -o wide > all-pods.txt
kubectl describe nodes > node-details.txt
informação

Sempre inclua o correlation ID dos comandos Azure CLI que falharam. Ele é impresso na saída de erro e permite que o suporte rastreie a chamada de API exata que falhou no backend deles.


Recursos​