Actualizar manifiestos de API obsoletos

KubernetesBeginner
Practicar Ahora

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.