Configuración de Ingress en Kubernetes: Guía Completa de Producción
Kubernetes Ingress proporciona enrutamiento HTTP y HTTPS a los servicios dentro de un clúster, ofreciendo balanceo de carga, terminación SSL/TLS y hosting virtual basado en nombres. Esta guía completa cubre controladores de Ingress, configuración, configuración de TLS y mejores prácticas de producción.
Tabla de Contenidos
- Introducción
- Requisitos Previos
- Conceptos de Ingress
- Instalación de Controladores de Ingress
- Configuración Básica de Ingress
- Enrutamiento Basado en Rutas
- Enrutamiento Basado en Host
- Configuración TLS/SSL
- Configuraciones Avanzadas
- Mejores Prácticas de Producción
- Resolución de Problemas
- Conclusión
Introducción
Ingress expone rutas HTTP y HTTPS desde fuera del clúster a servicios dentro del clúster. A diferencia de los servicios LoadBalancer que requieren un balanceador de carga del proveedor de nube para cada servicio, un único Ingress puede enrutar tráfico a múltiples servicios basándose en reglas.
¿Por Qué Usar Ingress?
- Rentable: Un solo balanceador de carga para múltiples servicios
- Enrutamiento Flexible: Enrutamiento basado en rutas y hosts
- Terminación SSL/TLS: Gestión centralizada de certificados
- Balanceo de Carga: Distribuir tráfico entre pods
- Características Avanzadas: Limitación de tasa, autenticación, reescrituras
Ingress vs LoadBalancer vs NodePort
| Característica | Ingress | LoadBalancer | NodePort |
|---|---|---|---|
| Costo | Bajo | Alto (por servicio) | Gratis |
| Enrutamiento L7 | Sí | No | No |
| Terminación SSL | Sí | No | No |
| IP Externa | 1 para muchos servicios | 1 por servicio | IPs de Nodo |
Requisitos Previos
- Clúster de Kubernetes (1.19+)
- kubectl configurado
- Nombre de dominio (para producción)
- Comprensión básica de Servicios y DNS
Verificar clúster:
kubectl version --client
kubectl cluster-info
kubectl get nodes
Conceptos de Ingress
Arquitectura de Ingress
Internet
↓
Controlador de Ingress (Servicio LoadBalancer)
↓
Recurso Ingress (reglas de enrutamiento)
↓
Servicios Backend
↓
Pods
Componentes de Ingress
- Controlador de Ingress: Implementación (NGINX, Traefik, HAProxy, etc.)
- Recurso Ingress: Reglas de enrutamiento definidas en YAML
- Servicios Backend: Servicios destino
- Secrets TLS: Certificados SSL/TLS
Instalación de Controladores de Ingress
Controlador de Ingress NGINX (Más Popular)
# Instalar vía Helm
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update
helm install ingress-nginx ingress-nginx/ingress-nginx \
--namespace ingress-nginx \
--create-namespace
# O vía manifiesto
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/cloud/deploy.yaml
# Verificar instalación
kubectl get pods -n ingress-nginx
kubectl get svc -n ingress-nginx
Controlador de Ingress Traefik
# Instalar vía Helm
helm repo add traefik https://traefik.github.io/charts
helm repo update
helm install traefik traefik/traefik \
--namespace traefik \
--create-namespace
# Verificar
kubectl get pods -n traefik
Controlador de Ingress HAProxy
# Instalar vía Helm
helm repo add haproxytech https://haproxytech.github.io/helm-charts
helm repo update
helm install haproxy haproxytech/kubernetes-ingress \
--namespace haproxy-ingress \
--create-namespace
# Verificar
kubectl get pods -n haproxy-ingress
Obtener IP Externa
# Obtener IP del LoadBalancer
kubectl get svc -n ingress-nginx ingress-nginx-controller
# Esperar por EXTERNAL-IP
NAME TYPE EXTERNAL-IP
ingress-nginx-controller LoadBalancer 34.123.45.67
Configuración Básica de Ingress
Ejemplo Simple de Ingress
# ingress-basic.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: simple-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx
rules:
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-service
port:
number: 80
# Crear servicio backend primero
kubectl create deployment web --image=nginx:alpine
kubectl expose deployment web --port=80 --target-port=80
# Aplicar ingress
kubectl apply -f ingress-basic.yaml
# Verificar
kubectl get ingress
kubectl describe ingress simple-ingress
Ejemplo Completo con Servicio
# web-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
spec:
replicas: 3
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: nginx
image: nginx:alpine
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: web-service
spec:
selector:
app: web
ports:
- port: 80
targetPort: 80
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: web-ingress
spec:
ingressClassName: nginx
rules:
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-service
port:
number: 80
# Aplicar todos los recursos
kubectl apply -f web-deployment.yaml
# Probar
curl http://<EXTERNAL-IP>/
Enrutamiento Basado en Rutas
Enrutar tráfico basado en la ruta URL a diferentes servicios.
Ingress Basado en Rutas
# ingress-paths.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: path-based-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
ingressClassName: nginx
rules:
- http:
paths:
- path: /api(/|$)(.*)
pathType: ImplementationSpecific
backend:
service:
name: api-service
port:
number: 8080
- path: /web(/|$)(.*)
pathType: ImplementationSpecific
backend:
service:
name: web-service
port:
number: 80
- path: /
pathType: Prefix
backend:
service:
name: default-service
port:
number: 80
Opciones de PathType
- Exact: Coincidencia exacta de URL
- Prefix: Coincidencia basada en prefijo de ruta URL
- ImplementationSpecific: Comportamiento dependiente del controlador
# pathtype-examples.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: pathtype-example
spec:
ingressClassName: nginx
rules:
- http:
paths:
# Coincidencia exacta solo /api
- path: /api
pathType: Exact
backend:
service:
name: api-service
port:
number: 8080
# Coincide con /app, /app/, /app/test
- path: /app
pathType: Prefix
backend:
service:
name: app-service
port:
number: 3000
Enrutamiento Basado en Host
Enrutar tráfico basado en hostname a diferentes servicios.
Ingress de Un Solo Host
# ingress-host.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: host-ingress
spec:
ingressClassName: nginx
rules:
- host: example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-service
port:
number: 80
Ingress de Múltiples Hosts
# ingress-multi-host.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: multi-host-ingress
spec:
ingressClassName: nginx
rules:
# Sitio web principal
- host: example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-service
port:
number: 80
# Subdominio API
- host: api.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: api-service
port:
number: 8080
# Subdominio Admin
- host: admin.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: admin-service
port:
number: 3000
Hosts Comodín
# ingress-wildcard.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: wildcard-ingress
spec:
ingressClassName: nginx
rules:
- host: "*.example.com"
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: catch-all-service
port:
number: 80
Configuración TLS/SSL
Crear Secret TLS
# Generar certificado autofirmado (solo para pruebas)
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout tls.key -out tls.crt \
-subj "/CN=example.com/O=example.com"
# Crear secret desde archivos
kubectl create secret tls example-tls \
--cert=tls.crt \
--key=tls.key
# O desde cert-manager (Let's Encrypt)
# Se cubrirá a continuación
Ingress con TLS
# ingress-tls.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: tls-ingress
spec:
ingressClassName: nginx
tls:
- hosts:
- example.com
- www.example.com
secretName: example-tls
rules:
- host: example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-service
port:
number: 80
- host: www.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-service
port:
number: 80
# Aplicar
kubectl apply -f ingress-tls.yaml
# Probar HTTPS
curl https://example.com
TLS Automático con cert-manager
# Instalar cert-manager
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.13.0/cert-manager.yaml
# Crear ClusterIssuer para Let's Encrypt
cat <<EOF | kubectl apply -f -
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: [email protected]
privateKeySecretRef:
name: letsencrypt-prod
solvers:
- http01:
ingress:
class: nginx
EOF
# ingress-certmanager.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: certmanager-ingress
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
ingressClassName: nginx
tls:
- hosts:
- example.com
secretName: example-tls-auto
rules:
- host: example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-service
port:
number: 80
Configuraciones Avanzadas
Anotaciones Personalizadas
# ingress-annotations.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: advanced-ingress
annotations:
# Reescritura de URL
nginx.ingress.kubernetes.io/rewrite-target: /$2
# Redirección SSL
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
# Limitación de tasa
nginx.ingress.kubernetes.io/limit-rps: "10"
# CORS
nginx.ingress.kubernetes.io/enable-cors: "true"
nginx.ingress.kubernetes.io/cors-allow-methods: "GET, POST, OPTIONS"
# Timeouts personalizados
nginx.ingress.kubernetes.io/proxy-connect-timeout: "30"
nginx.ingress.kubernetes.io/proxy-send-timeout: "30"
nginx.ingress.kubernetes.io/proxy-read-timeout: "30"
# Tamaño del cuerpo del cliente
nginx.ingress.kubernetes.io/proxy-body-size: "10m"
spec:
ingressClassName: nginx
rules:
- host: example.com
http:
paths:
- path: /api(/|$)(.*)
pathType: ImplementationSpecific
backend:
service:
name: api-service
port:
number: 8080
Autenticación Básica
# Crear archivo htpasswd
htpasswd -c auth username
# Crear secret
kubectl create secret generic basic-auth --from-file=auth
# ingress-basic-auth.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: auth-ingress
annotations:
nginx.ingress.kubernetes.io/auth-type: basic
nginx.ingress.kubernetes.io/auth-secret: basic-auth
nginx.ingress.kubernetes.io/auth-realm: 'Authentication Required'
spec:
ingressClassName: nginx
rules:
- host: admin.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: admin-service
port:
number: 80
Limitación de Tasa
# ingress-rate-limit.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: rate-limited-ingress
annotations:
nginx.ingress.kubernetes.io/limit-rps: "10"
nginx.ingress.kubernetes.io/limit-connections: "5"
nginx.ingress.kubernetes.io/limit-rpm: "100"
spec:
ingressClassName: nginx
rules:
- host: api.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: api-service
port:
number: 8080
Redirecciones de URL
# ingress-redirect.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: redirect-ingress
annotations:
# Redirigir www a no-www
nginx.ingress.kubernetes.io/permanent-redirect: "https://example.com$request_uri"
spec:
ingressClassName: nginx
rules:
- host: www.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-service
port:
number: 80
Mejores Prácticas de Producción
Alta Disponibilidad
# ha-ingress-controller.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: ingress-nginx-controller
namespace: ingress-nginx
spec:
replicas: 3 # Múltiples réplicas
selector:
matchLabels:
app.kubernetes.io/name: ingress-nginx
template:
metadata:
labels:
app.kubernetes.io/name: ingress-nginx
spec:
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: app.kubernetes.io/name
operator: In
values:
- ingress-nginx
topologyKey: kubernetes.io/hostname
Límites de Recursos
spec:
template:
spec:
containers:
- name: controller
resources:
requests:
cpu: 100m
memory: 90Mi
limits:
cpu: 1000m
memory: 1Gi
Monitoreo y Logging
metadata:
annotations:
# Métricas de Prometheus
prometheus.io/scrape: "true"
prometheus.io/port: "10254"
# Logging personalizado
nginx.ingress.kubernetes.io/configuration-snippet: |
access_log /var/log/nginx/custom-access.log custom;
Cabeceras de Seguridad
metadata:
annotations:
nginx.ingress.kubernetes.io/configuration-snippet: |
more_set_headers "X-Frame-Options: DENY";
more_set_headers "X-Content-Type-Options: nosniff";
more_set_headers "X-XSS-Protection: 1; mode=block";
more_set_headers "Strict-Transport-Security: max-age=31536000; includeSubDomains";
Resolución de Problemas
Problemas Comunes
# Verificar estado de Ingress
kubectl get ingress
kubectl describe ingress <ingress-name>
# Verificar logs del Controlador de Ingress
kubectl logs -n ingress-nginx -l app.kubernetes.io/name=ingress-nginx
# Verificar endpoints backend
kubectl get endpoints <service-name>
# Probar desde dentro del clúster
kubectl run curl --image=curlimages/curl --rm -it -- curl http://service-name
# Verificar secret TLS
kubectl get secret <secret-name> -o yaml
kubectl describe secret <secret-name>
Modo de Depuración
# Habilitar logging de depuración
kubectl edit deployment -n ingress-nginx ingress-nginx-controller
# Agregar a args:
- --v=3 # Aumentar verbosidad
Problemas de Certificados
# Verificar cert-manager
kubectl get certificates
kubectl get certificaterequests
kubectl describe certificate <cert-name>
# Forzar renovación
kubectl delete secret <tls-secret>
Conclusión
Ingress proporciona capacidades poderosas de enrutamiento HTTP/HTTPS para clústeres de Kubernetes, habilitando gestión de tráfico rentable y flexible con características avanzadas como terminación TLS y autenticación.
Puntos Clave
- Controladores de Ingress: Elegir el controlador apropiado (NGINX, Traefik, etc.)
- Enrutamiento: Flexibilidad de enrutamiento basado en rutas y hosts
- TLS/SSL: Gestión centralizada de certificados
- Anotaciones: Características avanzadas específicas del controlador
- Producción: HA, monitoreo, cabeceras de seguridad
Referencia Rápida
# Instalación
helm install ingress-nginx ingress-nginx/ingress-nginx
# Ingress básico
kubectl create ingress simple --rule="example.com/*=web-service:80"
# Con TLS
kubectl create ingress tls-ingress \
--rule="example.com/*=web-service:80,tls=example-tls"
# Operaciones
kubectl get ingress
kubectl describe ingress <name>
kubectl edit ingress <name>
kubectl delete ingress <name>
Próximos Pasos
- Desplegar: Configurar controlador de Ingress en tu clúster
- Configurar: Crear reglas de Ingress para tus servicios
- Asegurar: Implementar TLS con cert-manager
- Monitorear: Configurar métricas y alertas
- Optimizar: Ajustar anotaciones y caché
- Escalar: Configurar HA para producción
- Avanzado: Implementar autenticación, limitación de tasa, WAF
Ingress es esencial para despliegues de Kubernetes en producción. Domínalo para construir aplicaciones robustas y escalables.


