Módulo 4: Networking Ingress And Networkpolicy

3. `Ingress`: una puerta HTTP para el clúster

Descripción

Con el contrato de red de la lección 2 confirmado —cada Pod, una IP, sin NAT, en cualquier dirección—, esta lección responde una pregunta distinta: ¿cómo entra tráfico desde fuera del clúster? La respuesta ingenua sería "un Service de tipo NodePort o LoadBalancer por cada servicio que quieras exponer" — y esa respuesta, a escala, se vuelve tan insostenible como el problema que ya resolviste una vez en otra guía de este ecosistema. Ingress es la solución de Kubernetes al mismo problema, en una capa distinta.

Conexión con el módulo

Esta lección es puramente conceptual — no vas a ejecutar ningún comando. Es el fundamento sobre el que se apoyan las lecciones 4 y 5, que instalan y configuran un Ingress real. Cuando termines esta lección vas a poder explicar por qué Andes Cargo necesita esta pieza, antes de ver cómo se construye.


El problema, sin Ingress

status-api-service (Módulo 2) es un Service de tipo ClusterIP — deliberadamente, solo alcanzable desde dentro del clúster. Si quisieras exponerlo directamente hacia afuera sin Ingress, tendrías dos opciones, ninguna satisfactoria a escala:

  • NodePort: cada Service reserva un puerto fijo (en el rango 30000-32767) en cada nodo del clúster. Funciona, pero cada servicio nuevo necesita su propio puerto, memorizado y comunicado a cada cliente — nada de nombres de dominio legibles, nada de rutas por path.
  • LoadBalancer: en una nube real, cada Service de este tipo crea un balanceador de carga dedicado (un ALB o NLB en AWS). Funciona, pero un balanceador por cada microservicio de un sistema con decenas de ellos es, literalmente, decenas de balanceadores — cada uno con su propio costo, su propia IP pública, su propio certificado TLS que renovar.

Ninguna de las dos opciones resuelve algo que casi todo sistema real necesita: enrutar andes-cargo.example.com/status a un servicio y andes-cargo.example.com/manifests a otro, con una sola dirección pública, un solo certificado TLS, y una sola capa donde decidir reglas de tráfico. Ese es, exactamente, el problema que Ingress resuelve.


El paralelo explícito: Ingress es el API Gateway de un clúster de Kubernetes

Si completaste aws-serverless-and-containers-guide, ya construiste la solución a este mismo problema, en otra capa. El Módulo 5 de esa guía abrió con esta descripción:

"Un API Gateway es la recepción de un edificio de oficinas. No hace el trabajo de ningún piso —no factura, no procesa pedidos, no consulta bases de datos—, pero sin él, cada visitante tendría que saber de memoria en qué piso, oficina y horario encontrar a quien busca."

Ingress es la misma idea, en una capa distinta. La tabla siguiente hace el paralelo explícito, campo por campo:

CapacidadAPI Gateway (AWS, capa de cuenta)Ingress (Kubernetes, capa de clúster)
Qué resuelveUna URL pública, muchos backends (Lambda, contenedores, otros servicios de AWS)Un host/puerto, muchos Service internos del clúster
EnrutamientoPor método HTTP y ruta (GET /shipments/{id})Por host y path (andes-cargo.local/)
Quién lo implementaAmazon API Gateway (servicio gestionado de AWS)Un controller que tú instalas dentro del clúster (lección 4: ingress-nginx)
TLS/certificadosGestionado por AWS Certificate ManagerGestionado por cert-manager (nombrado en la lección 1, no construido)
Sin esta piezaCada Lambda/contenedor resuelve su propia URL pública, sin capa compartidaCada Service necesita su propio NodePort/LoadBalancer
AlcanceUna cuenta de AWSUn clúster de Kubernetes

La diferencia central, y la razón por la que ambas guías necesitan su propia lección para esto, no es conceptual —es la misma idea, "una recepción única en vez de una puerta por empresa"— sino de quién administra la implementación. API Gateway es un servicio gestionado: AWS corre la infraestructura, tú solo declaras las reglas. Ingress es distinto en un punto crítico: el objeto Ingress en sí es solo una declaración de reglas (qué host/path va a qué Service) — no hace nada por sí mismo hasta que instalas un controller que las implemente. Esa es, literalmente, la fricción que la cita de mikeocool (lección 1 de este módulo) describe: "vas a estar instalando controladores adicionales, empezando por ingress".

        EL MISMO PROBLEMA, DOS CAPAS DISTINTAS

  aws-serverless-and-containers-guide (M5)   kubernetes-and-eks-in-production-guide (M4)
  ┌─────────────────────────────┐            ┌─────────────────────────────┐
  │   Cliente HTTP externo        │            │   Cliente HTTP externo        │
  └──────────────┬───────────────┘            └──────────────┬───────────────┘
                  ▼                                            ▼
       ┌────────────────────┐                        ┌────────────────────┐
       │   API Gateway        │  gestionado por AWS   │   Ingress             │  tú instalas
       │   (una URL pública)   │                       │   (una regla)         │  el controller
       └──────────┬──────────┘                        └──────────┬──────────┘
                  │                                               │
        ┌─────────┼─────────┐                            ┌────────┼────────┐
        ▼         ▼         ▼                             ▼        ▼        ▼
     Lambda   contenedor  otro servicio               Service   Service   Service

