Introducción
Los Services proporcionan puntos de acceso estables para las aplicaciones dentro de un clúster. Ingress añade reglas de enrutamiento HTTP delante de los Services, lo que permite que varias aplicaciones compartan un mismo punto de entrada mediante el nombre de host o la ruta URL.
Inspeccionarás el controlador ingress-nginx preparado, implementarás dos backends, añadirás enrutamiento por host y por ruta, y seguirás una solicitud a través de Ingress, Service y Pod.
Ten presente durante todo el laboratorio el recorrido de la solicitud: cliente → punto de entrada de ingress-nginx → regla de Ingress → Service → Pod listo. Cuando una solicitud falla, comprobar estos enlaces en orden resulta mucho más sencillo que tratar Ingress como una única caja negra.
Inspeccionar el controlador de Ingress
En este paso, inspeccionarás el controlador que ya proporciona el entorno de CKA en lugar de instalar una segunda copia.
Un objeto Ingress es configuración, no un proceso proxy. No tiene ningún efecto a menos que un controlador compatible lo supervise. Comienza comprobando que existen ambas piezas de infraestructura: una IngressClass llamada nginx y un Deployment disponible del controlador ingress-nginx.
cd /home/labex/project/ingress-routing
kubectl get ingressclasses
kubectl get deployments,pods,services -n ingress-nginx
kubectl wait --for=condition=Available deployment/ingress-nginx-controller -n ingress-nginx --timeout=60s
Un recurso Ingress almacena la intención de enrutamiento. El controlador ingress-nginx supervisa los recursos cuyo ingressClassName es nginx y configura el proxy real.
El Service del controlador expone el proxy mediante un NodePort en este clúster local. Más adelante descubrirás ese puerto en lugar de escribirlo directamente.
El entorno preparado muestra una clase nginx, un controlador disponible y un Service NodePort:
NAME CONTROLLER
nginx k8s.io/ingress-nginx
deployment.apps/ingress-nginx-controller 1/1 ...
service/ingress-nginx-controller NodePort ... 80:.../TCP,443:.../TCP
Los dos Pods de admisión con estado Completed que también podrías ver son Jobs de instalación que ya finalizaron; no son réplicas fallidas del controlador.
Implementar dos backends de Service
En este paso, crearás dos cargas de trabajo web con una sola réplica cada una y sus correspondientes Services ClusterIP a partir de un único archivo con varios documentos.
Estos backends utilizan conceptos de Kubernetes para principiantes, por lo que el objetivo de aprendizaje es comprender su relación de enrutamiento, no la sintaxis de Deployment. El archivo contiene cinco documentos YAML separados por ---: un namespace, seguido de un Deployment y un Service para cada aplicación. Observa el Service.spec.selector junto a la etiqueta del Pod correspondiente; deben coincidir antes de que Ingress pueda llegar a ningún destino.
cd /home/labex/project/ingress-routing
cat <<'EOF' > backends.yaml
apiVersion: v1
kind: Namespace
metadata: {name: practice-ingress}
---
apiVersion: apps/v1
kind: Deployment
metadata: {name: storefront, namespace: practice-ingress}
spec:
replicas: 1
selector: {matchLabels: {app: storefront}}
template:
metadata: {labels: {app: storefront}}
spec:
containers: [{name: web, image: nginx:1.27-alpine, imagePullPolicy: IfNotPresent, ports: [{name: http, containerPort: 80}]}]
---
apiVersion: v1
kind: Service
metadata: {name: storefront, namespace: practice-ingress}
spec: {selector: {app: storefront}, ports: [{name: http, port: 80, targetPort: http}]}
---
apiVersion: apps/v1
kind: Deployment
metadata: {name: reports, namespace: practice-ingress}
spec:
replicas: 1
selector: {matchLabels: {app: reports}}
template:
metadata: {labels: {app: reports}}
spec:
containers: [{name: web, image: httpd:2.4-alpine, imagePullPolicy: IfNotPresent, ports: [{name: http, containerPort: 80}]}]
---
apiVersion: v1
kind: Service
metadata: {name: reports, namespace: practice-ingress}
spec: {selector: {app: reports}, ports: [{name: http, port: 80, targetPort: http}]}
EOF
Aplica los cinco documentos juntos y espera después a que ambos Deployments estén listos. Esperarlos por separado permite identificar con claridad qué backend falló si hay algún problema con una imagen o un selector:
kubectl apply -f backends.yaml
kubectl rollout status deployment/storefront -n practice-ingress --timeout=60s
kubectl rollout status deployment/reports -n practice-ingress --timeout=60s
Ingress solo enruta hacia Services, por lo que cada backend debe tener endpoints listos previamente.
Confirma explícitamente este requisito antes de crear las reglas de enrutamiento:
kubectl get services,endpointslices -n practice-ingress
Cada Service debería tener un EndpointSlice correspondiente con una dirección lista.
service/reports ClusterIP ... 80/TCP
service/storefront ClusterIP ... 80/TCP
endpointslice.../reports-... IPv4 80 10.244.104...
endpointslice.../storefront-... IPv4 80 10.244.104...
Los sufijos generados y las direcciones serán diferentes, pero cada nombre de Service debería tener un EndpointSlice no vacío. Ingress no puede reparar un Service sin backend; esta comprobación demuestra deliberadamente primero que la capa inferior funciona.
Añadir enrutamiento basado en host
En este paso, enrutarás store.practice.test al Service storefront.
Una regla de Ingress toma tres decisiones de enrutamiento: host, path y el puerto del Service de backend. ingressClassName: nginx selecciona el controlador. La anotación de reescritura es específica del controlador; cambia la ruta de la solicitud enviada al backend a /, que ambos servidores de demostración pueden atender.
cd /home/labex/project/ingress-routing
cat <<'EOF' > ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: practice-routing
namespace: practice-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx
rules:
- host: store.practice.test
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: storefront
port: {name: http}
EOF
Aplica la regla y utiliza describe para consultar cómo la interpreta el controlador, incluido el endpoint de backend resuelto:
kubectl apply -f ingress.yaml
kubectl describe ingress practice-routing -n practice-ingress
pathType: Prefix coincide con / y sus subrutas. La anotación de reescritura envía la solicitud seleccionada a / en el backend, donde el servidor web de demostración tiene una página disponible. El host es una clave de enrutamiento HTTP; no necesita DNS público para esta prueba local.
describe debería resolver la regla hasta llegar a una dirección de Pod:
Rules:
Host Path Backends
store.practice.test
/ storefront:http (10.244.104...:80)
Que el campo Address de nivel superior esté vacío inmediatamente después de la creación no indica un fallo en esta configuración local. Lo importante es que el backend storefront:http y su dirección de Pod estén resueltos.
Añadir enrutamiento por ruta y probar las solicitudes
En este paso, añadirás el enrutamiento /reports y probarás ambas reglas a través del punto de entrada del nodo.
La ruta del parche JSON termina en /-. En un array, - significa añadir un elemento nuevo en lugar de reemplazar la ruta / existente. El nuevo backend apunta al Service reports mediante su puerto http con nombre.
Ejecuta este parche de adición una sola vez. A diferencia de kubectl apply, añadir elementos en /- no es idempotente: si lo repites, se añadirá otro elemento /reports idéntico en lugar de reconocerse el anterior.
Las dos asignaciones siguientes descubren el endpoint en lugar de escribirlo directamente. minikube ip -p labex-v135 devuelve la IP del nodo para el perfil de Minikube indicado, y la sustitución de comandos $(...) guarda en una variable de shell la salida de cada comando. La consulta JSONPath selecciona el puerto del Service llamado http y extrae su NodePort.
kubectl patch ingress practice-routing -n practice-ingress --type='json' -p='[{"op":"add","path":"/spec/rules/0/http/paths/-","value":{"path":"/reports","pathType":"Prefix","backend":{"service":{"name":"reports","port":{"name":"http"}}}}}]'
NODE_IP=$(minikube ip -p labex-v135)
HTTP_NODE_PORT=$(kubectl get service ingress-nginx-controller -n ingress-nginx -o jsonpath='{.spec.ports[?(@.name=="http")].nodePort}')
echo "Ingress endpoint: ${NODE_IP}:${HTTP_NODE_PORT}"
Las dos variables evitan incluir direcciones específicas del entorno en las instrucciones. Ahora envía solicitudes con la cabecera de host necesaria para que la regla coincida. En cada comando curl, -s oculta el indicador de progreso, --retry 5 reintenta los fallos transitorios, --retry-connrefused también reintenta cuando la conexión se rechaza inicialmente y --retry-delay 2 espera dos segundos entre intentos. -H proporciona la cabecera HTTP Host, y la tubería envía la respuesta a grep para mostrar únicamente el texto identificativo de la página.
curl -s --retry 5 --retry-connrefused --retry-delay 2 -H 'Host: store.practice.test' "http://${NODE_IP}:${HTTP_NODE_PORT}/" | grep 'Welcome to nginx'
curl -s --retry 5 --retry-connrefused --retry-delay 2 -H 'Host: store.practice.test' "http://${NODE_IP}:${HTTP_NODE_PORT}/reports" | grep 'It works'
Las dos respuestas demuestran que un único punto de entrada puede enrutar hacia distintos Services.
La primera respuesta procede de NGINX y la segunda de Apache httpd. El texto diferenciado de las páginas es una prueba deliberada de que la regla de ruta seleccionó un backend distinto, no simplemente de que el proxy devolvió el código HTTP 200.
Las líneas esperadas son:
<title>Welcome to nginx!</title>
<h1>Welcome to nginx!</h1>
<title>It works! Apache httpd</title>
<p>It works!</p>
Este resultado también explica por qué es importante la cabecera Host personalizada: ambas solicitudes llegan a la misma IP del nodo y al mismo NodePort; son el host y la ruta los que seleccionan la regla y el backend.
Resumen
Has reutilizado el controlador ingress-nginx preparado, conectado las reglas de Ingress con Services que tienen endpoints listos y probado el enrutamiento basado en host y ruta a través de un único punto de entrada.


