kubectl debug: depurar um pod sem shell na imagem
Imagens distroless e scratch não têm shell, então o kubectl exec não tem o que abrir. O kubectl debug resolve isso com um container efêmero: um container temporário, com as ferramentas que você escolher, colocado dentro do pod que já está rodando.
Quando o kubectl exec não basta
O exec roda um comando dentro de um container que já existe. Se a imagem não tem sh, ele falha:
kubectl exec -it <pod> -n <namespace> -- sh
# OCI runtime exec failed: exec: "sh": executable file not found in $PATH 1. Abra um container efêmero com kubectl debug
O --target liga o container efêmero ao namespace de processos do container da aplicação, quando o runtime permite. Assim o ps mostra os processos dela:
kubectl debug -it <pod> -n <namespace> --image=busybox:1.36 --target=<container>
# Dentro do container efêmero
ps aux
ls /proc/1/root/ O sistema de arquivos da aplicação fica visível em /proc/<pid>/root, desde que o container efêmero rode com o mesmo usuário ou como root.
2. Escolha a imagem de debug
- busybox: sh, ps, wget, nslookup e o básico, numa imagem pequena.
- nicolaka/netshoot: curl, dig, nc, tcpdump, openssl e outras ferramentas de rede.
- Uma imagem da mesma linguagem da aplicação, quando você precisa do runtime dela.
- Em namespaces com PodSecurity restricted, uma imagem que rode como root pode ser recusada: nas versões mais novas do kubectl, --profile=restricted monta o container efêmero dentro do perfil.
3. Ou depure uma cópia do pod
Para um pod em CrashLoopBackOff, em que o container morre antes de você entrar, crie uma cópia com outro comando. O pod original continua como está:
# Cópia com um container de debug junto e processos compartilhados
kubectl debug <pod> -n <namespace> -it --copy-to=<pod>-debug \
--image=busybox:1.36 --share-processes
# Cópia em que o container da aplicação abre um shell em vez do comando dele
kubectl debug <pod> -n <namespace> -it --copy-to=<pod>-debug \
--container=<container> -- sh
# Apague a cópia no fim
kubectl delete pod <pod>-debug -n <namespace> A cópia é um pod novo, fora do Deployment: ela não recebe tráfego do Service, a menos que tenha os mesmos labels.
O que saber sobre containers efêmeros
- Estáveis desde o Kubernetes 1.25.
- Não saem do pod: o container efêmero fica na lista até o pod ser apagado ou recriado, e não reinicia.
- Não têm portas, probes nem resources próprios.
- Pedem permissão de patch em pods/ephemeralcontainers no namespace, além de get em pods e create em pods/attach para o -it.
- Aparecem em kubectl describe pod, em Ephemeral Containers.
kubectl debug ou kubectl exec
| Situação | Use |
|---|---|
| A imagem tem shell e você só quer olhar dentro do container | kubectl exec |
| Imagem distroless ou scratch, sem shell | kubectl debug com --target |
| Faltam ferramentas na imagem (curl, dig, tcpdump) | kubectl debug com uma imagem de ferramentas |
| O container morre antes de você entrar (CrashLoopBackOff) | kubectl debug --copy-to, com outro comando |
| Você não pode mexer no pod de produção | kubectl debug --copy-to |
kubectl debug e o Kubepier
O Kubepier não cria containers efêmeros: para eles, use o kubectl debug do seu terminal. No Pro e no Team, o Kubepier abre shell num container que já existe, como o kubectl exec: na web, para admin, e no desktop. No desktop, os containers efêmeros de um pod aparecem nos detalhes dele, em Ephemeral Containers. O shell no nó existe na web (admin) e no desktop.
Para testar a rede de dentro do cluster sem mexer no pod da aplicação, o Bastion da web abre um terminal num pod temporário com as ferramentas do netshoot.