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:
- --etcd-servers=https://127.0.0.1:2379
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:
- --etcd-servers=https://127.0.0.1:2381
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:
- --etcd-servers=https://127.0.0.1:2379
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.
Top comments (0)