Qué es, técnicamente, un objeto Ingress

Un Ingress es un objeto de la API de Kubernetes (apiVersion: networking.k8s.io/v1, kind: Ingress) que declara reglas de enrutamiento HTTP: dado un host (por ejemplo, andes-cargo.local) y un path (por ejemplo, /), a qué Service —y a qué puerto de ese Service— reenviar el tráfico. Nada más. El objeto en sí no escucha ningún puerto, no procesa ninguna solicitud HTTP, no arranca ningún proceso — es, exactamente como un manifiesto de Deployment o de Service, una declaración de intención, que otra pieza tiene que hacer real.

Esa otra pieza es el Ingress controller — un Pod (o varios) que corre dentro del clúster, hace watch de todos los objetos Ingress existentes, y configura, por debajo, un servidor HTTP real (típicamente NGINX, pero hay otras implementaciones) para que cumpla esas reglas. Sin un controller instalado, un Ingress aplicado con kubectl apply se guarda perfectamente en etcd, sin ningún error — y no hace absolutamente nada, porque no hay nadie leyéndolo. Esta es, en sí misma, una de las trampas más comunes de aprender Ingress por primera vez, y la lección 4 de este módulo la resuelve instalando el controller antes de declarar ninguna regla.

              EL OBJETO Ingress NO HACE NADA SOLO

  kubectl apply -f ingress.yaml
          │
          ▼
   ┌─────────────┐        sin un controller instalado:
   │   etcd        │  ──►  el objeto se guarda, nadie lo lee,
   │  (Ingress      │       ningún tráfico se enruta, sin ningún
   │   guardado)    │       error visible
   └─────────────┘

   ┌─────────────┐        con ingress-nginx corriendo (lección 4):
   │   etcd        │  ──►  el controller detecta el objeto nuevo,
   │  (Ingress      │       configura NGINX por debajo, el tráfico
   │   guardado)    │       empieza a fluir según la regla
   └─────────────┘
          ▲
          │
   ingress-nginx (hace watch constante)

IngressClass: cuando hay más de un controller

Un clúster puede tener más de un Ingress controller instalado al mismo tiempo (por ejemplo, ingress-nginx para tráfico interno y el AWS Load Balancer Controller para tráfico que necesita un ALB real — el Módulo 7 vuelve sobre esto). Cuando eso pasa, cada objeto Ingress necesita declarar, con el campo ingressClassName, a cuál controller le pertenece. Esta guía usa un solo controller (ingress-nginx, lección 4), así que el campo aparece con un solo valor posible (nginx) — pero vale la pena conocer el mecanismo desde ya, porque el Módulo 7 lo retoma con un segundo controller real.


Analogía: la recepción del edificio, otra vez, con las reglas escritas en el libro de visitas

Retomando la analogía de la lección 1: si Ingress es la recepción única de un edificio de oficinas, entonces el objeto Ingress en sí es solo el libro de reglas de acceso que alguien escribió —"todo visitante que pregunte por 'Andes Cargo' va al tercer piso"—, no la persona que efectivamente para al visitante en la puerta y lo dirige. Ese libro, sin un recepcionista real trabajando ese turno, es papel sin efecto: cualquiera podría caminar hasta el ascensor sin que nadie lo detenga a leer el libro. El Ingress controller es el recepcionista de carne y hueso —ingress-nginx, en el caso de esta guía— que efectivamente lee el libro, para a cada visitante, y lo dirige según lo que está escrito. Escribir el libro (aplicar un Ingress) sin haber contratado antes al recepcionista (instalar el controller) es exactamente el error que la sección anterior describe.


Errores comunes

Declarar un Ingress antes de instalar ningún controller, y no entender por qué "no pasa nada" (el error más común de aprender esta pieza por primera vez). Qué pasa: alguien, siguiendo un tutorial distinto a esta guía, aplica un manifiesto de Ingress sin haber instalado antes ningún controller, ve que kubectl apply responde created sin error, y espera que el tráfico ya esté enrutado. Por qué pasa: la mayoría de los objetos de Kubernetes que ya conoces (Pod, Deployment, Service) hacen algo tangible en cuanto los aplicas — es intuitivo esperar lo mismo de Ingress. Cómo detectarlo: kubectl get ingress muestra el objeto, pero cualquier curl contra la dirección esperada falla, sin ningún error del lado de Kubernetes que lo explique. Cómo corregirlo: esta guía evita el error por orden de las lecciones —la 4 instala el controller antes de que la 5 declare ninguna regla—, pero si alguna vez te encuentras en esta situación, kubectl get pods -A | grep -i ingress es el primer comando de diagnóstico: si no hay ningún Pod de un Ingress controller corriendo en ningún namespace, esa es la causa.

