Ephemeral containers: debugging sem alterar o pod
1. O que são Ephemeral Containers e por que surgiram?
O debugging em clusters Kubernetes sempre foi um desafio para times de DevOps. O clássico kubectl exec permite acesso a um container em execução, mas falha quando:
- O container não possui shell ou ferramentas de diagnóstico (
sh,curl,tcpdump) - O container está em estado
CrashLoopBackOffe não aceita comandos - Você precisa de ferramentas específicas que não podem ser instaladas na imagem de produção
Ephemeral containers surgiram para resolver exatamente esse problema. Eles são containers temporários que se anexam a um pod já em execução, sem modificar a especificação original do pod. Diferentemente de sidecars (que são declarados no deployment e executam durante todo o ciclo de vida) ou init containers (que executam e morrem antes dos containers principais), os ephemeral containers são injetados sob demanda e existem apenas enquanto você precisa deles.
A característica fundamental é: você não precisa alterar o Deployment, StatefulSet ou Pod original. O pod continua intacto, mas ganha um container extra para debugging.
2. Pré-requisitos e habilitação da feature
A feature EphemeralContainers passou por estágios:
- Kubernetes 1.16: alpha (feature gate necessário)
- Kubernetes 1.23: beta (habilitado por padrão em muitos clusters)
- Kubernetes 1.25+: estável (GA), disponível sem configuração adicional
Se você estiver em versões antigas, verifique o feature gate:
kubectl describe node | grep -i ephemeral
Para RBAC, a permissão necessária é pods/ephemeralcontainers. Um ClusterRole típico:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: ephemeral-debugger
rules:
- apiGroups: [""]
resources: ["pods/ephemeralcontainers"]
verbs: ["create", "get", "list", "update", "patch", "delete"]
3. Comandos fundamentais: kubectl alpha debug e alternativas
O comando principal é kubectl debug. Até o Kubernetes 1.27, pode ser necessário usar kubectl alpha debug em algumas distribuições.
Sintaxe básica para anexar um ephemeral container ao pod em execução:
kubectl debug my-pod -it --image=busybox --target=my-container
Flags importantes:
--target: especifica o container alvo (para compartilhar namespace de processos)--copy-to: cria um pod duplicado (útil quando o pod não está Running)--share-processes: permite ver processos do container alvo via/proc--container: nome personalizado para o ephemeral container
Diferença crucial: usar --copy-to cria um pod separado (clone), enquanto o comportamento padrão anexa ao pod existente sem modificar sua especificação.
4. Debugando sem modificar o pod original
O caso de uso mais comum é anexar um container com ferramentas de rede a um pod de produção que só tem o binário da aplicação.
Exemplo prático: anexar nicolaka/netshoot (imagem repleta de ferramentas como curl, dig, tcpdump, nslookup):
kubectl debug my-app-pod -it --image=nicolaka/netshoot --target=my-app-container
Dentro do netshoot, você pode:
# Ver processos do container alvo (com --share-processes)
ps aux
# Acessar sistema de arquivos do container alvo via /proc/PID/root
ls -la /proc/1/root/app/config.json
# Inspecionar variáveis de ambiente
cat /proc/1/environ | tr '\0' '\n'
# Ver arquivos de configuração compartilhados
cat /proc/1/root/etc/nginx/nginx.conf
5. Casos de uso avançados
Debug de falhas de startup: containers que nunca ficam Running (CrashLoopBackOff) não podem receber kubectl debug direto. Use --copy-to:
kubectl debug my-crashing-pod -it --image=busybox --copy-to=my-debug-pod
Isso cria um pod duplicado com um container extra, permitindo inspecionar volumes, variáveis de ambiente e configurações antes mesmo do container principal iniciar.
Coleta de dump de memória sem reiniciar: anexe um ephemeral container com gdb ou jcmd (para Java) e capture heap dumps:
kubectl debug my-java-pod -it --image=openjdk:11-slim --target=java-container
jcmd 1 GC.heap_dump /tmp/heap.hprof
Teste de conectividade entre pods: crie um pod duplicado em outro namespace para testar comunicação:
kubectl debug my-pod -it --image=nicolaka/netshoot --copy-to=debug-pod --namespace=debug-ns
6. Limitações e boas práticas
Restrições de segurança: ephemeral containers herdam o securityContext do pod, mas não podem ultrapassar PodSecurityPolicy (PSP) ou Pod Security Standards (PSS). Se o pod roda como restricted, seu ephemeral container também rodará restrito.
Não persistem: se o pod for recriado (por exemplo, após um rollout), o ephemeral container desaparece. Eles não fazem parte da especificação do pod e não são recriados.
Impacto em recursos: ephemeral containers consomem CPU e memória adicionais. Monitore com:
kubectl top pod my-pod
Logs: logs do ephemeral container aparecem junto com os do pod, mas podem ser filtrados pelo nome do container:
kubectl logs my-pod -c debug-container
Boas práticas:
- Sempre remova ephemeral containers após o uso com
kubectl delete pod --forceou editando a especificação (remova o campoephemeralContainers) - Use imagens pequenas como
busybox,alpineoudistrolesspara evitar overhead - Documente os comandos de debug para que o time inteiro possa usar
7. Comparação com ferramentas externas
| Ferramenta | Quando usar | Limitação |
|---|---|---|
kubectl debug |
Debug direto em pods running | Não funciona em CrashLoopBackOff sem --copy-to |
kubectl-node-shell |
Acesso ao nó (kubelet, containerd) | Não resolve problemas de aplicação |
stern + kubetail |
Agregação de logs multi-pod | Apenas logs, sem acesso interativo |
k9s |
Interface TUI para gestão de clusters | Debug limitado a execução de comandos |
Ephemeral containers não são a melhor escolha quando:
- Você precisa de debug persistente (use sidecar)
- O cluster é muito antigo (< 1.16)
- Há restrições severas de segurança que impedem containers interativos
8. Exemplo completo: debug de um pod com falha de DNS
Cenário: aplicação web-frontend não resolve nomes de domínio externos.
Passo 1: Verificar estado do pod
kubectl get pods web-frontend
NAME READY STATUS RESTARTS AGE
web-frontend 1/1 Running 2 15m
Passo 2: Anexar netshoot com compartilhamento de processos
kubectl debug web-frontend -it --image=nicolaka/netshoot --target=web-frontend-container
Passo 3: Testar DNS dentro do netshoot
# Testar resolução
nslookup google.com
;; connection timed out; no servers could be reached
# Ver configuração de DNS do pod
cat /etc/resolv.conf
search default.svc.cluster.local svc.cluster.local cluster.local
nameserver 10.96.0.10
options ndots:5
# Verificar conectividade com o servidor DNS
nc -zv 10.96.0.10 53
Passo 4: Identificar problema — o servidor DNS (CoreDNS) não está respondendo. Verifique o cluster:
kubectl get pods -n kube-system -l k8s-app=kube-dns
Passo 5: Limpeza — remova o ephemeral container
# Saia do container (Ctrl+D ou exit)
# Remova o campo ephemeralContainers do pod
kubectl patch pod web-frontend --type=json -p='[{"op": "remove", "path": "/spec/ephemeralContainers"}]'
Se preferir, force a exclusão e recriação:
kubectl delete pod web-frontend --force --grace-period=0
O deployment recriará o pod automaticamente.
Referências
- Kubernetes Documentation: Ephemeral Containers — Documentação oficial sobre ephemeral containers, incluindo definição, casos de uso e limitações.
- kubectl debug command reference — Referência completa do comando
kubectl debugcom todas as flags e exemplos. - Debugging Kubernetes Pods with Ephemeral Containers (Google Cloud Blog) — Artigo técnico da Google Cloud com exemplos práticos de debugging usando ephemeral containers.
- Netshoot: a network troubleshooting container — Repositório oficial da imagem netshoot, com lista completa de ferramentas de rede disponíveis.
- Kubernetes RBAC: pods/ephemeralcontainers permission — Documentação sobre as permissões RBAC necessárias para criar e gerenciar ephemeral containers.
- Debugging Kubernetes: Ephemeral Containers (Red Hat Developer) — Tutorial da Red Hat com cenários avançados de debugging usando ephemeral containers em clusters OpenShift.