Introducción
Las API de Kubernetes evolucionan. Un manifiesto que funcionaba en un clúster antiguo puede fallar en uno más reciente debido a que una versión de la API ha sido eliminada o porque los campos han cambiado de estructura. En el trabajo para la certificación CKAD, esto suele presentarse como una tarea de mantenimiento práctica: leer el error, identificar la API actual, actualizar el manifiesto y verificar que la nueva versión sea aceptada.
En este laboratorio, migrará un manifiesto de Ingress antiguo de networking.k8s.io/v1beta1 a networking.k8s.io/v1. Primero creará un Service al que el Ingress hará referencia, luego observará cómo falla el manifiesto antiguo, utilizará los comandos de descubrimiento de kubectl para inspeccionar la API actual, reescribirá el manifiesto y aplicará el Ingress corregido.
Preparar una referencia de Service
En este paso, preparará un espacio de nombres (namespace) limpio y un Service sencillo. Tanto el manifiesto de Ingress antiguo como el nuevo apuntarán a este Service, de modo que la migración se centre en la estructura de la API y no en la disponibilidad de los Pods o el enrutamiento de tráfico.
Comience en /home/labex/project:
mkdir -p /home/labex/project
cd /home/labex/project
Compruebe que el servidor de la API de Kubernetes sea accesible. Si la máquina virtual acaba de iniciarse y el nodo aún no está listo, espere unos segundos y vuelva a ejecutar el comando.
kubectl get nodes --request-timeout=5s
La salida esperada incluye:
NAME STATUS ROLES AGE VERSION
labex-v135 Ready control-plane ... v1.35...
Cree un espacio de nombres llamado ckad-prep-api-migration y establézcalo como el espacio de nombres actual:
kubectl create namespace ckad-prep-api-migration
kubectl config set-context --current --namespace=ckad-prep-api-migration
Cree un Service de tipo ClusterIP llamado app-web. La opción --tcp=80:80 significa que el Service escucha en el puerto 80 y reenviaría al puerto de destino 80 si existieran Pods coincidentes. Para este laboratorio de migración, el objeto Service por sí solo es suficiente, ya que está validando los campos de la API de Ingress, no el tráfico HTTP.
kubectl create service clusterip app-web --tcp=80:80
Confirme que el Service existe:
kubectl get service app-web
La salida esperada incluye:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
app-web ClusterIP ... <none> 80/TCP ...
Observar el fallo de un manifiesto obsoleto
En este paso, creará un manifiesto de Ingress antiguo y dejará que el clúster actual lo rechace. Esta es una práctica útil, ya que la primera pista en una tarea de migración suele ser el mensaje de error del servidor de la API.
Cree old-ingress.yaml:
cat > old-ingress.yaml <<'EOF'
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: app-web
spec:
rules:
- host: app.example.local
http:
paths:
- path: /
backend:
serviceName: app-web
servicePort: 80
EOF
Lea la parte superior del archivo. El campo apiVersion le indica a Kubernetes qué grupo y versión de API deben gestionar este objeto.
sed -n '1,20p' old-ingress.yaml
La salida esperada incluye:
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
...
serviceName: app-web
servicePort: 80
Solicite al servidor de la API que valide el manifiesto sin crearlo. --dry-run=server envía el objeto al servidor de la API para su validación, mientras que || true permite que el tutorial continúe, ya que este fallo es esperado.
kubectl apply --dry-run=server -f old-ingress.yaml || true
La salida esperada incluye un error similar a:
error: resource mapping not found for name: "app-web" namespace: "" from "old-ingress.yaml": no matches for kind "Ingress" in version "networking.k8s.io/v1beta1"
La evidencia importante es no matches for kind "Ingress" in version "networking.k8s.io/v1beta1". Esto significa que el clúster actual ya no sirve esta versión de la API.
Descubrir la estructura actual de la API de Ingress
En este paso, inspeccionará la API de Ingress actual antes de reescribir el archivo. Esta es la parte que mantiene el trabajo de migración disciplinado: no adivine los nuevos campos cuando el clúster puede mostrarle la estructura aceptada.
Enumere el recurso Ingress servido:
kubectl api-resources | grep -i '^ingresses'
La salida esperada incluye:
ingresses ing networking.k8s.io/v1 true Ingress
Utilice kubectl explain para inspeccionar el campo del backend service actual. La ruta es larga porque el backend del Service está anidado bajo spec.rules[].http.paths[].backend.service.
kubectl explain ingress.spec.rules.http.paths.backend.service --recursive | sed -n '1,80p'
La salida esperada incluye:
GROUP: networking.k8s.io
KIND: Ingress
VERSION: v1
FIELD: service <IngressServiceBackend>
...
name <string> -required-
port <ServiceBackendPort> -required-
Ahora cree el archivo current-ingress.yaml migrado. El nuevo manifiesto utiliza networking.k8s.io/v1, añade pathType y reemplaza serviceName y servicePort con los campos anidados service.name y service.port.number.
cat > current-ingress.yaml <<'EOF'
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: app-web
spec:
rules:
- host: app.example.local
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: app-web
port:
number: 80
EOF
Valide el manifiesto migrado con una prueba de ejecución en el servidor (dry run):
kubectl apply --dry-run=server -f current-ingress.yaml
Salida esperada:
ingress.networking.k8s.io/app-web created (server dry run)
Aplicar e inspeccionar el Ingress migrado
En este paso, creará el Ingress migrado e inspeccionará los campos almacenados por Kubernetes. Aplicar el recurso es la prueba final de que el manifiesto ahora coincide con el servidor de la API actual.
Aplique el manifiesto migrado:
kubectl apply -f current-ingress.yaml
Salida esperada:
ingress.networking.k8s.io/app-web created
Enumere el Ingress:
kubectl get ingress app-web
La salida esperada incluye:
NAME CLASS HOSTS ADDRESS PORTS AGE
app-web ... app.example.local ... 80 ...
Inspeccione los campos del backend migrado directamente desde el objeto almacenado:
kubectl get ingress app-web -o jsonpath='{.apiVersion}{" "}{.spec.rules[0].http.paths[0].pathType}{" "}{.spec.rules[0].http.paths[0].backend.service.name}{":"}{.spec.rules[0].http.paths[0].backend.service.port.number}{"\n"}'
Salida esperada:
networking.k8s.io/v1 Prefix app-web:80
Esta salida demuestra tres cosas a la vez: el objeto utiliza la versión actual de la API, la ruta tiene un pathType explícito y el backend utiliza la referencia de Service anidada requerida por networking.k8s.io/v1.
Resumen
Ha practicado un flujo de trabajo práctico de migración de API. Creó un manifiesto de Ingress antiguo de networking.k8s.io/v1beta1, utilizó una prueba de ejecución en el servidor para confirmar que el clúster actual lo rechaza, inspeccionó la API networking.k8s.io/v1 servida, reescribió los campos del backend con pathType y la referencia de Service anidada, y finalmente aplicó e inspeccionó el Ingress migrado.