Confundir Ingress con un Service de tipo LoadBalancer (conceptual). Qué pasa: alguien asume que Ingress y Service type: LoadBalancer resuelven el mismo problema, de formas intercambiables. Cómo detectarlo: si dudas sobre cuál usar para exponer status-api-service. Cómo corregirlo: un LoadBalancer expone un Service, con una IP externa, sin ninguna lógica de enrutamiento por host/path — es la herramienta correcta cuando de verdad solo tienes un servicio que exponer, sin necesidad de reglas. Ingress está diseñado para el caso donde varios Service comparten una sola puerta de entrada, con reglas de enrutamiento entre ellos — el caso que se vuelve inevitable en cualquier sistema con más de un componente HTTP, como Andes Cargo con el tiempo.

Esperar que Ingress reemplace la necesidad de un Service (ya adelantado en la lección 1, vale la pena repetirlo aquí con el mecanismo completo delante). Qué pasa: alguien, entendiendo que Ingress "expone tráfico hacia afuera", asume que puede saltarse la declaración de status-api-service (Módulo 2) y apuntar el Ingress directo a los Pods. Cómo detectarlo: si buscas, en la especificación de un Ingress, algún campo para declarar Pods directamente, en vez de un Service. Cómo corregirlo: la especificación de Ingress solo acepta un Service como backend (backend.service.name), nunca un Pod ni un selector de etiquetas directo — la lección 5 lo confirma en YAML real.


Ejercicios

Ejercicio 1 — Completa la tabla de paralelo de memoria. Sin volver a la tabla de esta lección, completa: "API Gateway es a una cuenta de AWS lo que Ingress es a ___". Después, nombra dos capacidades que ambos comparten.

Ver solución

"API Gateway es a una cuenta de AWS lo que Ingress es a un clúster de Kubernetes." Dos capacidades compartidas: enrutamiento de tráfico HTTP entrante hacia múltiples backends según reglas (ruta/host), y una sola puerta de entrada compartida en vez de una por cada backend individual.

Ejercicio 2 — Explica por qué un Ingress recién aplicado "no hace nada" a un colega. Un colega aplicó un manifiesto de Ingress en un clúster sin ningún controller instalado, y no entiende por qué curl no responde nada. Explícaselo en dos o tres frases, usando la analogía de esta lección.

Ver solución

Una explicación razonable: "El objeto Ingress que aplicaste es solo el libro de reglas de acceso — dice qué visitante va a qué piso, pero no hace nada por sí mismo. Falta contratar al recepcionista de carne y hueso, el Ingress controller, que efectivamente lee ese libro y dirige el tráfico según lo que dice. Sin ese controller corriendo, el libro existe, perfectamente guardado, y nadie lo lee."

Ejercicio 3 — Decide cuándo Ingress no hace falta. Una empresa ficticia tiene un único microservicio interno, sin ningún plan de agregar más en el futuro cercano, y solo necesita exponerlo temporalmente para una demo. Usando el criterio de esta lección (no tu intuición), argumenta si Ingress es la herramienta correcta, o si algo más simple alcanza.

Ver solución

Para ese caso específico, un Service de tipo NodePort (o LoadBalancer, si está en una nube real) probablemente alcanza: el problema que Ingress resuelve —enrutamiento por host/path entre múltiples backends, con una sola puerta compartida— no existe todavía cuando solo hay un servicio. Instalar y mantener un Ingress controller completo para un solo servicio temporal es más infraestructura de la que el caso justifica — el mismo tipo de contrapartida que ya viste, en otra capa, entre Lambda y un contenedor en aws-serverless-and-containers-guide M1.


Resumen y siguiente paso

Esta lección explicó qué es un Ingress sin ejecutar ningún comando: una declaración de reglas de enrutamiento HTTP (host/pathService) que, por sí sola, no hace nada hasta que un Ingress controller —un Pod real que hace watch de esas reglas y configura un servidor HTTP por debajo— las implementa. El paralelo con API Gateway (aws-serverless-and-containers-guide M5) no es casualidad: es el mismo problema —una recepción única, en vez de una puerta por servicio— resuelto en dos capas distintas del mismo sistema.

Antes de avanzar deberías poder: explicar la diferencia entre el objeto Ingress y el Ingress controller; completar la tabla de paralelo con API Gateway sin mirarla; y decidir, para un caso nuevo, si Ingress es la herramienta correcta o si un Service más simple alcanza.

Siguiente lección: manos a la obra, instalando ingress-nginx en kind. Ahí instalas, por primera vez en esta guía, el recepcionista real que esta lección describió en teoría — con la fricción exacta que la cita de mikeocool anticipó.

Recursos

  1. Kubernetes — Ingress — la especificación oficial completa del objeto Ingress, incluida la distinción con el controller.
  2. Kubernetes — Ingress Controllers — el listado oficial de implementaciones, y la explicación de por qué un Ingress sin controller no hace nada.
  3. aws-serverless-and-containers-guide (NIEVA), Módulo 5, lección 2 — el origen exacto de la analogía "recepción de un edificio de oficinas", retomada aquí en la capa de Kubernetes.
  4. Kubernetes — Service — referencia del Módulo 2 de esta guía, la pieza que un Ingress siempre necesita como backend.