Network Policies: isolando tráfego entre pods
1. Introdução ao Isolamento de Tráfego em Kubernetes
1.1. Por que o isolamento padrão do Kubernetes é insuficiente
Por padrão, o Kubernetes adota uma topologia de flat network — todos os Pods podem se comunicar com todos os outros Pods, independentemente do namespace. Essa abertura total é conveniente para desenvolvimento, mas representa um risco grave de segurança em produção. Um atacante que comprometa um Pod pode se mover lateralmente para qualquer serviço interno, acessar bancos de dados ou até mesmo exfiltrar dados.
1.2. O papel das Network Policies na segurança de microsserviços
As Network Policies atuam como firewalls virtuais no nível do Pod, definindo regras de tráfego baseadas em labels, namespaces e IP blocks. Elas implementam o princípio do menor privilégio: um Pod deve se comunicar apenas com os serviços estritamente necessários para sua função.
1.3. Pré-requisitos: CNI plugins compatíveis
Network Policies não funcionam com todos os CNI plugins. É necessário que o plugin suporte o recurso. Os mais comuns são:
- Calico (padrão em muitos clusters gerenciados)
- Cilium (baseado em eBPF, alta performance)
- Weave Net
- Antrea
- Flannel (não suporta Network Policies nativamente — requer extensão)
Verifique seu CNI com:
kubectl get pods -n kube-system | grep -E "calico|cilium|weave|antrea"
2. Anatomia de uma Network Policy
2.1. Estrutura YAML
Toda Network Policy segue esta estrutura básica:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-frontend-to-backend
spec:
podSelector:
matchLabels:
app: backend
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- protocol: TCP
port: 8080
2.2. Seletores de pods e namespaces
Labels são o mecanismo de identidade em Kubernetes. Uma Network Policy pode selecionar Pods alvo (podSelector) e Pods origem (from.podSelector). Também é possível selecionar namespaces inteiros:
ingress:
- from:
- namespaceSelector:
matchLabels:
environment: production
2.3. Regras de entrada e saída
As regras podem especificar:
- Ingress: tráfego que chega ao Pod
- Egress: tráfego que sai do Pod
- Ambos os tipos, com combinações de:
podSelector(pods específicos)namespaceSelector(namespaces específicos)ipBlock(faixas CIDR externas)ports(portas e protocolos)
3. Políticas de Ingress: Controlando Tráfego de Entrada
3.1. Permitindo tráfego apenas de pods específicos
Exemplo: apenas Pods com label app: frontend podem acessar Pods app: backend na porta 8080:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: backend-ingress
spec:
podSelector:
matchLabels:
app: backend
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- protocol: TCP
port: 8080
3.2. Restringindo acesso por namespace de origem
Para isolar ambientes (dev, staging, production):
ingress:
- from:
- namespaceSelector:
matchLabels:
environment: production
- podSelector:
matchLabels:
app: api-gateway
3.3. Combinando seletores com ipBlock
Para permitir tráfego externo controlado (ex: monitoramento Prometheus):
ingress:
- from:
- ipBlock:
cidr: 10.0.0.0/24
except:
- 10.0.0.5/32
ports:
- port: 9090
4. Políticas de Egress: Controlando Tráfego de Saída
4.1. Bloqueando comunicação indesejada
Por padrão, um Pod pode acessar qualquer destino. Com política de egress, restringimos:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: app-egress
spec:
podSelector:
matchLabels:
app: web
policyTypes:
- Egress
egress:
- to:
- podSelector:
matchLabels:
app: database
ports:
- port: 5432
4.2. Permitindo acesso seletivo
Para acesso a bancos de dados, caches ou APIs externas:
egress:
- to:
- ipBlock:
cidr: 192.168.1.0/24
ports:
- port: 6379 # Redis
- to:
- ipBlock:
cidr: 0.0.0.0/0
ports:
- port: 443
4.3. Uso de ports e ipBlock
Restringir saída apenas para DNS e API externa específica:
egress:
- to:
- ipBlock:
cidr: 10.96.0.10/32 # CoreDNS
ports:
- port: 53
protocol: UDP
- to:
- ipBlock:
cidr: 203.0.113.0/24
ports:
- port: 443
5. Estratégias de Isolamento por Ambiente e Aplicação
5.1. Abordagem "default deny" vs. "default allow"
Default deny é a prática recomendada para produção:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
Isso bloqueia todo tráfego. Em seguida, crie políticas específicas para liberar o necessário.
Default allow é o comportamento nativo do Kubernetes — inseguro para produção, mas útil para desenvolvimento.
5.2. Políticas por camada
Arquitetura típica de três camadas:
- Frontend: permite ingress do Ingress Controller, egress para Backend
- Backend: permite ingress do Frontend, egress para Database
- Database: permite ingress apenas do Backend na porta 5432
5.3. Isolamento multi-tenant
Para times diferentes no mesmo cluster:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-cross-namespace
namespace: team-alpha
spec:
podSelector: {}
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: team-alpha
6. Monitoramento, Depuração e Troubleshooting
6.1. Verificando políticas aplicadas
kubectl get networkpolicy -n <namespace>
kubectl describe networkpolicy <nome> -n <namespace>
6.2. Ferramentas de diagnóstico
Teste conectividade com:
kubectl exec -it <pod-name> -- curl http://<target-service>:<port>
kubectl exec -it <pod-name> -- nc -zv <target-ip> <port>
Para logs detalhados, verifique os logs do CNI:
kubectl logs -n kube-system <calico-node-pod> | grep -i policy
6.3. Problemas comuns
- Políticas conflitantes: regras mais específicas podem ser sobrescritas por regras mais genéricas
- Ordem de avaliação: regras são avaliadas em ordem, mas a primeira correspondência vence
- Falsos positivos: um Pod pode estar sem labels corretas, fazendo a política não se aplicar
Solução: sempre verifique os labels dos Pods e use kubectl get pods --show-labels.
7. Boas Práticas e Integração com o Fluxo DevOps
7.1. Versionamento de Network Policies no Git
Trate Network Policies como código:
infra/
├── namespaces/
│ └── production/
│ └── network-policies/
│ ├── default-deny.yaml
│ ├── frontend.yaml
│ ├── backend.yaml
│ └── database.yaml
7.2. Testes automatizados de conectividade
Em pipelines CI/CD, use ferramentas como k6 ou curl em Pods temporários:
kubectl run test-pod --image=alpine/curl --rm -it --restart=Never -- /bin/sh -c "curl -s http://backend-svc:8080/health"
7.3. Relação com temas vizinhos
Network Policies se integram com:
- GitOps (ArgoCD, Flux): políticas aplicadas automaticamente
- External Secrets: senhas de bancos que as políticas protegem
- Resource Quotas: limite de recursos por namespace
- Pod Security Standards: políticas de segurança em nível de Pod
Referências
- Kubernetes Official Documentation: Network Policies — Documentação oficial completa sobre Network Policies, com exemplos e especificações.
- Calico: Kubernetes Network Policy Tutorial — Guia prático da Tigera (mantenedora do Calico) sobre implementação de políticas de rede.
- Cilium: Network Policy Examples — Exemplos avançados de Network Policies usando Cilium e eBPF.
- Learn Kubernetes: Network Policy Tutorial by KodeKloud — Tutorial passo a passo com cenários reais de isolamento de tráfego.
- GitHub: Kubernetes Network Policy Recipes — Repositório com dezenas de receitas práticas de Network Policies para diferentes cenários.