Network Policies em Kubernetes: Isolamento de Rede entre Pods: Do Básico ao Avançado Já leu

Network Policies em Kubernetes: Isolamento de Rede entre Pods Network Policies são recursos fundamentais do Kubernetes que permitem controlar o tráfego de rede entre pods, implementando segurança em nível de microsserviços. Por padrão, o Kubernetes permite comunicação irrestrita entre todos os pods em um cluster, o que viola o princípio do menor privilégio. Com Network Policies, você define regras explícitas de entrada (ingress) e saída (egress) de tráfego, criando um modelo de segurança robusto e granular. Neste artigo, vamos explorar como as Network Policies funcionam, quando e por que utilizá-las, e como implementá-las de forma prática em seus clusters. Entender esse conceito é essencial para qualquer engenheiro que trabalha com Kubernetes em ambientes de produção. O que é uma Network Policy e Como Funciona Entendendo o Conceito Fundamental Uma Network Policy é um objeto Kubernetes que define regras de firewall para pods. Ela atua no nível de rede, controlando quais pods podem se comunicar entre si através de seletores de

Network Policies em Kubernetes: Isolamento de Rede entre Pods

Network Policies são recursos fundamentais do Kubernetes que permitem controlar o tráfego de rede entre pods, implementando segurança em nível de microsserviços. Por padrão, o Kubernetes permite comunicação irrestrita entre todos os pods em um cluster, o que viola o princípio do menor privilégio. Com Network Policies, você define regras explícitas de entrada (ingress) e saída (egress) de tráfego, criando um modelo de segurança robusto e granular.

Neste artigo, vamos explorar como as Network Policies funcionam, quando e por que utilizá-las, e como implementá-las de forma prática em seus clusters. Entender esse conceito é essencial para qualquer engenheiro que trabalha com Kubernetes em ambientes de produção.

O que é uma Network Policy e Como Funciona

Entendendo o Conceito Fundamental

Uma Network Policy é um objeto Kubernetes que define regras de firewall para pods. Ela atua no nível de rede, controlando quais pods podem se comunicar entre si através de seletores de labels. Quando uma Network Policy é criada, o controlador de rede do cluster (como Calico, Weave ou Cilium) implementa essas regras no sistema operacional do nó, geralmente através de iptables ou eBPF.

A grande diferença entre Network Policy e um firewall tradicional é que ela trabalha com abstrações do Kubernetes (labels, namespaces) ao invés de endereços IP. Isso torna as regras portáveis e dinâmicas: mesmo que um pod seja recriado com um novo IP, a política continua aplicável porque se baseia em labels.

Componentes de uma Network Policy

Uma Network Policy consiste em quatro elementos principais:

  • podSelector: Define quais pods a política se aplica (usando labels)
  • policyTypes: Especifica se a política controla tráfego de Ingress, Egress ou ambos
  • ingress: Lista de regras que permitem tráfego de entrada
  • egress: Lista de regras que permitem tráfego de saída

Quando uma Network Policy é aplicada a um pod através do podSelector, esse pod entra em modo restritivo: por padrão, todo tráfego é bloqueado, exceto o explicitamente permitido pelas regras. Isso é importante: ausência de regra significa negação.

Implementando Network Policies na Prática

Exemplo 1: Bloqueio Total com Permissão Seletiva

Vamos começar com um caso simples: bloquear todo o tráfego de entrada e permitir apenas de pods específicos. Este é um padrão muito comum em produção.

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-all-ingress
  namespace: default
spec:
  podSelector: {}
  policyTypes:
  - Ingress

Essa política aplica-se a todos os pods no namespace (porque podSelector: {} está vazio) e nega todo tráfego de entrada. Agora, vamos permitir tráfego apenas de pods com label role: frontend:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-from-frontend
  namespace: default
spec:
  podSelector:
    matchLabels:
      role: backend
  policyTypes:
  - Ingress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          role: frontend
    ports:
    - protocol: TCP
      port: 8080

Aqui, apenas pods com role: backend são afetados. Eles receberão tráfego TCP na porta 8080 vindo de pods com role: frontend. Qualquer outro tráfego é bloqueado.

Exemplo 2: Controle de Egress (Saída)

Nem sempre pensamos em bloquear tráfego de saída, mas é igualmente importante. Vamos criar uma política que permite que um pod de aplicação acesse apenas um banco de dados específico:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-app-to-db
  namespace: production
spec:
  podSelector:
    matchLabels:
      app: myapp
  policyTypes:
  - Egress
  egress:
  - to:
    - podSelector:
        matchLabels:
          app: postgres
    ports:
    - protocol: TCP
      port: 5432
  - to:
    - namespaceSelector:
        matchLabels:
          name: kube-system
    ports:
    - protocol: TCP
      port: 53
    - protocol: UDP
      port: 53

Neste exemplo, o pod myapp pode fazer requisições saintes para:
1. Pods postgres na mesma rede na porta 5432
2. Qualquer pod no namespace kube-system nas portas 53 (DNS)

