Série k8s: Pods — o básico do Kubernetes
Este post faz parte da série de fundamentos de Kubernetes. A ideia é apresentar conceitos essenciais em uma sequência prática, do básico ao avançado. Aqui vamos falar de Pods, o primeiro bloco de construção de qualquer aplicação no cluster.
Se você está começando, este é o momento de entender o que é um Pod e como ele se comporta. Se já usa Kubernetes, este texto serve como referência rápida com exemplos diretos.
O que é um Pod
Pod é a menor unidade que o Kubernetes cria e gerencia. Ele funciona como um “envelope” que agrupa um ou mais containers que precisam rodar juntos e compartilhar recursos.
Dentro de um Pod, os containers:
- Compartilham rede (mesmo IP e portas);
- Compartilham volumes (dados podem ser lidos/escritos entre eles);
- Compartilham ciclo de vida (sobem e descem juntos).
Você pode ter dois cenários principais:
- Pod com um container: é o caso mais comum. O Pod é apenas o wrapper do container.
- Pod com múltiplos containers: usado quando os containers são fortemente acoplados, como um app + sidecar de logs ou proxy.
Ciclo de vida do Pod
O ciclo de vida de um Pod descreve as fases pelas quais ele passa até ser finalizado. Entender isso ajuda muito no troubleshooting:
- Pending: o Pod foi aceito pelo cluster, mas ainda não foi agendado ou as imagens não foram baixadas.
- Running: o Pod já foi agendado em um nó e pelo menos um container está em execução.
- Succeeded: todos os containers terminaram com sucesso (comum em Jobs).
- Failed: algum container terminou com erro e o Pod não conseguiu completar.
- Unknown: o estado não pôde ser obtido do nó (problema de comunicação).
Durante a execução, você também verá motivos comuns como CrashLoopBackOff, ImagePullBackOff e ErrImagePull, que indicam problemas de inicialização e download de imagens.
Init Containers (containers de inicialização)
Init Containers são executados antes dos containers principais. Eles são úteis para tarefas de preparação, como:
- baixar configurações;
- verificar dependências;
- preparar volumes ou permissões.
Se um init container falha, o Pod não avança para o estado Running até que ele finalize com sucesso.
Sidecar Containers (containers auxiliares)
Sidecar containers rodam junto com o container principal dentro do mesmo Pod. Eles são usados para complementar a aplicação, por exemplo:
- coletar logs;
- fazer proxy/mesh;
- sincronizar arquivos ou configurar cache.
O sidecar compartilha rede e volumes com o container principal, por isso é ideal quando as funções precisam estar bem acopladas.
Ephemeral Containers (depuração)
Ephemeral containers são containers temporários usados para depuração. Eles não fazem parte do manifesto original e podem ser adicionados em um Pod em execução para investigar problemas.
Eles não reiniciam automaticamente e são indicados apenas para troubleshooting.
Disruptions (interrupções)
Disruptions são eventos que interrompem Pods, como:
- atualização de nós;
- escalonamento do cluster;
- manutenção planejada;
- falhas de infraestrutura.
Para reduzir impacto, usamos Pod Disruption Budgets (PDBs), que definem quantos Pods podem ficar indisponíveis durante uma manutenção.
Importante: você não usa vários containers no Pod para escalar. Escala se faz criando mais Pods, normalmente via Deployment.
Para que os Pods rodem, cada nó precisa ter um container runtime instalado (ex.: containerd ou CRI-O).
Mão na massa
Vamos para alguns comandos e exemplos práticos. Se você ainda não tem um cluster k8s local, utilize o nosso guia de instalação e configuração do Kind: instalar Kind no WSL.
Consultar Pods
- Listar Pods de um namespace específico:
kubectl get pods -n <namespace>
- Ver detalhes do Pod em YAML:
kubectl get pod <nome-do-pod> -o yaml
- Inspecionar eventos e status do Pod:
kubectl describe pod <nome-do-pod>
Criar e remover Pods
Criar um Pod simples
Arquivo: pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: meu-primeiro-pod
labels:
run: meu-primeiro-pod
spec:
containers:
- name: meu-primeiro-pod
image: nginx
ports:
- containerPort: 80
Aplicar o manifesto:
kubectl apply -f pod.yaml
Criar Pod com múltiplos containers
Arquivo: pod-mult-container.yaml
apiVersion: v1
kind: Pod
metadata:
name: meu-primeiro-pod-multi
labels:
run: meu-primeiro-pod-multi
spec:
containers:
- name: web
image: nginx
ports:
- containerPort: 80
- name: sidecar
image: alpine
args:
- sleep
- "1800"
kubectl apply -f pod-mult-container.yaml
Remover Pods
- Remover um Pod pelo nome:
kubectl delete pod <nome-do-pod>
- Remover o Pod definido em um arquivo:
kubectl delete -f pod.yaml
Logs
- Ver logs de um Pod:
kubectl logs <nome-do-pod>
- Acompanhar logs em tempo real:
kubectl logs -f <nome-do-pod>
- Ver logs de um container específico dentro do Pod:
kubectl logs <nome-do-pod> -c <container-name>
Acesso ao container
O comando attach conecta ao processo principal do container em execução:
kubectl attach <pod-name> -c <container-name>
O comando exec executa comandos dentro do container:
kubectl exec <pod-name> -c <container-name> -- <comando>
- Abrir shell interativo no container:
kubectl exec -it ubuntu -- bash
Limites de CPU e memória
Requests definem o mínimo garantido de CPU/memória para o container. Limits definem o máximo que ele pode consumir.
Arquivo: pod-limits.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-com-limits
labels:
run: pod-com-limits
spec:
containers:
- name: app
image: nginx
ports:
- containerPort: 80
resources:
limits:
memory: "128Mi"
cpu: "0.5"
requests:
memory: "64Mi"
cpu: "0.3"
Aplicar o manifesto:
kubectl apply -f pod-limits.yaml
Validar Pods criados:
kubectl get pods
Opcional: testar consumo com stress dentro do container:
apt update
apt install -y stress
stress --vm 1 --vm-bytes 100M
Volume EmptyDir no Pod
EmptyDir é um volume temporário criado quando o Pod inicia e removido quando o Pod é destruído. É útil para compartilhamento de dados entre containers no mesmo Pod.
Arquivo: pod-emptydir.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-emptydir
spec:
containers:
- name: app
image: ubuntu
args:
- sleep
- infinity
volumeMounts:
- name: primeiro-emptydir
mountPath: /dados
volumes:
- name: primeiro-emptydir
emptyDir:
sizeLimit: 256Mi
Criar Pod com volume EmptyDir:
kubectl apply -f pod-emptydir.yaml
No próximo post da série, vamos aprofundar em Deployments, com exemplos práticos.
