Módulo 4: Networking Ingress And Networkpolicy
1. Introducción al módulo: la capa que "no es *batteries included*"
Descripción
El Módulo 3 dejó a andes-cargo-status-api con configuración externalizada, probes reales, y un HorizontalPodAutoscaler que ya demostró, con carga real, que ajusta réplicas solo. Todo eso es cierto — y todo eso sigue siendo invisible desde fuera del clúster. Hoy, la única forma de hablarle a andes-cargo-status-api es kubectl port-forward, un túnel temporal que exige tener kubectl instalado, una sesión de terminal abierta, y que se cierra en cuanto la cierras. Ningún socio logístico de Andes Cargo va a instalar kubectl para consultar un envío. Este módulo resuelve exactamente eso: una puerta HTTP real, permanente, y un guardrail de red que decide quién puede cruzarla.
Conexión con el módulo
Este es, textualmente, el módulo que la lección 2 de aws-serverless-and-containers-guide M1... no — que la propia lección 2 del Módulo 1 de esta guía ya anticipó con una cita completa. Vale la pena volver a leerla ahora, con el clúster ya construido delante, en vez de como promesa abstracta.
La cita que abrió esta guía, ahora es este módulo
En el Módulo 1, lección 2, esta guía citó a un ingeniero con experiencia real, en un hilo de Hacker News sobre exactamente este tema:
"it's not at all batteries included... you're still going to be installing a bunch of additional controllers (ingress, cert-manager, external dns to start)" — mikeocool, Hacker News (discusión 48548137).
Esa cita nombraba tres piezas que un clúster de Kubernetes recién creado no trae por defecto: un controller de Ingress, cert-manager, y external-dns. Esta guía, fiel a su regla de honestidad, no se saltó ninguna sin nombrarla: cert-manager y external-dns dependen de un dominio público y de un proveedor de DNS real, fuera del alcance de un laboratorio kind de $0 — se nombran, no se instalan. Pero la primera pieza, Ingress, es exactamente la que este módulo construye de principio a fin, con la misma fricción real que describe la cita: nada llega preinstalado, tú decides qué manifiesto aplicar, tú decides qué imagen correr, y tú confirmas, con kubectl get pods, que terminó de arrancar.
kind create cluster (Módulo 1) te dio un clúster funcional en menos de un minuto. Instalar y configurar Ingress —la lección 4 de este módulo— toma más pasos, más YAML, y una decisión de arquitectura real (qué puertos del host mapear, en qué nodo debe correr el controlador). Esa diferencia de esfuerzo es el punto que mikeocool describe, y es el hueco que VALIDACION.md (la auditoría de mercado de este ecosistema) encontró en 0 de 10 guías anteriores.
Qué construye este módulo, en dos mitades
Este módulo tiene dos mitades, cada una resolviendo un problema de red distinto:
Primera mitad (lecciones 2-5): sacar tráfico hacia adentro. Hoy, status-api-service es un Service de tipo ClusterIP — accesible solo desde dentro del clúster, o mediante kubectl port-forward desde tu máquina. La lección 2 explica el modelo de red que hace esto posible (cada Pod, una IP propia). La lección 3 explica qué es un Ingress y por qué "un Service por cliente expuesto directamente" no escala. Las lecciones 4 y 5 lo construyen de verdad: ingress-nginx instalado dentro de kind, y una regla de Ingress real, con curl respondiendo sin ningún túnel de por medio.
Segunda mitad (lecciones 6-8): decidir quién puede hablar con quién, adentro. Abrir una puerta hacia afuera no dice nada sobre qué pasa dentro del clúster — por defecto, cualquier Pod de cualquier namespace puede hablarle a cualquier otro Pod. Eso es exactamente lo que cloud-security-and-guardrails-guide delegó a esta guía, con cita textual de su propio diseño (ver más abajo). Las lecciones 6, 7 y 8 construyen el modelo opuesto: nada pasa hasta que una regla explícita lo permite.
EL MAPA DE ESTE MÓDULO
Hoy (fin del M3) Al cerrar este módulo
───────────────── ──────────────────────
status-api-service (ClusterIP) status-api-service (ClusterIP)
│ │
kubectl port-forward ┌─────────────┐
(túnel temporal, │ Ingress │◄── curl real,
requiere kubectl) │ (ingress-nginx) sin túnel
│ └──────┬──────┘
▼ │
tu terminal ┌──────▼──────┐
│ NetworkPolicy │ default-deny +
│ (deny-by- │ regla explícita
│ default) │ solo para
└─────────────────┘ ingress-nginx
La delegación exacta que este módulo cierra
Este no es un módulo que esta guía decidió construir por iniciativa propia — es, en parte, una promesa que otra guía hermana ya diseñada dejó por escrito, apuntando aquí. cloud-security-and-guardrails-guide declaró, en su propio DISEÑO.md, la frontera exacta de lo que no construye:
"EKS y runtime de contenedores (admission controllers en clúster — OPA Gatekeeper, Kyverno —, escaneo de imágenes Docker,
NetworkPolicy) →kubernetes-and-eks-in-production-guide."
NetworkPolicy está nombrado, textualmente, en esa cita. La lección 6 de este módulo retoma esta misma cita completa, con el contexto de por qué esa guía —enfocada en seguridad de infraestructura y cadena de suministro de Terraform— nunca construyó el guardrail de red en clúster: es una capa distinta de la misma disciplina, y esta guía es donde vive.
Analogía: el edificio que ya tiene empleados, pero ni recepción ni control de acceso
Piensa en andes-cargo-status-api como una empresa que ya contrató a su personal (Módulo 2), le dio manuales de operación y una rutina de salud (Módulo 3) — pero todavía opera en un edificio sin recepción y sin ninguna puerta con llave. Cualquier visitante que sepa el número exacto de oficina puede entrar directo, sin pasar por ningún mostrador; y cualquier otra empresa del mismo edificio puede caminar hasta esa oficina sin que nadie se lo impida. Este módulo instala dos cosas, en ese orden: una recepción única (Ingress) que recibe a todo visitante externo por la misma puerta principal, sin que cada oficina tenga que resolver su propia seguridad de entrada; y un sistema de tarjetas de acceso (NetworkPolicy) donde, por defecto, ninguna puerta interior se abre para nadie, hasta que alguien autoriza explícitamente quién puede pasar a dónde. Ningún edificio de oficinas real opera sin las dos cosas — y ningún clúster de Kubernetes de producción tampoco.
Mapa de este módulo
| # | Lección | Qué resuelve |
|---|---|---|
| 2 | El modelo de red de Kubernetes: cada Pod, una IP | El contrato que hace posible que un Ingress funcione: por qué todo Pod puede hablarle a todo Pod, sin NAT, por defecto |
| 3 | Ingress: una puerta HTTP para el clúster | Qué problema resuelve, con el paralelo explícito de API Gateway (aws-serverless-and-containers-guide M5) |
| 4 | Manos a la obra: instalando ingress-nginx en kind | El controlador real, corriendo dentro del clúster |
| 5 | Manos a la obra: Ingress para status-api-service | curl real, sin port-forward, por primera vez en esta guía |
| 6 | NetworkPolicy: por defecto, todos hablan con todos — y por qué eso no dura | La delegación de cloud-security-and-guardrails-guide, y el modelo deny-by-default |
| 7 | Manos a la obra: NetworkPolicy real sobre andes-cargo | Bloqueo real verificado, con un hallazgo que corrige una idea común sobre kind |
| 8 | Proyecto: status-api-service expuesto y protegido | Ingress + NetworkPolicy juntos, el camino permitido y el bloqueado, verificados los dos |
Al cerrar este módulo, andes-cargo-status-api va a ser alcanzable desde fuera del clúster por una puerta HTTP real, y va a estar protegido por una política de red que solo deja pasar exactamente el tráfico que decidiste permitir. El Módulo 5 va a tomar este mismo estado y entregárselo a ArgoCD como fuente de verdad de GitOps.
Errores comunes
Asumir que "instalar ingress-nginx" es el final del trabajo de este módulo (de expectativa). Qué pasa: alguien completa las lecciones 4 y 5, ve curl respondiendo, y da el módulo por cerrado. Por qué pasa: una puerta HTTP funcionando se siente como el objetivo completo — "ya puedo hablarle al servicio desde afuera". Cómo detectarlo: si terminas la lección 5 sin haber leído todavía nada sobre NetworkPolicy. Cómo corregirlo: recuerda la analogía de esta lección — una recepción sin ningún control de acceso interior deja que cualquier otra empresa del edificio entre a la oficina de Andes Cargo sin restricción. Las lecciones 6-8 no son un anexo opcional, son la otra mitad del mismo problema de red.
Confundir "el clúster tiene un Ingress" con "el tráfico ya no necesita un Service" (conceptual, sobre la relación entre ambos objetos). Qué pasa: alguien, al ver la lección 5, asume que Ingress reemplaza a status-api-service (Módulo 2), en vez de apoyarse en él. Por qué pasa: ambos objetos resuelven "cómo llega el tráfico", y es fácil pensar que uno sustituye al otro. Cómo detectarlo: si te preguntas si deberías borrar service.yaml al llegar a este módulo. Cómo corregirlo: la lección 3 lo explica a fondo — un Ingress nunca le habla directo a un Pod; siempre reenvía a través de un Service existente. Vas a seguir necesitando status-api-service, sin ningún cambio, durante el resto de esta guía.
Esperar que el Módulo 4 resuelva /shipments/<id> (de continuidad, el mismo patrón que ya viste en el Módulo 3). Qué pasa: alguien, al ver curl funcionando por primera vez sin port-forward en la lección 5, espera que también /shipments/4471 responda con datos reales. Cómo detectarlo: si te sorprende ver el mismo 500 que dejaron los módulos 2 y 3. Cómo corregirlo: este módulo resuelve cómo llega el tráfico y quién puede enviarlo — no de dónde salen los datos. Esa segunda pieza depende de una capa de datos (DynamoDB, vía LocalStack) que queda fuera del alcance $0 de esta guía: ningún módulo la instala. /health sigue siendo la señal que este módulo valida de punta a punta; /shipments/<id> se mantiene representativo hasta el capstone.
Ejercicios
Ejercicio 1 — Cita la fuente de este módulo sin volver a leerla. Sin volver a la sección correspondiente, escribe de memoria: (a) la frase textual de mikeocool sobre "batteries included"; (b) las tres piezas que nombra; (c) cuál de esas tres construye este módulo, y por qué las otras dos no.
Ver solución
(a) "it's not at all batteries included... you're still going to be installing a bunch of additional controllers (ingress, cert-manager, external dns to start)". (b) Ingress, cert-manager, external-dns. (c) Este módulo construye Ingress, ejecutado de verdad; cert-manager y external-dns dependen de un dominio público real y un proveedor de DNS, fuera del alcance de un laboratorio kind de $0 — se nombran por honestidad, no se instalan.
Ejercicio 2 — Explica la analogía del edificio a un colega que solo conoce Docker. En dos o tres frases, sin usar la palabra "Kubernetes", explica por qué un edificio con empleados sanos (Módulos 2-3) todavía podría no estar listo para recibir visitantes.
Ver solución
Una explicación razonable: "Tener empleados sanos trabajando adentro no es lo mismo que estar listo para recibir público — falta una recepción única por donde entre todo visitante externo, en vez de que cada visitante tenga que saber el número exacto de oficina; y falta un sistema de tarjetas de acceso que, por defecto, no deje pasar a nadie entre oficinas internas hasta que alguien lo autorice explícitamente."
Ejercicio 3 — Predice la relación entre Ingress y Service. Antes de leer la lección 3, con lo que ya sabes del Módulo 2 sobre status-api-service, predice: ¿un Ingress habla directo con los Pods, o pasa primero por el Service existente? Justifica tu respuesta con lo que ya sabes sobre por qué existe un Service en primer lugar.
Ver solución
Pasa primero por el Service. El Módulo 2 (lección 6) ya estableció por qué un Service existe: las IPs de Pod son efímeras, y el Service da una dirección estable que sobrevive a que los Pods cambien. Un Ingress que hablara directo con IPs de Pod tendría que resolver el mismo problema de estabilidad por su cuenta — en vez de eso, reutiliza el Service que ya lo resuelve, y solo agrega la capa de enrutamiento HTTP por encima.
Resumen y siguiente paso
Esta lección conectó este módulo con la cita que abrió toda la guía: mikeocool describió, sin adornos, que un clúster de Kubernetes recién creado no trae Ingress de fábrica — hay que instalarlo, configurarlo, y verificarlo, exactamente el trabajo real que las lecciones 4 y 5 hacen. También conectó este módulo con una promesa textual de cloud-security-and-guardrails-guide, que delegó NetworkPolicy aquí por nombre. Al cerrar este módulo, andes-cargo-status-api va a tener una puerta HTTP real y un guardrail de red deny-by-default — las dos mitades de "listo para tráfico de producción" que "3 réplicas balanceadas" (Módulo 2) y "configuración/salud/autoscaling" (Módulo 3) todavía no cubrían.
Antes de avanzar deberías poder: citar la fuente de mercado que abre este módulo; explicar por qué Ingress no reemplaza a Service; y nombrar las dos mitades de este módulo (tráfico entrante, y quién puede generarlo).
Siguiente lección: el modelo de red de Kubernetes. Ahí empieza el fundamento técnico que hace posible todo lo demás — el contrato que garantiza que cada Pod tenga su propia IP, y que cualquier Pod pueda hablarle a cualquier otro, sin NAT, por defecto.
Recursos
- Hacker News — discusión 48548137 — el hilo original donde mikeocool describe la experiencia real de "no batteries included", citado también en el Módulo 1, lección 2.
src/paths/aws-cloud-ecosystem/VALIDACION.md(NIEVA, auditoría de mercado, 19-jul-2026) — el hallazgo completo: 0 de 10 guías cubríaningress,cert-manager,external-dns, CNI, autoscaling o GitOps.- Kubernetes — Services, Load Balancing, and Networking — la puerta de entrada oficial a todo lo que construye este módulo.
cloud-security-and-guardrails-guide(NIEVA),DISEÑO.md— la delegación textual deNetworkPolicyque la lección 6 de este módulo retoma completa.kubernetes-and-eks-in-production-guide(NIEVA), Módulo 3, lección 8 — el estado exacto del que parte este módulo:andes-cargo-status-apicon configuración,probesyHPAreales.