Observe que adicionamos uma regra DNS. Sem ela, o pod não conseguiria resolver nomes de domínio, mesmo podendo fazer conexões.

Exemplo 3: Política com Múltiplos Critérios

Políticas complexas precisam de múltiplos seletores. Vamos permitir tráfego de múltiplas origens:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: complex-policy
  namespace: default
spec:
  podSelector:
    matchLabels:
      tier: api
  policyTypes:
  - Ingress
  - Egress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          role: frontend
    - namespaceSelector:
        matchLabels:
          environment: staging
    ports:
    - protocol: TCP
      port: 8080
  - from:
    - namespaceSelector: {}
    ports:
    - protocol: TCP
      port: 443
  egress:
  - to:
    - podSelector:
        matchLabels:
          tier: database
    ports:
    - protocol: TCP
      port: 5432
  - to:
    - namespaceSelector: {}
    ports:
    - protocol: TCP
      port: 443
    - protocol: TCP
      port: 80

Nesta política:
- Pods com tier: api recebem tráfego na porta 8080 de pods frontend OU de qualquer pod em namespaces com label environment: staging
- Recebem tráfego na porta 443 de qualquer namespace
- Enviam tráfego apenas para pods database na porta 5432 e para qualquer destino nas portas 80 e 443

Estratégias e Melhores Práticas

Começar Restritivo e Evoluir

A abordagem mais segura é começar com uma "deny-all" policy em todos os namespaces e depois adicionar permissões conforme necessário. Muitos engenheiros fazem o oposto e perdem o controle rapidamente.

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-all
  namespace: production
spec:
  podSelector: {}
  policyTypes:
  - Ingress
  - Egress

Quando essa política está em vigor, nenhum pod consegue comunicar. A partir daí, você adiciona exceções necessárias. Essa abordagem garante que você está explicitamente permitindo o que precisa, não tentando negar tudo que não deveria.

Usar Namespaces como Barreira

Namespaces fornecem um isolamento organizacional natural. Combine-os com Network Policies para criar zonas de segurança:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: isolate-namespace
  namespace: sensitive-data
spec:
  podSelector: {}
  policyTypes:
  - Ingress
  - Egress
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          name: sensitive-data
  egress:
  - to:
    - namespaceSelector:
        matchLabels:
          name: sensitive-data
  - to:
    - podSelector:
        matchLabels:
          role: external-api

Isso isola um namespace inteiro, permitindo comunicação apenas interna e com serviços externos aprovados.

Debugging e Validação

Para verificar se suas políticas estão funcionando, você pode testar conectividade entre pods:

# Execute um pod de teste
kubectl run -it --rm debug --image=busybox --restart=Never -- sh

# Dentro do pod, teste conectividade
wget -O- http://service-name:port

# Verifique logs de iptables (se disponível)
kubectl exec -it pod-name -- iptables -L -n

Uma ferramenta excelente é o kube-networkpolicy-viewer ou usar logs do seu CNI plugin (Calico, Cilium) para auditoria.

Considerações Técnicas Importantes

Requisitos de Infraestrutura

Network Policies só funcionam com CNI plugins que as suportam. Kubernetes com kubenet (padrão em alguns casos) não funciona com Network Policies. Você precisa de:

  • Calico: Excelente suporte, usa iptables/eBPF
  • Cilium: Suporte avançado com eBPF, ideal para produção
  • Weave: Funciona bem, bom para ambientes menores
  • Kube-router: Alternativa leve

Se está usando um serviço gerenciado (EKS, GKE, AKS), o provedor já oferece um CNI compatível.

Performance e Impacto

Network Policies baseadas em iptables podem impactar performance em clusters muito grandes com mudanças frequentes de pods. Cilium com eBPF é mais eficiente. Porém, para a maioria dos casos, o impacto é negligenciável.

Teste em staging antes de rollout em produção. Identifique os padrões de comunicação real:

# Use ferramentas como Cilium CLI para mapear tráfego
cilium connectivity test

# Ou verifique logs do seu observability stack
# (Prometheus, ELK, Jaeger, etc)

Conclusão

Network Policies são um componente essencial de uma arquitetura Kubernetes segura. Os três pontos principais que você deve levar deste artigo são:

  1. Princípio do Menor Privilégio: Comece negando tudo e permita apenas o necessário. Isso previne vazamentos de dados e movimentação lateral de ataques.

  2. Abstrações Kubernetes: Use labels e seletores, não endereços IP. Isso torna suas políticas resilientes a mudanças dinâmicas de pods e fáceis de manter.

  3. Validação Contínua: Network Policies não funcionam isoladas. Combine com observability, auditoria de logs e testes regulares para garantir que estão tendo o efeito desejado.

A implementação de Network Policies não é opcional em ambientes de produção, especialmente quando múltiplas equipes compartilham um cluster. Invista tempo compreendendo os padrões de comunicação reais da sua aplicação antes de implementar as políticas.

Referências


Artigos relacionados