Ingress: roteando tráfego externo
1. Introdução ao Ingress no Kubernetes
Em um cluster Kubernetes, expor aplicações ao mundo externo é um desafio fundamental. Três abordagens principais existem:
- NodePort: expõe cada serviço em uma porta estática em todos os nós. Problemático para produção — portas limitadas (30000–32767), sem balanceamento de carga inteligente, e expõe IPs dos nós.
- LoadBalancer: cria um balanceador de carga externo (ex: ELB na AWS). Funcional, mas cada serviço consome um recurso de nuvem caro.
- Ingress: um único ponto de entrada que roteia tráfego para múltiplos serviços baseado em regras de hostname e path. Econômico, flexível e padronizado.
O Ingress é um recurso da API Kubernetes que gerencia acesso externo a serviços no cluster, tipicamente HTTP/HTTPS. Ele fornece balanceamento de carga, terminação SSL e roteamento baseado em regras.
Ciclo de vida de uma requisição externa:
1. Usuário acessa app.exemplo.com
2. DNS resolve para IP do Ingress Controller (ex: IP do LoadBalancer)
3. Ingress Controller recebe a requisição, analisa hostname e path
4. Encaminha para o Service correto no namespace apropriado
5. Service faz load balance para um Pod saudável
6. Pod processa e retorna a resposta
2. Componentes Fundamentais do Ingress
Dois componentes distintos trabalham juntos:
O recurso Ingress (objeto YAML de configuração):
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: meu-ingress
spec:
rules:
- host: app.exemplo.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: meu-servico
port:
number: 80
O Ingress Controller (implementação real que processa as regras):
- NGINX Ingress Controller: mais popular, mantido pela comunidade Kubernetes
- Traefik: moderno, suporte nativo a Let's Encrypt
- HAProxy Ingress: alta performance, rico em recursos
- AWS Load Balancer Controller: integração nativa com ALB/NLB
A diferença crucial: o Ingress é apenas a configuração declarativa; sem um Controller instalado no cluster, ele não faz nada.
3. Configuração Básica de um Ingress
Vamos criar um exemplo prático: dois serviços sendo roteados por um único IP.
Pré-requisito: instalar o NGINX Ingress Controller:
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.10.0/deploy/static/provider/cloud/deploy.yaml
Manifesto completo:
# Serviço de backend API
apiVersion: v1
kind: Service
metadata:
name: api-svc
spec:
selector:
app: api
ports:
- port: 80
targetPort: 3000
---
# Serviço de frontend web
apiVersion: v1
kind: Service
metadata:
name: web-svc
spec:
selector:
app: web
ports:
- port: 80
targetPort: 8080
---
# Ingress com roteamento baseado em path
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: multi-servico-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx
rules:
- host: meuapp.exemplo.com
http:
paths:
- path: /api
pathType: Prefix
backend:
service:
name: api-svc
port:
number: 80
- path: /
pathType: Prefix
backend:
service:
name: web-svc
port:
number: 80
Neste exemplo:
- Requisições para meuapp.exemplo.com/api vão para o serviço api-svc
- Requisições para meuapp.exemplo.com/ vão para o serviço web-svc
- A anotação rewrite-target: / remove o prefixo /api antes de encaminhar
Roteamento por hostname (virtual hosting):
spec:
rules:
- host: api.exemplo.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: api-svc
port:
number: 80
- host: web.exemplo.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-svc
port:
number: 80
4. Criptografia com TLS/HTTPS no Ingress
Para habilitar HTTPS, precisamos de um Secret TLS e referenciá-lo no Ingress.
Criando certificado auto-assinado (para testes):
# Gerar certificado
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout tls.key -out tls.crt \
-subj "/CN=meuapp.exemplo.com"
# Criar Secret no Kubernetes
kubectl create secret tls meuapp-tls \
--cert=tls.crt --key=tls.key
Ingress com TLS:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-com-tls
spec:
ingressClassName: nginx
tls:
- hosts:
- meuapp.exemplo.com
secretName: meuapp-tls
rules:
- host: meuapp.exemplo.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-svc
port:
number: 80
Redirecionamento HTTP para HTTPS automático (com NGINX):
metadata:
annotations:
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
Para produção, use cert-manager com Let's Encrypt:
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: admin@exemplo.com
privateKeySecretRef:
name: letsencrypt-prod-key
solvers:
- http01:
ingress:
class: nginx
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-producao
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
ingressClassName: nginx
tls:
- hosts:
- app.exemplo.com
secretName: app-tls-prod
rules:
- host: app.exemplo.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-svc
port:
number: 80
5. Técnicas Avançadas de Roteamento
Roteamento canário (traffic splitting):
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: app-canario
annotations:
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-weight: "10" # 10% do tráfego
spec:
ingressClassName: nginx
rules:
- host: app.exemplo.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: app-v2-svc
port:
number: 80
Anotações úteis:
metadata:
annotations:
nginx.ingress.kubernetes.io/proxy-body-size: "10m" # Limite de tamanho do corpo
nginx.ingress.kubernetes.io/proxy-read-timeout: "60" # Timeout de leitura
nginx.ingress.kubernetes.io/limit-rps: "100" # Rate limiting (req/segundo)
nginx.ingress.kubernetes.io/affinity: "cookie" # Sticky sessions
nginx.ingress.kubernetes.io/session-cookie-name: "route"
6. Operações e Troubleshooting
Comandos essenciais:
# Listar todos os Ingress
kubectl get ingress --all-namespaces
# Detalhes de um Ingress específico
kubectl describe ingress meu-ingress
# Logs do Ingress Controller
kubectl logs -n ingress-nginx deployment/ingress-nginx-controller
# Verificar endpoints dos serviços
kubectl get endpoints meu-servico
Problemas comuns e soluções:
- DNS não resolvido: verifique se o hostname no Ingress corresponde ao registro DNS apontando para o IP do LoadBalancer
- Portas conflitantes: NGINX Controller usa portas 80 e 443 por padrão; verifique se não há conflito com outros serviços
- Certificados expirados: monitore a data de expiração com kubectl get secret meu-tls -o jsonpath='{.data.tls\.crt}' | base64 -d | openssl x509 -noout -enddate
- Regra não funcionando: verifique pathType (Prefix, Exact, ImplementationSpecific) e a ordem das regras (a primeira correspondência vence)
7. Integração com o Ecossistema DevOps
GitOps com ArgoCD: o manifesto Ingress é versionado no Git e sincronizado automaticamente:
# Exemplo de aplicativo ArgoCD
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: meu-app
spec:
source:
repoURL: https://github.com/equipe/gitops-repo
path: k8s/ingress
destination:
server: https://kubernetes.default.svc
namespace: producao
syncPolicy:
automated:
prune: true
Monitoramento com Prometheus: o NGINX Ingress Controller expõe métricas em /metrics (porta 10254). Configure um ServiceMonitor:
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: ingress-nginx-monitor
spec:
endpoints:
- interval: 30s
port: metrics
selector:
matchLabels:
app.kubernetes.io/component: controller
Integração com HPA: o Ingress não escala diretamente, mas você pode escalar os Pods baseado em métricas do Ingress:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: web-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: web
minReplicas: 2
maxReplicas: 10
metrics:
- type: Pods
pods:
metric:
name: nginx_ingress_controller_requests
target:
type: AverageValue
averageValue: 1000
Namespaces e isolamento: use namespaces para ambientes (dev, staging, prod) e Ingress específicos para cada um:
kubectl create namespace staging
kubectl apply -f ingress-staging.yaml -n staging
O Ingress é a peça central para expor aplicações Kubernetes de forma profissional. Combinado com GitOps, monitoramento e autoscaling, ele se torna a fundação de uma plataforma DevOps robusta e escalável.
Referências
- Kubernetes Official Documentation: Ingress — Documentação oficial completa sobre o recurso Ingress, regras, paths e tipos de backend
- NGINX Ingress Controller User Guide — Guia oficial do NGINX Ingress Controller com anotações, exemplos e configurações avançadas
- cert-manager Documentation: Let's Encrypt — Tutorial passo a passo para configurar certificados TLS automáticos com Let's Encrypt e NGINX Ingress
- Traefik Ingress Controller Documentation — Documentação oficial do Traefik como Ingress Controller, incluindo middlewares e rate limiting
- ArgoCD: Managing Kubernetes Ingress with GitOps — Guia oficial sobre como gerenciar recursos Ingress em pipelines GitOps com ArgoCD
- Prometheus Monitoring for NGINX Ingress — Repositório oficial com exemplos de ServiceMonitor e dashboards para monitorar o Ingress Controller