Marcio Cunha

Isolamento de Carga de Trabalho em Ambientes Multi-Tenant Kubernetes com Network Policies e Gatekeeper

Aprenda como blindar clusters Kubernetes compartilhados utilizando Network Policies e OPA Gatekeeper para garantir isolamento robusto entre diferentes equipes ou clientes.

Marcio Cunha•5 min
Também disponível em:EnglishEspañol
Resumo
  • Namespaces nativos oferecem apenas divisão lógica rasa e exigem controles adicionais de segurança para impedir o tráfego lateral indesejado entre equipes distintas no mesmo cluster.
  • Network Policies funcionam como regras de trânsito de uma cidade, bloqueando ou permitindo o fluxo de pacotes na camada de rede com base em rótulos e seletores.
  • OPA Gatekeeper atua como um fiscal de portaria automatizado, impedindo a criação de recursos mal configurados ou inseguros antes mesmo que eles alcancem o ambiente produtivo.
  • A combinação de restrições de rede e validação de políticas de admissão reduz drasticamente o raio de explosão caso um componente isolado seja comprometido por invasores.
  • Ambientes multi-tenant eficientes exigem auditoria contínua e testes regulares de penetração para validar se as barreiras de software realmente suportam falhas inesperadas.

O Desafio de Compartilhar Infraestrutura com Segurança

Imagine um prédio comercial onde várias empresas alugam salas diferentes, mas compartilham o mesmo saguão, os mesmos elevadores e a mesma rede elétrica. Se uma porta ficar destrancada, qualquer pessoa pode entrar no escritório vizinho. No mundo da computação em nuvem, essa analogia descreve o ambiente multi-tenant (ou multilocatário) no Kubernetes, onde múltiplos projetos ou clientes rodam dentro de uma mesma estrutura física ou lógica. Na prática, isso significa otimizar custos e reduzir a complexidade operacional, mas abre margem para sérios riscos de segurança se as fronteiras não forem rigorosamente controladas.

Quando falamos de Kubernetes, o isolamento padrão baseado apenas em namespaces (compartimentos lógicos de trabalho) é frágil. Por padrão, qualquer pod (a menor unidade de computação que roda containers) consegue conversar com qualquer outro pod em qualquer namespace, a menos que alguma regra impeça isso. Na prática, essa liberdade inicial facilita o desenvolvimento, mas transforma um incidente em uma brecha catastrófica. Se o sistema de uma equipe for invadido, o atacante ganha uma autoestrada livre para explorar os demais serviços rodando no mesmo cluster.

Controlando o Tráfego de Rede com Network Policies

Para colocar ordem nessa bagunça de conexões abertas, utilizamos as Network Policies (políticas de rede). Em termos simples, elas funcionam como as regras de um condomínio fechado que determinam quem pode visitar quem. Sem uma política explícita, o tráfego é totalmente livre (comportamento conhecido como allow-all). Quando aplicamos uma política restritiva, o cluster passa a adotar o princípio do menor privilégio, bloqueando tudo por padrão e liberando apenas as portas e endereços estritamente necessários para o funcionamento das aplicações.

Na prática, configurar uma Network Policy exige o uso de seletores baseados em rótulos (labels), que funcionam como crachás de identificação colados nos pods. Podemos definir, por exemplo, que o banco de dados do projeto Alfa só aceita conexões vindas exclusivamente do microsserviço de autenticação do mesmo projeto, ignorando qualquer tentativa de acesso vinda de outras equipes. Abaixo, veja um exemplo prático de manifesto em formato YAML que bloqueia todo o tráfego de entrada em um namespace específico:

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

Esse bloco de código define uma muralha intransponível para novos acessos externos naquele espaço de trabalho. O campo podSelector vazio indica que a regra se aplica a todos os pods do namespace equipe-alfa, enquanto o policyTypes Ingress garante que o bloqueio atua sobre o tráfego que tenta entrar. A partir desse momento, qualquer comunicação adicional precisa ser autorizada por regras complementares que liberem conexões específicas, garantindo que o tráfego lateral indesejado seja totalmente neutralizado.

Impondo Governança com OPA Gatekeeper

Se as Network Policies controlam o que acontece depois que os recursos estão rodando, o OPA Gatekeeper atua antes mesmo que qualquer erro chegue ao cluster. O Open Policy Agent (OPA) combinado com o Gatekeeper funciona como um fiscal rigoroso de portaria. Ele intercepta todas as requisições enviadas ao servidor da API do Kubernetes e valida se o que está sendo criado cumpre as regras de conformidade da empresa. Na prática, isso impede que engenheiros distraídos criem pods sem limites de consumo de CPU, usem imagens de fontes não confiáveis ou esqueçam de aplicar os rótulos de isolamento obrigatórios.

O Gatekeeper utiliza uma linguagem declarativa chamada Rego para escrever essas regras de validação, chamadas de Constraints. Em vez de confiar apenas na boa vontade da equipe de desenvolvimento, a plataforma rejeita automaticamente qualquer tentativa de implantação irregular e devolve uma mensagem explicativa ao usuário. Essa abordagem shift-left (trazer a segurança para o início do ciclo de vida) evita que vulnerabilidades estruturais cheguem aos ambientes de homologação ou produção, poupando horas preciosas de depuração durante incidentes críticos.

Implementando Validações de Segurança na Prática

Para entender como o Gatekeeper protege o multi-tenancy, imagine a necessidade de garantir que nenhum pod seja executado sem especificar limites de recursos, evitando que um inquilino ruidoso (noisy neighbor) consuma toda a memória do nó e derrube os serviços dos outros. O processo prático envolve primeiro a criação de um modelo de restrição (ConstraintTemplate) e, em seguida, a aplicação da restrição propriamente dita. Veja o exemplo abaixo de uma restrição que exige limites explícitos de CPU e memória:

apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sRequiredResources
metadata:
  name: require-cpu-mem-limits
spec:
  match:
    kinds:
      - apiGroups: [""]
        kinds: ["Pod"]
    namespaces:
      - equipe-alfa
      - equipe-beta

Esse código instrui o Kubernetes a rejeitar qualquer criação de pod nos namespaces da equipe alfa e beta caso o desenvolvedor não tenha declarado o uso máximo de recursos. Na prática, isso blinda a infraestrutura compartilhada contra abusos acidentais ou intencionais. Quando combinamos essa governança preventiva com o controle rígido de tráfego de rede, transformamos um cluster compartilhado e caótico em um ambiente corporativo seguro, previsível e altamente resiliente.

Considerações Finais sobre Arquiteturas Multi-Tenant

Garantir o isolamento de cargas de trabalho em um cluster Kubernetes compartilhado não é uma tarefa que se resolve com uma única ferramenta mágica, mas sim com uma estratégia em camadas. A utilização conjunta de namespaces lógicos, Network Policies restritivas e OPA Gatekeeper cria uma defesa em profundidade capaz de conter falhas e mitigar ataques laterais com eficiência. Na prática, o sucesso dessa jornada depende tanto da automação quanto da conscientização contínua das equipes sobre a importância de respeitar os limites de segurança estabelecidos.

À medida que a adoção de microsserviços cresce e a pressão por redução de custos se intensifica, dominar essas técnicas deixa de ser um diferencial estético e passa a ser um requisito obrigatório de sobrevivência operacional. Investir tempo na configuração correta das políticas de rede e na governança de admissão evita dores de cabeça futuras, garantindo que o Kubernetes continue sendo o motor veloz e seguro que sustenta a inovação tecnológica da organização.