Introdução: O que é kubectl e Por Que Importa
O kubectl é a ferramenta de linha de comando oficial do Kubernetes, responsável por toda interação com clusters. Ele funciona como um cliente HTTP que se comunica com a API do Kubernetes, traduzindo seus comandos em requisições REST. Diferentemente de outras ferramentas, kubectl não armazena estado — cada comando é uma operação isolada contra o cluster, o que o torna previsível e auditável.
Dominar kubectl é essencial porque ele é a porta de entrada para qualquer operação em Kubernetes. Seja deployando aplicações, escalando recursos ou debugando problemas, você usará kubectl. Neste artigo, vamos além dos comandos básicos e entraremos na profundidade: entenderemos como o kubectl se conecta a clusters diferentes através de contexts, como gerenciar múltiplas configurações com kubeconfig, e dominar os comandos que realmente importam no dia a dia.
Kubeconfig: Arquitetura e Gerenciamento de Credenciais
Estrutura e Localização
O kubeconfig é um arquivo YAML que contém toda a informação necessária para kubectl se conectar a um cluster Kubernetes. Por padrão, kubectl procura este arquivo em ~/.kube/config. Este arquivo é dividido em três seções principais: clusters, users e contexts. Cada seção é independente, permitindo combinações flexíveis de credenciais com endpoints diferentes.
A estrutura básica de um kubeconfig é simples mas poderosa:
apiVersion: v1
kind: Config
clusters:
- name: production
cluster:
server: https://api.prod.company.com:6443
certificate-authority-data: LS0tLS1CRUdJTi... # base64 encoded CA cert
- name: staging
cluster:
server: https://api.staging.company.com:6443
certificate-authority: /path/to/ca.crt
users:
- name: admin-prod
user:
client-certificate-data: LS0tLS1CRUdJTi... # base64 encoded client cert
client-key-data: LS0tLS1CRUdJTi... # base64 encoded client key
- name: dev-staging
user:
token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
contexts:
- name: prod
context:
cluster: production
user: admin-prod
namespace: default
- name: staging
context:
cluster: staging
user: dev-staging
namespace: development
current-context: prod
Quando você executa um comando kubectl, ele primeiro lê o kubeconfig, localiza o current-context, depois busca a combinação de cluster + user especificada naquele contexto. É por isso que você pode ter múltiplas configurações em um único arquivo sem conflitos.
Gerenciando Múltiplos Kubeconfigs
Na prática, você frequentemente trabalha com múltiplos arquivos kubeconfig — um para cada cliente, ambiente ou projeto. Em vez de mesclar manualmente todos em um arquivo, você pode usar a variável de ambiente KUBECONFIG para carregar múltiplos arquivos simultaneamente:
export KUBECONFIG=~/.kube/config:~/.kube/prod-cluster:~/.kube/staging-cluster
kubectl config view
O comando kubectl config view consolida todos os arquivos carregados. Observe que kubectl usa : no Linux/Mac e ; no Windows para separar caminhos. Quando múltiplos arquivos definem o mesmo contexto, o primeiro na lista vence.
Para adicionar um novo cluster ao seu kubeconfig de forma segura:
kubectl config set-cluster new-cluster \
--server=https://new-api.company.com:6443 \
--certificate-authority=/path/to/ca.crt \
--kubeconfig=~/.kube/config
kubectl config set-credentials new-user \
--client-certificate=/path/to/client.crt \
--client-key=/path/to/client.key \
--kubeconfig=~/.kube/config
kubectl config set-context new-context \
--cluster=new-cluster \
--user=new-user \
--namespace=production \
--kubeconfig=~/.kube/config
Isso é mais seguro que editar o YAML manualmente, pois kubectl valida a sintaxe e a estrutura. Após isso, você pode visualizar sua nova configuração com kubectl config view --context=new-context.
Contexts: Navegação Entre Clusters e Namespaces
Entendendo Contexts na Prática
Um context é uma tupla (cluster, user, namespace). É o mecanismo que kubectl usa para determinar "para onde vou agora e com que credenciais?". Você pode ter 10 clusters diferentes, mas trabalhar com apenas um de cada vez trocando de contexto. Isso é muito mais seguro que alternar arquivos kubeconfig inteiros.
Listar todos os contextos disponíveis é uma operação frequente:
kubectl config get-contexts
Saída esperada:
CURRENT NAME CLUSTER AUTHINFO NAMESPACE
* prod-us-east prod-us-east admin@prod default
prod-eu-west prod-eu-west admin@prod default
staging staging-cluster dev@staging development
local-minikube minikube minikube default
O asterisco (*) indica o contexto ativo. Para trocar para outro:
kubectl config use-context staging
Agora qualquer comando kubectl será executado contra o cluster staging, com as credenciais dev@staging, no namespace development. Essa simplicidade é crucial em ambientes com múltiplos clusters.
Editando e Renomeando Contexts
Às vezes você precisa corrigir um contexto ou renomeá-lo. Para renomear:
kubectl config rename-context old-context-name new-context-name
Para alterar o namespace padrão de um contexto sem perder outras configurações:
kubectl config set-context prod-us-east --namespace=kube-system
Se você precisar de um novo contexto idêntico a um existente, mas com namespace diferente (cenário comum quando você trabalha com múltiplos namespaces em paralelo):
kubectl config set-context staging-admin \
--cluster=staging-cluster \
--user=dev@staging \
--namespace=admin
Agora você tem dois contextos: staging (namespace development) e staging-admin (namespace admin), ambos apontando para o mesmo cluster com o mesmo usuário. Essa flexibilidade é essencial para fluxos de trabalho complexos.
Comandos kubectl em Profundidade
Padrões de Consulta e Seleção
Além dos comandos básicos get e describe, kubectl oferece recursos poderosos de seleção e formatação. O padrão -l permite selecionar recursos por labels:
# Listar todos os pods com label app=nginx
kubectl get pods -l app=nginx
# Listar services que NÃO possuem um label específico
kubectl get svc -l '!managed-by'
# Combinações complexas
kubectl get pods -l 'tier=frontend,app!=web-old'
Labels são metadados estruturados que você adiciona aos recursos. Ao invés de usar grep em saídas de texto, use labels para filtrar — é mais confiável e mais rápido.
A formatação de saída é igualmente importante. O padrão -o json ou -o yaml permite que você processe saídas com ferramentas como jq:
# Obter o IP de todos os pods em um namespace
kubectl get pods -o jsonpath='{.items[*].status.podIP}'
# Listar nome e namespace de todos os recursos
kubectl get all -o custom-columns=NAME:.metadata.name,NAMESPACE:.metadata.namespace
# Formatação mais legível para humans
kubectl get nodes -o wide
O jsonpath é poderoso mas verboso. Para debugging rápido, use wide; para automação ou processamento, use json + jq. Exemplo prático:
# Encontrar pods que estão em estado "Pending"
kubectl get pods -o json | jq '.items[] | select(.status.phase=="Pending") | .metadata.name'
Exec, Logs e Port-Forward
Três comandos são fundamentais para debugging em produção: exec, logs e port-forward. Cada um resolve um problema específico.
exec permite você executar comandos dentro de um container rodando:
# Abrir shell interativo em um pod
kubectl exec -it deployment/nginx -- /bin/bash
# Rodar comando único e retornar
kubectl exec pod/my-app-xyz -- ps aux
# Entrar em um container específico se o pod tem múltiplos
kubectl exec -it pod/multi-container -c container-name -- bash
logs recupera saída do processo principal do container. Por padrão mostra logs do último container que falhou:
# Últimas 100 linhas de logs
kubectl logs pod/my-app --tail=100
# Seguir logs em tempo real (como tail -f)
kubectl logs -f deployment/nginx --all-containers=true
# Logs de pods anteriores que foram reiniciados
kubectl logs pod/my-app --previous
# Logs com timestamps
kubectl logs deployment/api --timestamps=true
port-forward cria um túnel local para um serviço rodando no cluster, útil para acessar interfaces web ou bancos de dados:
# Acessar aplicação que escuta na porta 8080 do cluster localmente na 3000
kubectl port-forward service/webapp 3000:8080
# Para um pod específico
kubectl port-forward pod/postgres-0 5432:5432
# Em background
kubectl port-forward svc/redis 6379:6379 &
Aplicando e Gerenciando Recursos
apply é o comando mais usado para criar ou atualizar recursos a partir de arquivos YAML:
# Aplicar um arquivo
kubectl apply -f deployment.yaml
# Aplicar diretório inteiro
kubectl apply -f ./manifests/
# Aplicar a partir de stdin
cat my-config.yaml | kubectl apply -f -
# Dry-run para ver o que seria aplicado sem fazer
kubectl apply -f deployment.yaml --dry-run=client -o yaml
# Server-side dry-run (valida contra estado real do cluster)
kubectl apply -f deployment.yaml --dry-run=server
Ao contrário de create, apply é idempotente — executar múltiplas vezes produz o mesmo resultado. Isso torna seguro executar em pipelines CI/CD. O --dry-run=server é especialmente útil: ele valida seu YAML contra as regras do servidor sem realmente aplicar, evitando surpresas.
Para atualizar um recurso sem recriar:
# Editar interativamente (abre seu editor padrão)
kubectl edit deployment nginx
# Patchear um campo específico
kubectl patch deployment nginx -p '{"spec":{"replicas":5}}'
# Alternar imagem de um deployment
kubectl set image deployment/nginx nginx=nginx:1.21 --record
O --record adiciona uma anotação de histórico, útil para entender quem fez o quê e quando. Você pode visualizar com:
kubectl rollout history deployment/nginx
Deleção de Recursos
Deletar é tão importante quanto criar. Entender as nuances evita desastres:
# Deletar um recurso
kubectl delete pod my-pod
# Deletar múltiplos recursos
kubectl delete pods pod1 pod2 pod3
# Deletar por label
kubectl delete pods -l app=old-version
# Deletar tudo em um namespace (cuidado!)
kubectl delete all --all -n production
# Deletar com atraso de graça (graceful shutdown)
kubectl delete pod my-pod --grace-period=30
# Deletar imediatamente sem graça (force)
kubectl delete pod my-pod --force --grace-period=0
O --grace-period permite que a aplicação se prepare para desligar. Padrão é 30 segundos. Use --force apenas quando estritamente necessário — não dá à aplicação chance de limpar recursos.
Debugging e Monitoramento com kubectl
Investigando Estado do Cluster
Quando algo quebra, você precisa entender o estado atual. describe é seu melhor amigo:
# Descrição detalhada de um pod
kubectl describe pod my-app-xyz
# Eventos recentes que afetaram o pod
kubectl get events --sort-by='.lastTimestamp' -n production
# Status dos nós
kubectl describe node node-01
# Verificar se há problemas de recursos
kubectl top nodes
kubectl top pods --all-namespaces
describe mostra metadados, status atual, eventos e condições — é a visão 360 graus. events mostra o histórico de mudanças. Juntos, permitem diagnoscar 90% dos problemas.
Para problemas de rede ou DNS:
# Testar DNS dentro do cluster
kubectl run -it --rm debug --image=busybox --restart=Never -- nslookup my-service
# Verificar conectividade para um serviço
kubectl run -it --rm nettest --image=nicolaka/netcat --restart=Never -- -zv service.namespace 80
# Acessar logs de inicialização (muito útil para CrashLoopBackOff)
kubectl logs pod/my-app --previous --all-containers=true
Esses comandos executam ferramentas de rede dentro de um pod no cluster, permitindo testar conectividade do mesmo "lugar" que sua aplicação.
Monitoramento e Métricas
Kubernetes coleta métricas de CPU e memória nativamente (Metrics Server). Você pode consultar sem ferramentas adicionais:
# CPU e memória atual de todos os nós
kubectl top nodes
# CPU e memória de pods em um namespace
kubectl top pods -n production
# Pod que mais consome recursos
kubectl top pods --all-namespaces | sort -k3 -rn | head -10
Para análise mais profunda, use get com campos customizados:
# Ver requisições e limites de CPU/memória
kubectl get pods -o custom-columns=\
NAME:.metadata.name,\
CPU_REQ:.spec.containers[0].resources.requests.cpu,\
CPU_LIM:.spec.containers[0].resources.limits.cpu,\
MEM_REQ:.spec.containers[0].resources.requests.memory,\
MEM_LIM:.spec.containers[0].resources.limits.memory
# Ver imagens rodando em todos os nós
kubectl get pods --all-namespaces \
-o custom-columns=NAME:.metadata.name,IMAGE:.spec.containers[0].image
Entender requisições vs limites é crítico: requisições são o que kubectl usa para scheduling; limites são o máximo que o container pode usar antes de ser morto. Mismatch nestes valores causa problemas de performance ou OOMKill inesperado.
Conclusão
Dominar kubectl significa três coisas concretas. Primeiro, entender profundamente como kubeconfig e contexts funcionam — isso elimina confusão sobre "qual cluster estou usando?" e permite trabalhar com múltiplos clusters sem medo. Segundo, conhecer os comandos core além do básico: patch, exec, logs, port-forward e as nuances de apply vs create — esses são seus ferramentas do dia a dia. Terceiro, saber debugar eficientemente com describe, events e top — quando algo quebra, você resolve em minutos, não horas.
A chave é prática. Configure múltiplos contexts hoje mesmo, teste exec e logs em um ambiente seguro, e estude os eventos quando deployments falharem. kubectl é uma ferramenta com grande profundidade — cada comando tem flags e comportamentos que você descobrirá ao usá-lo. Comece pelos comandos aqui apresentados, consulte kubectl --help frequentemente, e você rapidamente se tornará proficiente.