Gateway API
Gateway API é a evolução do modelo de publicação de serviços HTTP/TCP no Kubernetes.
Ela foi criada para resolver limitações do Ingress, separando melhor as responsabilidades
entre quem opera a entrada do cluster e quem publica aplicações.
Enquanto o Ingress concentrava quase tudo em um único recurso, a Gateway API
divide o problema em objetos com papéis mais claros:
- GatewayClass: define qual controlador vai implementar o gateway.
- Gateway: representa a entrada compartilhada do cluster.
- HTTPRoute: define como cada aplicação será roteada para os serviços.
Na prática, a principal vantagem é esta: você deixa de repetir configuração
de entrada em cada aplicação e passa a ter um Gateway compartilhado com várias
rotas independentes.
Por que preferir Gateway API em vez de Ingress
- Modelo mais moderno: foi desenhada para substituir os casos mais comuns
de
Ingress. - Separação de responsabilidades: infraestrutura e aplicações ficam mais desacopladas.
- Mais extensível: middlewares, TLS e filtros ficam mais organizados.
- Melhor migração incremental: você pode manter um único gateway e migrar serviço por serviço.
Traefik como provider de Gateway API
O Traefik é uma boa opção de provider para Gateway API porque tem instalação simples,
integração madura com Kubernetes e suporte direto a Gateway e HTTPRoute.
Para ambientes simples, ele funciona muito bem com uma abordagem direta:
- instalar o chart via Helm;
- deixar o chart criar e publicar o gateway;
- usar
HTTPRoutepara conectar cada serviço a esse gateway compartilhado.
Esse modelo costuma ser suficiente para laboratórios, ambientes internos e muitos cenários reais de produção sem precisar começar com manifests extras.
Instalação do Traefik com Gateway API
Certificado TLS
Em um listener HTTPS, o Traefik precisa de um certificado TLS para conseguir terminar a conexão segura. Sem isso, ele não consegue responder em HTTPS de forma correta para o domínio publicado.
No exemplo abaixo usamos um certificado self-signed apenas para laboratorio e
testes locais. Isso funciona bem para ambientes como *.localhost,
mas não deve ser a abordagem usada em produção.
Em ambiente produtivo, o normal é importar um certificado real emitido por uma autoridade
certificadora ou gerenciado pelo time de infraestrutura.
Se você já tiver os arquivos tls.crt e tls.key,
basta criar o secret no namespace do Traefik:
kubectl create secret tls local-selfsigned-tls \
--cert=tls.crt --key=tls.key \
--namespace traefik
Se quiser usar um nome mais apropriado para produção, por exemplo app-tls,
o comando fica assim:
kubectl create secret tls app-tls \
--cert=tls.crt --key=tls.key \
--namespace traefik
Nesse caso, lembre de ajustar o certificateRefs.name no values.yaml para apontar
para o nome correto do secret.
Gerando um certificado self-signed
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout tls.key -out tls.crt \
-subj "/CN=*.localhost"
Criando o secret TLS no namespace do Traefik
kubectl create namespace traefik
kubectl create secret tls local-selfsigned-tls \
--cert=tls.crt --key=tls.key \
--namespace traefik
Adicionando o repositório do chart
helm repo add traefik https://traefik.github.io/charts
helm repo update
Instalando o Traefik
helm upgrade --install traefik traefik/traefik \
--namespace traefik \
--create-namespace \
--values values.yaml
Exemplo de values.yaml
# Ajuste do Service para usar NodePort com externalTrafficPolicy Local
service:
type: NodePort
spec:
externalTrafficPolicy: Local
# Configura as portas de rede e os EntryPoints.
# EntryPoints sao os listeners de rede para trafego de entrada.
ports:
# Define o entry point HTTP chamado `web`.
web:
port: 8000
nodePort: 30000
# Redireciona todo o trafego desse entry point para `websecure`.
http:
redirections:
entryPoint:
to: websecure
scheme: https
permanent: true
# Define o entry point HTTPS chamado `websecure`.
websecure:
port: 8443
nodePort: 30001
# Vamos rotear usando Gateway API em vez de Ingress.
ingressClass:
enabled: false
# Providers dizem ao Traefik onde encontrar a configuracao de roteamento.
providers:
kubernetesIngress:
enabled: false
kubernetesGateway:
enabled: true
# Listeners do Gateway.
gateway:
listeners:
web:
# Listener HTTP que corresponde ao entryPoint `web`.
port: 8000
protocol: HTTP
namespacePolicy:
from: All
websecure:
port: 8443
protocol: HTTPS
namespacePolicy:
from: All
mode: Terminate
certificateRefs:
- kind: Secret
name: local-selfsigned-tls
group: ""
# Habilita observabilidade.
logs:
general:
level: INFO
# Habilita access logs na saida padrao do Traefik.
access:
enabled: true
# Habilita metricas Prometheus.
metrics:
prometheus:
enabled: true
# Cabecalhos encaminhados confiaveis para quando o trafego vier do Cloudflare.
additionalArguments:
- "--entrypoints.web.forwardedheaders.trustedips=173.245.48.0/20,103.21.244.0/22,103.22.200.0/22,103.31.4.0/22,141.101.64.0/18,108.162.192.0/18,190.93.240.0/20,188.114.96.0/20,197.234.240.0/22,198.41.128.0/17,162.158.0.0/15,104.16.0.0/13,104.24.0.0/14,172.64.0.0/13,131.0.72.0/22"
- "--entrypoints.websecure.forwardedheaders.trustedips=173.245.48.0/20,103.21.244.0/22,103.22.200.0/22,103.31.4.0/22,141.101.64.0/18,108.162.192.0/18,190.93.240.0/20,188.114.96.0/20,197.234.240.0/22,198.41.128.0/17,162.158.0.0/15,104.16.0.0/13,104.24.0.0/14,172.64.0.0/13,131.0.72.0/22"
Com essa configuração, Traefik fica pronto para usar Gateway API e já expõe listeners HTTP e HTTPS no gateway principal.
Um único Gateway para vários serviços
Em vez de criar um Gateway para cada aplicação, o mais comum em cenários
simples é ter um único gateway compartilhado e conectar vários HTTPRoute nele.
Esse é justamente o modelo mais natural de migração a partir de Ingress:
você mantém uma entrada compartilhada e move as regras de roteamento para HTTPRoute.
Descobrindo o nome do Gateway criado pelo chart
Depois da instalação, veja os gateways disponíveis:
kubectl get gateway -A
Use o nome retornado por esse comando nos exemplos abaixo.
Neste artigo vamos assumir o nome traefik-gateway no namespace traefik.
Expondo um serviço com HTTPRoute
Suponha um Service chamado whoami na porta 80, no namespace default.
O HTTPRoute abaixo publica esse serviço usando o gateway compartilhado do Traefik:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: whoami
namespace: default
spec:
parentRefs:
- name: traefik-gateway
namespace: traefik
hostnames:
- whoami.localhost
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: whoami
port: 80
Aplicando:
kubectl apply -f httproute-whoami.yaml
Neste exemplo:
- o gateway continua centralizado no namespace
traefik; - a aplicação publica apenas o
HTTPRouteno próprio namespace; - o tráfego de
https://whoami.localhost/vai para oServicewhoami.
Expondo múltiplos serviços no mesmo Gateway
Aqui está o ponto mais importante da migração: o mesmo gateway pode atender várias aplicações diferentes sem precisar duplicar infraestrutura.
Exemplo com dois serviços
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: app1
namespace: default
spec:
parentRefs:
- name: traefik-gateway
namespace: traefik
hostnames:
- app1.localhost
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: app1
port: 80
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: app2
namespace: default
spec:
parentRefs:
- name: traefik-gateway
namespace: traefik
hostnames:
- app2.localhost
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: app2
port: 80
Nesse modelo, cada serviço só precisa declarar sua própria rota. O gateway continua único, compartilhado e muito mais fácil de operar.
Migração de Ingress para Gateway API
Uma migração comum é sair de vários recursos Ingress e manter apenas um
gateway central.
Antes: um Ingress por aplicação
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: app1
spec:
ingressClassName: nginx
rules:
- host: app1.exemplo.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: app1
port:
number: 80
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: app2
spec:
ingressClassName: traefik
rules:
- host: app2.exemplo.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: app2
port:
number: 80
Depois: um Gateway compartilhado e várias rotas
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: app1
spec:
parentRefs:
- name: traefik-gateway
namespace: traefik
hostnames:
- app1.exemplo.com
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: app1
port: 80
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: app2
spec:
parentRefs:
- name: traefik-gateway
namespace: traefik
hostnames:
- app2.exemplo.com
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: app2
port: 80
A principal mudança conceitual é esta:
- o gateway deixa de ser repetido por aplicação;
- cada serviço passa a publicar só a sua rota;
- a entrada HTTPS/HTTP continua centralizada no Traefik.
Middlewares com Traefik
O Traefik permite usar middlewares próprios junto com HTTPRoute.
Isso é útil para reaproveitar comportamentos como CORS, autenticação básica,
redirects e outras políticas de entrada.
Exemplo de CORS
Primeiro, crie um middleware:
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: cors
namespace: default
spec:
headers:
accessControlAllowMethods:
- GET
- POST
- OPTIONS
accessControlAllowOriginList:
- https://app.exemplo.com
accessControlAllowHeaders:
- Authorization
- Content-Type
accessControlMaxAge: 100
addVaryHeader: true
Agora associe esse middleware ao HTTPRoute:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: app1
namespace: default
spec:
parentRefs:
- name: traefik-gateway
namespace: traefik
hostnames:
- api.exemplo.com
rules:
- matches:
- path:
type: PathPrefix
value: /
filters:
- type: ExtensionRef
extensionRef:
group: traefik.io
kind: Middleware
name: cors
backendRefs:
- name: app1
port: 80
Exemplo de Basic Auth
Crie o secret com o conteúdo em formato compatível com htpasswd:
htpasswd -nb admin senha-forte
Exemplo de secret:
apiVersion: v1
kind: Secret
metadata:
name: authsecret
namespace: default
type: Opaque
stringData:
users: |
admin:$apr1$EXEMPLO$HASHGERADOAQUI
Depois crie o middleware:
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: basic-auth
namespace: default
spec:
basicAuth:
secret: authsecret
E use esse middleware na rota:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: painel
namespace: default
spec:
parentRefs:
- name: traefik-gateway
namespace: traefik
hostnames:
- painel.exemplo.com
rules:
- matches:
- path:
type: PathPrefix
value: /
filters:
- type: ExtensionRef
extensionRef:
group: traefik.io
kind: Middleware
name: basic-auth
backendRefs:
- name: painel
port: 80
Cert-manager
Em ambientes reais, o mais comum é substituir o certificado local por certificados emitidos pelo cert-manager.
A ideia geral continua a mesma:
- o gateway permanece compartilhado;
- o listener HTTPS referencia um
SecretTLS; - o cert-manager passa a manter esse secret atualizado.
Se o seu ambiente já está funcionando com certificado local, faz sentido começar assim e só introduzir cert-manager quando houver necessidade de automatizar emissão e renovação.
Resumo
Para cenários simples, a abordagem mais limpa costuma ser esta:
- Instalar o Traefik com Helm.
- Deixar o chart criar o gateway principal.
- Publicar cada aplicação com um
HTTPRoute. - Reaproveitar o mesmo gateway para todos os serviços.
- Adicionar middlewares e TLS conforme a necessidade.
Esse modelo reduz a complexidade inicial e deixa a migração a partir de
Ingress mais natural.