Módulo 7: Eks Specifics For Production
6. El AWS Load Balancer Controller: el `Ingress` real de producción
Descripción
En el Módulo 4, lección 4, instalaste ingress-nginx de verdad dentro de andes-cargo-cluster, resolviste un hallazgo real (el manifiesto oficial dejó el Pod del controlador en el nodo equivocado), y en la lección 5 aplicaste un objeto Ingress que expuso andes-cargo-status-api por HTTP, sin port-forward, contra 127.0.0.1. Ese Ingress funcionó exactamente como el estándar de Kubernetes lo define. Esta lección te muestra qué pasa cuando ese mismo objeto, con la misma sintaxis exacta, corre en un clúster EKS real: el objeto Ingress no cambia, pero quién lo interpreta y qué construye por debajo cambia por completo.
Conexión con el módulo
Kubernetes define Ingress como una API, no como una implementación — cualquier controlador puede reclamar esa API e interpretar sus reglas a su manera. ingress-nginx es un controlador; el AWS Load Balancer Controller es otro, con una diferencia de fondo que esta lección desarrolla a fondo: uno vive completamente dentro del clúster, el otro crea infraestructura real fuera del clúster, en tu cuenta de AWS.
El mismo objeto, dos mundos distintos por debajo
MISMO Ingress DE KUBERNETES — DOS CONTROLADORES DISTINTOS
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: andes-cargo-ingress
spec:
ingressClassName: ??? ◀── esto decide cuál controlador actúa
rules:
- host: andes-cargo.local
http:
paths:
- path: /
backend:
service:
name: status-api-service
ingressClassName: nginx (M4, EJECUTADO) ingressClassName: alb (M7, representativo)
───────────────────────────────────── ─────────────────────────────────────────
ingress-nginx interpreta la regla AWS Load Balancer Controller interpreta
│ la regla
▼ ▼
Un Pod más, corriendo DENTRO Una llamada a la API de AWS,
de andes-cargo-cluster crea un Application Load
(namespace ingress-nginx) Balancer REAL en tu cuenta,
│ fuera del clúster
▼ ▼
nginx.conf generado internamente, Un ALB con su propio DNS
el proceso enruta el tráfico público, sus propios
entre Pods dentro del clúster target groups, apuntando
directo a los Pods
La AWS Load Balancer Controller, en las palabras exactas de la documentación oficial: "The AWS Load Balancer Controller manages AWS Elastic Load Balancers for a Kubernetes cluster... The controller watches for Kubernetes Ingress or Service resources. In response, it creates the appropriate AWS Elastic Load Balancing resources." La palabra clave es "creates": no simula, no proxea internamente — crea recursos reales de AWS (un Application Load Balancer, con su propio ARN, su propia factura, visible en la consola de EC2/ELB) cada vez que un objeto Ingress lo pide.
Qué crea exactamente, según el tipo de objeto
La documentación oficial de AWS es precisa sobre qué recurso corresponde a qué objeto de Kubernetes:
| Objeto de Kubernetes | Qué crea el AWS Load Balancer Controller |
|---|---|
Ingress | Un Application Load Balancer (ALB) — balanceo de capa 7, HTTP/HTTPS, reglas de ruta |
Service de tipo LoadBalancer | Un Network Load Balancer (NLB) — balanceo de capa 4, TCP/UDP |
Gateway (Kubernetes Gateway API, controlador v2.14.0+) | Un Application Load Balancer (ALB), con configuración estandarizada en vez de anotaciones |
ingress-nginx, para comparar, no crea ningún recurso de AWS bajo ninguna circunstancia — no tiene forma de hacerlo, ni falta que le hace: es, en sí mismo, el balanceador, corriendo como Pods dentro del clúster que ya administras. Esa es la diferencia de arquitectura completa entre ambos: uno es el balanceador; el otro crea un balanceador aparte.
Un detalle documentado que vale la pena conocer antes de decidir: desde la versión 2.5 del controlador, si lo instalas en un clúster EKS, se convierte por defecto en el controlador de cualquier Service de tipo LoadBalancer también —no solo de Ingress—, reemplazando al legacy cloud provider de Kubernetes (que crea Classic Load Balancers, un tipo de balanceador que AWS ya no recomienda). Es una razón adicional, documentada, para instalarlo incluso si tu único uso inicial es Ingress: evita que Kubernetes recurra por accidente al proveedor de balanceadores más antiguo.
El IngressClass: el mismo mecanismo, apuntando a otro controlador
En el Módulo 4, ingressClassName: nginx le decía a Kubernetes "esta regla le pertenece al controlador de ingress-nginx" — el valor exacto que el manifiesto de esa lección creó como IngressClass. Con el AWS Load Balancer Controller, el mismo campo apunta a un IngressClass distinto, con un controller propio:
Con IngressClass (representativo) — verificado contra la documentación oficial del proyecto aws-load-balancer-controller:
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
name: alb
spec:
controller: ingress.k8s.aws/alb
Y el Ingress de andes-cargo-status-api, con el mismo path/host que ya conoces del Módulo 4, apuntando a esta clase en vez de a nginx:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: andes-cargo-ingress
namespace: andes-cargo
annotations:
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: ip
spec:
ingressClassName: alb
rules:
- host: andes-cargo.local
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: status-api-service
port:
number: 80
Compara este YAML, campo por campo, contra el ingress.yaml real del Módulo 4.5: host, path, pathType, backend.service, todos idénticos. Lo único que cambia es ingressClassName (nginx → alb) y la aparición de anotaciones específicas del controlador (alb.ingress.kubernetes.io/*), el mecanismo estándar que cada controlador de Ingress usa para exponer configuración propia sin romper la portabilidad del objeto base — un patrón que docs.aws.amazon.com/eks documenta con su propio catálogo completo de anotaciones. alb.ingress.kubernetes.io/target-type: ip merece explicación aparte: le dice al ALB que enrute directo a la IP del Pod (vía el CNI de la VPC), en vez de al puerto del nodo — la opción recomendada cuando el clúster usa el Amazon VPC CNI, que le da a cada Pod una IP real y enrutable dentro de la VPC.
Tabla de contraste directo
ingress-nginx (M4, EJECUTADO) | AWS Load Balancer Controller (M7, representativo) | |
|---|---|---|
| Dónde vive el balanceador | Dentro del clúster, como Pod (namespace ingress-nginx) | Fuera del clúster, como recurso real de AWS |
| Qué recurso de AWS crea | Ninguno | Un Application Load Balancer real, con ARN propio |
| Costo | $0 adicional — es solo cómputo del clúster que ya pagas | El costo real de un ALB (horas + LCU de AWS), aparte del costo del clúster |
ingressClassName | nginx | alb |
| Alta disponibilidad del balanceador en sí | Depende de cuántas réplicas del propio Pod controlador corran, y de que el clúster las mantenga sanas | Administrada por AWS, con la misma disponibilidad que cualquier ALB de la cuenta |
Necesita extraPortMappings (el detalle específico de kind del Módulo 4) | Sí, en kind — no aplica a EKS, donde el ALB tiene su propio DNS público real | No aplica — el ALB nunca reenvía puertos del host, tiene su propia dirección pública |
| Requiere identidad de AWS (IRSA/Pod Identity, lección 5) | No — nunca llama a ninguna API de AWS | Sí — el propio controlador necesita un ServiceAccount con permisos de IAM para crear/modificar ALBs en tu nombre |
La última fila conecta directamente con la lección anterior: el AWS Load Balancer Controller es, él mismo, un consumidor del patrón IRSA/EKS Pod Identity — necesita permiso para llamar a la API de Elastic Load Balancing en tu nombre, así que se instala con su propio ServiceAccount anotado, exactamente con el mismo mecanismo que usarías para andes-cargo-status-api.
Instalación con Helm (representativo), el método que AWS recomienda para quien empieza:
eksctl create iamserviceaccount \
--cluster andes-cargo-cluster \
--namespace kube-system \
--name aws-load-balancer-controller \
--attach-policy-arn arn:aws:iam::000000000000:policy/AWSLoadBalancerControllerIAMPolicy \
--approve
helm repo add eks https://aws.github.io/eks-charts
helm install aws-load-balancer-controller eks/aws-load-balancer-controller \
--namespace kube-system \
--set clusterName=andes-cargo-cluster \
--set serviceAccount.create=false \
--set serviceAccount.name=aws-load-balancer-controller
Errores comunes
Asumir que hay que reescribir el objeto Ingress completo al migrar de ingress-nginx al AWS Load Balancer Controller (de sobreestimación del cambio). Qué pasa: alguien, al enterarse de que "el controlador cambia por completo", asume que también hay que reescribir host, path, pathType y el backend. Cómo detectarlo: si tu plan de migración incluye cambiar el spec.rules del Ingress. Cómo corregirlo: como confirmó la comparación campo por campo de esta lección, host/path/pathType/backend.service son idénticos — es el mismo estándar de Kubernetes. Solo ingressClassName y las anotaciones específicas del controlador cambian.
Olvidar que el propio controlador necesita su propia identidad de AWS antes de que cree nada (de secuencia). Qué pasa: alguien instala el Helm chart del AWS Load Balancer Controller sin haber creado antes el ServiceAccount con IRSA/Pod Identity, y el controlador arranca sin permisos para llamar a la API de ELB. Cómo detectarlo: si el controlador queda en estado Running pero ningún ALB llega a crearse, y los logs muestran errores de AccessDenied contra la API de elasticloadbalancing. Cómo corregirlo: la secuencia correcta, como muestra el ejemplo de instalación de esta lección, es primero eksctl create iamserviceaccount (con la policy AWSLoadBalancerControllerIAMPolicy oficial), y solo después el helm install — el mismo orden de dependencia de identidad que ya viste con StatusApiTaskRole en la lección anterior.
Pensar que alb.ingress.kubernetes.io/target-type: ip es opcional o cosmético (técnico). Qué pasa: alguien omite esa anotación, asumiendo que el ALB va a "simplemente funcionar" igual sin ella. Cómo detectarlo: si tu Ingress para el AWS Load Balancer Controller no declara ningún target-type. Cómo corregirlo: sin esa anotación, el valor por defecto (instance) enruta el tráfico al puerto del nodo, no directo al Pod —una diferencia real de comportamiento con un CNI de VPC real, donde cada Pod ya tiene una IP enrutable propia—; para el patrón de esta guía (Amazon VPC CNI, IPs de Pod reales), target-type: ip es la opción documentada como recomendada, no un detalle cosmético.
Ejercicios
Ejercicio 1 — Identifica qué cambia y qué no, sin mirar la lección. Escribe de memoria: ¿qué campos de un Ingress de andes-cargo-status-api cambian al pasar de ingress-nginx a AWS Load Balancer Controller, y cuáles permanecen exactamente iguales?
Ver solución
Cambia: ingressClassName (de nginx a alb), y aparecen anotaciones específicas del controlador (alb.ingress.kubernetes.io/scheme, alb.ingress.kubernetes.io/target-type, entre otras). Permanece exactamente igual: host, path, pathType, y toda la referencia a backend.service (nombre y puerto del Service). Si tu respuesta separó "lo que pertenece al estándar de Kubernetes" (sin cambios) de "lo que pertenece a la implementación del controlador" (cambia), capturaste la distinción central de esta lección.
Ejercicio 2 — Explica, sin usar la palabra "dentro" ni "fuera", la diferencia arquitectónica entre ambos controladores. Un colega te pregunta cuál es la diferencia real entre ingress-nginx y el AWS Load Balancer Controller. Respóndele en una frase, sin usar las palabras "dentro" ni "fuera".
Ver solución
Una respuesta completa suena, más o menos, así: "ingress-nginx es, él mismo, el balanceador —un proceso corriendo como Pod, administrado con las mismas herramientas que cualquier otra carga del clúster—; el AWS Load Balancer Controller, en cambio, es un operador que observa objetos Ingress y, en respuesta, crea un Application Load Balancer real, un recurso de AWS con su propio ciclo de vida, facturación y disponibilidad, separado del clúster que lo pidió."
Ejercicio 3 — Predice el efecto de instalar el controlador sin darle identidad de AWS primero. Basándote en el "Errores comunes" de esta lección, predice: si instalas el Helm chart del AWS Load Balancer Controller sin haber creado antes su ServiceAccount con IRSA/Pod Identity, ¿el Pod del controlador arranca? ¿Y un Ingress aplicado después llega a crear un ALB?
Ver solución
El Pod del controlador sí arranca y queda en estado Running — no hay ninguna dependencia técnica que le impida arrancar sin credenciales de AWS. Lo que falla es su función: al recibir un Ingress nuevo e intentar llamar a la API de elasticloadbalancing para crear el ALB, esa llamada es rechazada con un error de AccessDenied, porque el ServiceAccount del controlador no tiene ningún rol IAM asociado. El síntoma visible, en la práctica, es un Ingress que se queda sin ninguna dirección asignada (ADDRESS vacío en kubectl get ingress) y logs de error en el propio controlador — no un fallo de arranque, sino un fallo de permisos en el primer intento de actuar.
Resumen y siguiente paso
Esta lección contrastó, campo por campo, el mismo objeto Ingress de Kubernetes bajo dos controladores completamente distintos: ingress-nginx (Módulo 4, ejecutado de verdad en kind), que es el balanceador, corriendo como Pod dentro del clúster; y el AWS Load Balancer Controller (representativo), que observa el objeto Ingress y crea un Application Load Balancer real en tu cuenta de AWS, fuera del clúster, con costo, disponibilidad y ciclo de vida propios. Confirmaste que host/path/pathType/backend.service no cambian —solo ingressClassName y las anotaciones específicas del controlador—, y que el propio controlador necesita su propia identidad de AWS (IRSA/Pod Identity, lección 5) antes de poder crear nada.
Antes de avanzar deberías poder: nombrar qué recurso de AWS crea el controlador para un Ingress frente a un Service de tipo LoadBalancer; explicar por qué target-type: ip importa con un CNI de VPC real; y describir, sin ambigüedad, la diferencia arquitectónica entre "ser el balanceador" y "crear un balanceador".
Siguiente lección: manos a la obra — el YAML de EKS, mostrado y explicado. Ahí vas a ver, reunidos en un solo lugar, eksctl create cluster, un IAMServiceAccount con IRSA, y este mismo IngressClass — sintaxis real, verificada, explícitamente etiquetada como no ejecutada.
Recursos
- Amazon EKS — Route internet traffic with AWS Load Balancer Controller — la fuente exacta de las citas y de la tabla de qué recurso crea para cada objeto de Kubernetes.
- AWS Load Balancer Controller — Ingress annotations — catálogo completo de anotaciones
alb.ingress.kubernetes.io/*. - AWS Load Balancer Controller — IngressClass — la fuente exacta del
controller: ingress.k8s.aws/albusado en esta lección. kubernetes-and-eks-in-production-guide(NIEVA), Módulo 4, lecciones 4-5 —ingress-nginxinstalado y elIngressreal destatus-api-service, el punto de comparación central de esta lección.