O NetworkPolicy do Kubernetes é uma daquelas funcionalidades que parecem simples até serem aplicadas num cluster em plena produção. Em 2026, continua a ser um componente essencial para redes com privilégios mínimos, mas é fácil configurar de forma errada porque a aplicação depende do CNI, os seletores são conduzidos por labels e “o que pretendia” nem sempre coincide com “o que a API faz”. Este guia foca-se nos erros que realmente causam incidentes e nos padrões que as equipas usam repetidamente para segmentar tráfego sem partir o ambiente.
O caso mais comum de “não funciona” nem sequer é um problema de YAML: o NetworkPolicy é uma API, não é uma firewall por si só. O cluster tem de usar uma solução de rede que implemente a aplicação de NetworkPolicy; caso contrário, as políticas podem existir e mesmo assim não produzir qualquer efeito. Mesmo quando a aplicação está ativa, o comportamento pode variar entre CNIs em casos limite, registos e observabilidade, por isso “suportado” deve ser algo a confirmar, não a assumir.
Em seguida, seja rigoroso quanto à semântica de isolamento. Por defeito, os pods não estão isolados e aceitam tráfego de qualquer origem. Um pod passa a estar isolado para ingress e/ou egress apenas quando é selecionado por uma política que cobre essa direção (via policyTypes ou por comportamento implícito). A partir daí, as regras funcionam como listas de permissões: o tráfego só é permitido se pelo menos uma política aplicável o permitir, e tudo o resto é negado para a direção isolada.
Por fim, recorde a camada em que o Kubernetes NetworkPolicy atua. O NetworkPolicy clássico é sobretudo L3/L4: blocos de IP, namespaces, pods e portas. Se o requisito de segmentação for “permitir apenas este caminho HTTP” ou “apenas este nome DNS”, pode precisar de extensões específicas do CNI ou de APIs de políticas mais recentes, em vez de tentar forçar esses conceitos no NetworkPolicy básico.
Confiar numa política num cluster onde a aplicação não está ativa (ou não está ativa em todos os node pools) continua a ser um dos erros mais frequentes. O YAML parece correto, o CI passa, nada muda, e a equipa só descobre numa auditoria de segurança ou após um incidente. Inclua uma verificação explícita nos procedimentos: confirmar que CNI aplica as políticas e como validar a aplicação num namespace não produtivo.
Deixar policyTypes implícito e assumir que cobre ambas as direções cria falhas discretas. As equipas escrevem uma política de ingress e assumem que também limita chamadas de saída, e mais tarde percebem que o egress ficou completamente aberto. Torne a direção explícita em qualquer workload onde o acesso de saída seja relevante (o que, na prática, é a maioria).
Assumir que objetos Service são “alvos” de política é outro mal-entendido recorrente. O NetworkPolicy seleciona pods, não Services. Pode desenhar políticas que correspondam aos pods por trás de um Service, mas o nome do Service não é um seletor. Quando alguém “permite o Service”, muitas vezes esquece o conjunto de labels nos pods e a regra acaba por não corresponder a nada.
Um modelo de segmentação que resiste a mudanças reais na organização começa com limites que significam algo: namespaces para tenancy e ciclo de vida, labels para identidade e função da aplicação e uma lista curta de serviços partilhados (DNS, logging, métricas, ingress, gateways de service mesh) aos quais muitos workloads precisam de aceder. Se estes fundamentos forem inconsistentes, as NetworkPolicies tornam-se frágeis e as equipas acabam por as desativar ou por criar exceções demasiado amplas.
Um padrão prático é normalizar um contrato mínimo de labels em todos os workloads: app.kubernetes.io/name, app.kubernetes.io/part-of, app.kubernetes.io/component, além de uma label de ambiente ou tenant ao nível do namespace. Assim, os seletores tornam-se legíveis e previsíveis, reduzindo a depuração “porque é que isto não corresponde?” causada por labels improvisadas.
Serviços partilhados merecem tratamento especial. O DNS é a interrupção mais comum causada por rollout de políticas: uma equipa ativa egress default-deny e depois esquece-se de permitir egress para os pods de DNS (e, por vezes, para o endereço de DNS local ao nó, se existir). Trate DNS, sincronização de tempo (quando aplicável) e proxies obrigatórios de egress como dependências de base e modele-os explicitamente no padrão inicial.
Padrão 1: “Baseline por namespace + refinamento por aplicação”. Comece com um default-deny ao nível do namespace para ingress (e para egress quando fizer sentido) e depois adicione regras de permissão pequenas e específicas por aplicação. O objetivo não é escrever uma matriz perfeita no primeiro dia, mas criar um perímetro controlado e iterar com segurança à medida que descobre fluxos legítimos.
Padrão 2: “Lista de permissões para serviços partilhados”. Mantenha um conjunto reduzido de políticas (frequentemente geridas pela equipa de plataforma/SRE) que permite a todos os namespaces de aplicação acederem a serviços essenciais: DNS, backends do controlador de ingress (quando necessário), agentes de observabilidade e endpoints de admission/webhook usados pelas operações do cluster. Mantenha esta lista curta e revista, porque cada exceção “partilhada” pode tornar-se um atalho para movimento lateral se crescer demasiado.
Padrão 3: “Camadas por labels dentro do mesmo namespace”. Para equipas que preferem menos namespaces, use camadas como role=frontend, role=backend, role=db e defina fluxos permitidos: frontend → backend, backend → db, e negar tudo o resto. Isto corresponde à forma como as pessoas pensam a arquitetura e reduz a proliferação de políticas face a seletores avulsos.

