DEV Community

DeividFerraz
DeividFerraz

Posted on

Troubleshooting no Cluster do Kubernetes.

Ontem eu estava pensando em uma coisa que acontece muito quando a gente faz troubleshooting em Kubernetes:

a gente corre para os logs antes de entender a estrutura. 🧠

E eu entendo o motivo.

Quando algo quebra, a primeira reação é procurar uma mensagem clara dizendo:

“o problema está exatamente aqui”

Só que, na prática, quase nunca é assim.

Logs ajudam muito.
Comandos ajudam muito.
Mas eles não substituem o entendimento da estrutura.

E esse é o ponto principal:

👉 você precisa entender o que está olhando.

Neste exemplo, vou simular uma falha no kube-apiserver, quebrando propositalmente a comunicação dele com o etcd.

A ideia não é decorar comando.

A ideia é entender o caminho:

🧩 sintoma → hipótese → componente → configuração → causa raiz → correção

Imagine um cluster local com Minikube.

O kube-apiserver está rodando como um Static Pod, definido por um arquivo YAML dentro do node:

/etc/kubernetes/manifests/kube-apiserver.yaml

Esse arquivo é observado pelo kubelet.

Ou seja:

📌 se o YAML muda, o kubelet tenta recriar o componente.
📌 se o YAML está errado, o componente pode quebrar.
📌 se o API Server quebra, o kubectl começa a falhar.

Antes de assumir qualquer coisa, eu valido se o cluster está saudável:

kubectl get nodes
kubectl get pods -A

Se tudo estiver funcionando, eu devo ver o node como Ready e os pods listados normalmente.

Esse passo cria uma linha de base.

✅ Antes estava funcionando.
❌ Depois da alteração, parou.

Sem isso, vira achismo.

Agora entro no node do Minikube:

minikube ssh

Dentro do node, consigo localizar os manifests dos componentes do control plane:

sudo ls -lah /etc/kubernetes/manifests

E abrir o manifest do API Server:

sudo cat /etc/kubernetes/manifests/kube-apiserver.yaml

Aqui já começa a parte importante.

O kube-apiserver não está rodando como um Deployment comum.

Ele está definido como Static Pod.

Antes de mexer em qualquer componente crítico:

sudo cp /etc/kubernetes/manifests/kube-apiserver.yaml \
/etc/kubernetes/manifests/kube-apiserver.yaml.backup

⚠️ Backup sempre.

Control Plane não é lugar para editar no impulso.

Se você quebrar o API Server, talvez nem consiga usar kubectl para corrigir.

A correção precisa ser feita direto no node.

Agora vamos procurar a configuração do etcd dentro do YAML:

sudo grep -n "etcd-servers" /etc/kubernetes/manifests/kube-apiserver.yaml

Você deve encontrar algo parecido com:

Essa linha é extremamente importante.

Ela diz para o kube-apiserver:

“O estado do cluster está nesse endpoint do etcd.”

Então, se essa porta estiver errada, o API Server pode até tentar subir, mas não consegue se comunicar com o banco de estado do cluster.

Agora vamos simular uma falha alterando a porta correta 2379 para uma porta errada, por exemplo 2381:

sudo sed -i 's/127.0.0.1:2379/127.0.0.1:2381/g' \
/etc/kubernetes/manifests/kube-apiserver.yaml

Valido a alteração:

sudo grep -n "etcd-servers" /etc/kubernetes/manifests/kube-apiserver.yaml

Agora o YAML deve ter algo assim:

Parece pouca coisa.

Mas uma porta errada pode derrubar a comunicação entre o API Server e o etcd. 💥

E quando isso acontece, o kubectl começa a falhar:

kubectl get nodes
kubectl get pods -A

Você pode ver algo como:

The connection to the server was refused

ou:

Unable to connect to the server

Esse é o ponto mais importante do troubleshooting:

🚫 o erro do kubectl é o sintoma.
✅ a causa ainda precisa ser encontrada.

Muita gente para aqui e conclui:

“o cluster caiu”

Mas será mesmo?

Mesmo com o API Server quebrado, o node ainda pode estar vivo.

Dentro do Minikube:

hostname
uptime
sudo systemctl status kubelet --no-pager

Aqui começamos a separar as camadas:

🖥️ O node está vivo?
⚙️ O kubelet está rodando?
📦 O container do API Server está subindo?
📄 O YAML faz sentido?
🔌 O endpoint do etcd está correto?

Troubleshooting bom é isso:

👉 quebrar o problema em partes menores.

Se o API Server está fora, o kubectl deixa de ser a melhor ferramenta.

Então vou direto no container runtime:

sudo crictl ps -a | grep kube-apiserver

Aqui consigo ver se o container do kube-apiserver está:

🔁 reiniciando
🛑 parado
💥 falhando
✅ rodando

Depois, pego o ID do container e vejo os logs:

sudo crictl logs ID_DO_CONTAINER

Exemplo:

sudo crictl logs abc123

Provavelmente vou encontrar erro de conexão com o etcd, algo como:

connection refused

ou:

failed to connect to etcd

Agora sim o log começa a fazer sentido.

Porque eu não estou lendo log no escuro.

Eu já tenho contexto. 🔎

Também vale olhar o log do kubelet:

sudo journalctl -u kubelet --no-pager -n 100

