Gateway API x Ingress: o que muda na segurança
Se você mantém Ingress controllers em produção há alguns anos, já sabe a dor: anotações específicas de cada implementação (nginx, Traefik, ALB) que não são portáveis, comportamento de roteamento que varia entre controllers e pouca separação de responsabilidades entre quem cuida da infraestrutura e quem cuida da aplicação. A Gateway API do Kubernetes existe para resolver isso — e traz junto um modelo de segurança por padrão diferente do que o Ingress oferece.
Este post explica o que muda estruturalmente e, principalmente, o que muda no comportamento padrão de exposição de tráfego entre namespaces — o ponto mais relevante do ponto de vista de segurança.
Premissas e limitações desta análise
Antes de entrar no conteúdo, uma declaração de escopo importante: a pesquisa que baseia este texto usou como fonte exclusiva a documentação oficial do Kubernetes sobre Gateway API. Essa fonte não traz uma comparação estruturada com o Ingress, nem detalhes sobre a spec do Ingress (anotações, comportamento de controllers, limitações). A única menção a Ingress no material original é lateral, citando anotações customizadas como contraste histórico para roteamento avançado.
Por isso, os pontos sobre a Gateway API neste post são tratados como fato documentado, com link para a fonte. Os pontos sobre o Ingress "clássico" refletem conhecimento geral e amplamente estabelecido do ecossistema Kubernetes (é o modelo de API estável desde a v1.19), não citações diretas de uma fonte fornecida — trate-os como contexto, não como afirmação com referência primária anexada aqui. Também não foram testados neste ambiente nenhum dos manifestos YAML reproduzidos abaixo; eles vêm da documentação oficial e servem para ilustrar estrutura, não como cópia pronta para produção sem revisão.
O problema estrutural que a Gateway API ataca
O Ingress define um único kind (Ingress) que precisa cobrir provisionamento de load balancer, regras de roteamento HTTP e configuração específica de cada controller — tudo isso na mesma spec, ou espalhado em anotações não padronizadas. Isso gera dois efeitos conhecidos: portabilidade baixa entre implementações e nenhuma separação de papéis entre quem opera a borda da rede e quem só quer expor uma aplicação.
A Gateway API resolve isso dividindo responsabilidades em quatro kinds estáveis, descritos assim pela documentação:
- GatewayClass: define um conjunto de gateways com configuração comum, gerenciado por um controller que implementa a classe.
- Gateway: define uma instância de infraestrutura de tratamento de tráfego (por exemplo, um load balancer de nuvem).
- HTTPRoute: mapeia regras HTTP de um listener do Gateway para endpoints de backend, geralmente um Service.
- GRPCRoute: equivalente ao HTTPRoute, mas para tráfego gRPC.
O design é explicitamente role-oriented: a documentação descreve três papéis organizacionais — Infrastructure Provider (gerencia a infra que serve múltiplos clusters/tenants), Cluster Operator (políticas, acesso de rede, permissões) e Application Developer (configuração de nível de aplicação). Cada kind é pensado para ser gerenciado pelo papel correspondente, com RBAC do Kubernetes aplicado normalmente sobre objetos diferentes — algo que o Ingress, como recurso único, não separa da mesma forma.
O ponto central para segurança: isolamento por namespace é o padrão
Este é o fato mais relevante do ponto de vista de exposição de tráfego: por padrão, um Gateway só aceita Routes do mesmo namespace em que ele está definido. Rotas cross-namespace exigem configuração explícita via allowedRoutes.
Isso muda o modelo mental de segurança: no Ingress, qualquer objeto Ingress no cluster que aponte para um IngressClass compartilhado normalmente entra na configuração do controller, sem uma barreira de namespace embutida na spec — o isolamento, quando existe, costuma vir de política externa (RBAC sobre o objeto Ingress, admission webhook, ou convenção de time). Na Gateway API, o isolamento por namespace já vem como comportamento padrão da API, não como algo que você precisa impor por fora.
Veja o exemplo de Gateway da própria documentação:
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: example-gateway
namespace: example-namespace
spec:
gatewayClassName: example-class
listeners:
- name: http
protocol: HTTP
port: 80
hostname: "www.example.com"
allowedRoutes:
namespaces:
from: Same
O valor Same em allowedRoutes.namespaces.from é o comportamento padrão demonstrado na documentação: só HTTPRoutes do namespace example-namespace podem se anexar a este listener. O campo aceita outros valores que ampliam ou restringem esse escopo, mas a fonte consultada aqui não detalha essa enumeração — antes de configurar algo diferente de Same em produção, vale checar a referência oficial do Gateway e a página de reference do kind.
O HTTPRoute correspondente referencia o Gateway explicitamente via parentRefs:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: example-httproute
spec:
parentRefs:
- name: example-gateway
hostnames:
- "www.example.com"
rules:
- matches:
- path:
type: PathPrefix
value: /login
backendRefs:
- name: example-svc
port: 8080
A documentação chama isso de modelo de confiança bidirecional: o Gateway decide quais rotas aceita (via allowedRoutes), e a rota decide a qual Gateway quer se anexar (via parentRefs). Nenhum dos dois lados sozinho consegue forçar a associação. Do ponto de vista de DevSecOps, isso é relevante porque reduz um vetor comum de erro: um time de aplicação criar uma rota que, sem querer, herda exposição pública de um Gateway compartilhado gerenciado por outro time.
Diferenças práticas: o que muda no dia a dia
Com base no que a fonte confirma, três diferenças práticas se destacam:
- Portabilidade da configuração de roteamento. Matching por header e weighting de tráfego (canary, blue/green) fazem parte da spec padrão do HTTPRoute. No Ingress, esse tipo de caso só era viável via anotações específicas de cada controller — a própria documentação da Gateway API cita isso como motivação histórica.
- Separação de RBAC por kind. Como GatewayClass, Gateway e HTTPRoute são objetos distintos, dá para conceder permissão de criar HTTPRoute a um time de aplicação sem dar acesso a Gateway ou GatewayClass — sem depender de convenção informal.
- Extensibilidade via custom resources em camadas. A documentação descreve a Gateway API como "extensible" justamente por permitir vincular custom resources em pontos específicos da estrutura, em vez de sobrecarregar anotações de um único objeto.
O que a fonte não cobre, e que fica como lacuna explícita: comportamento de TLS/HTTPS nos listeners (há apenas a menção ao "Gateway API TLS Guide", sem conteúdo extraído), mTLS, políticas de rede complementares (NetworkPolicy), e detalhes de RBAC granular aplicado na prática a cada kind. Se sua decisão de migração depende desses pontos — e para a maioria dos ambientes depende —, trate-os como pesquisa adicional necessária antes de qualquer corte de produção.
Recomendação condicionada
Se seu cluster já roda com múltiplos times compartilhando um Ingress controller e você resolve isolamento de exposição hoje via convenção, RBAC externo ou admission webhook customizado, a Gateway API tende a formalizar esse isolamento em vez de depender de disciplina de time. Isso reduz superfície de erro humano em ambientes multi-tenant.
Se seu cenário é um cluster único, poucos times, e o Ingress controller atual já resolve os casos de roteamento que você precisa sem acúmulo de anotações mágicas, a migração pode esperar — trocar um modelo estável por outro tem custo de aprendizado e de reescrita de manifests que precisa ser justificado por um ganho real de segurança ou expressividade, não por tendência.
Vale reforçar: como a Gateway API tem controllers específicos por implementação (assim como o Ingress tinha), o comportamento exato de TLS, health check e integração com load balancer de nuvem ainda depende de qual controller você escolhe. A portabilidade é da spec, não necessariamente de todo comportamento operacional.
Próximo passo
Antes de migrar qualquer ambiente de Ingress para Gateway API, valide três coisas no seu controller específico: suporte a GRPCRoute (se você usa gRPC), o comportamento real de allowedRoutes em cenário multi-tenant, e a cobertura de TLS pelo guia oficial da Gateway API — nenhuma dessas três é opcional para um rollout com segurança sob controle.