Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

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 HTTPRoute para 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 HTTPRoute no próprio namespace;
  • o tráfego de https://whoami.localhost/ vai para o Service whoami.

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 Secret TLS;
  • 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:

  1. Instalar o Traefik com Helm.
  2. Deixar o chart criar o gateway principal.
  3. Publicar cada aplicação com um HTTPRoute.
  4. Reaproveitar o mesmo gateway para todos os serviços.
  5. Adicionar middlewares e TLS conforme a necessidade.

Esse modelo reduz a complexidade inicial e deixa a migração a partir de Ingress mais natural.

Referências