Ou acompanhando em tempo real:

sudo journalctl -u kubelet -f

O kubelet é quem observa o diretório:

/etc/kubernetes/manifests

E tenta manter os Static Pods rodando.

Se o kube-apiserver falha, o kubelet provavelmente vai registrar tentativas de criação, falhas e reinícios.

Agora volto para o YAML.

Mas não para decorar.

Volto para entender.

Um trecho simplificado do kube-apiserver.yaml pode ter essa cara:

apiVersion: v1
kind: Pod
metadata:
name: kube-apiserver
namespace: kube-system
spec:
containers:
- name: kube-apiserver
image: registry.k8s.io/kube-apiserver:v1.30.0
command:
- kube-apiserver
- --advertise-address=192.168.49.2
- --secure-port=6443
- --etcd-servers=https://127.0.0.1:2381
- --etcd-cafile=/etc/kubernetes/pki/etcd/ca.crt
- --etcd-certfile=/etc/kubernetes/pki/apiserver-etcd-client.crt
- --etcd-keyfile=/etc/kubernetes/pki/apiserver-etcd-client.key

Aqui dá para enxergar bastante coisa.

Se o problema é comunicação com o etcd, eu olho:

🔌 --etcd-servers
🔐 --etcd-cafile
📜 --etcd-certfile
🔑 --etcd-keyfile

Se o problema é acesso ao API Server, eu olho:

🌐 --advertise-address
🚪 --secure-port

Se o problema é montagem de arquivos, eu olho:

📁 volumeMounts
📦 volumes
🗂️ hostPath

Um exemplo de montagem dos certificados seria algo assim:

volumeMounts:

  • name: etcd-certs mountPath: /etc/kubernetes/pki/etcd readOnly: true
  • name: k8s-certs mountPath: /etc/kubernetes/pki readOnly: true

volumes:

  • name: etcd-certs hostPath: path: /etc/kubernetes/pki/etcd type: DirectoryOrCreate
  • name: k8s-certs hostPath: path: /etc/kubernetes/pki type: DirectoryOrCreate

Se o log fala que não encontrou certificado, não adianta olhar só para a mensagem.

Eu preciso perguntar:

📌 o arquivo existe no host?
📌 o caminho está montado no container?
📌 o mountPath bate com a flag usada no comando?
📌 o certificado é o correto para falar com o etcd?

Por exemplo, se a flag aponta para:

  • --etcd-cafile=/etc/kubernetes/pki/etcd/ca.crt

Mas o volume não monta /etc/kubernetes/pki/etcd, o problema pode não ser o certificado em si.

Pode ser a montagem.

Esse é o tipo de coisa que só aparece quando você entende a estrutura. 🧩

Outro exemplo:

  • --secure-port=6443

Essa é a porta em que o API Server escuta as requisições HTTPS.

Se o kubectl tenta falar com uma porta, mas o API Server está configurado para outra, o sintoma pode parecer rede, firewall ou cluster fora.

Mas a causa pode estar em uma flag.

O mesmo vale para:

  • --advertise-address=192.168.49.2

Esse é o endereço que o API Server anuncia para o cluster.

Se esse endereço estiver errado, você pode ter comportamento estranho de conectividade.

Percebe a diferença?

Você deixa de depender apenas da mensagem do log e começa a enxergar a estrutura.

O troubleshooting deixa de ser tentativa e erro.

Vira investigação.

Se a causa foi a porta errada do etcd, a correção seria voltar para:

Ou restaurar o backup do manifest:

sudo cp /etc/kubernetes/manifests/kube-apiserver.yaml.backup \
/etc/kubernetes/manifests/kube-apiserver.yaml

Depois valido se o container voltou:

sudo crictl ps -a | grep kube-apiserver

E, da minha máquina, valido se o API Server voltou a responder:

kubectl get nodes
kubectl get pods -A

Se tudo voltou, fechamos o ciclo:

✅ sintoma identificado
✅ componente isolado
✅ configuração analisada
✅ causa encontrada
✅ correção aplicada
✅ ambiente validado

No fim, o aprendizado é simples:

não adianta saber só o comando.

Você precisa saber o que aquele comando está validando.

kubectl get nodes não é só “ver se o cluster está ok”.

Ele depende do API Server.

crictl ps -a não é só “listar container”.

Ele ajuda quando o Kubernetes não consegue te responder pela API.

journalctl -u kubelet não é só “ver log”.

Ele mostra o comportamento do processo que está tentando manter os Static Pods vivos.

E o YAML não é só configuração.

Ele é o contrato de como aquele componente deve subir.

Quando você entende isso, começa a identificar erro “no olho”. 👀

Não porque virou mágico.

Mas porque agora você sabe onde cada coisa mora.

Logs continuam sendo importantes.

Mas eles não deveriam ser a única coisa que te guia.

O ideal é juntar:

🧠 sintoma
🔎 contexto
📄 estrutura
⚙️ configuração
🧾 logs

Aí sim você chega mais perto da causa raiz.

Menos comando aleatório.
Menos achismo.
Menos “vou copiar o erro e torcer”.

Mais entendimento da estrutura.
Mais leitura de YAML.
Mais investigação com intenção.

Kubernetes #DevOps #SRE #Troubleshooting #KubeAPIServer #Minikube #Containers #Linux #CloudNative

Top comments (0)