A estratégia mais segura em 2026 continua a ser a aplicação progressiva. Comece por documentar os fluxos pretendidos (até uma tabela simples serve), introduza o default-deny num âmbito controlado e adicione regras de permissão de forma iterativa enquanto monitoriza. A abordagem “big bang” — aplicar default-deny em todo o lado e corrigir quebras em tempo real — quase sempre gera um incidente ruidoso e um rollback.
Os testes devem incluir casos positivos e negativos. Não basta confirmar “o serviço A consegue chamar o serviço B”; também quer um teste de regressão que comprove que “o serviço C não consegue chamar o serviço B”. Sem testes negativos, as políticas tendem a derivar para um estado permissivo com o tempo, porque ninguém repara nos caminhos extra que foram abertos.
O troubleshooting precisa de um método consistente. Comece por confirmar se o pod é selecionado por alguma política (e para que direção), depois liste todas as políticas no namespace que possam corresponder e só então analise as regras. Se o seu CNI fornecer visibilidade de fluxos ou logs de vereditos de política, use-os cedo: reduzem a depuração de horas para minutos ao mostrar que regra permitiu ou negou uma ligação.
O egress é onde se concentra a maior parte da dor no mundo real: APIs externas, repositórios de pacotes, fornecedores de identidade e webhooks transformam rapidamente o “negar por defeito” numa longa lista de permissões. Duas medidas ajudam: encaminhar tráfego de saída por um caminho controlado (proxy ou gateway) e permitir egress sobretudo para esse caminho, em vez de dezenas de destinos externos. Isto mantém as políticas menores e torna auditorias mais simples.
Seletores de namespace falham na prática quando os namespaces não são etiquetados de forma consistente. As pessoas escrevem regras baseadas em namespaceSelector e depois descobrem que namespaces de sistema ou legados não têm labels, pelo que a regra não consegue corresponder. A correção é tanto organizacional como técnica: defina um padrão mínimo de labels para namespaces e imponha-o (verificações policy-as-code funcionam bem aqui).
Por fim, acompanhe o ecossistema em torno de NetworkPolicy. O grupo de trabalho upstream de Network Policy API continua a evoluir recursos de política com âmbito global e foco administrativo como CRDs (com mudanças de nomenclatura e versionamento ao longo do tempo). Se precisar de guardrails globais ou políticas base transversais a namespaces, avalie essas APIs de nível administrativo no seu ambiente, em vez de tentar aproximar “política de cluster” usando apenas objetos NetworkPolicy por namespace.