Veraltete API-Manifeste aktualisieren

KubernetesBeginner
Jetzt üben

Einführung

Kubernetes-APIs entwickeln sich ständig weiter. Ein Manifest, das in einem älteren Cluster funktionierte, kann in einem neueren Cluster fehlschlagen, weil eine API-Version entfernt wurde oder Felder in eine andere Struktur verschoben wurden. In der CKAD-Praxis ist dies meist eine alltägliche Wartungsaufgabe: Fehlermeldung lesen, die aktuelle API identifizieren, das Manifest aktualisieren und die Akzeptanz der neuen Version verifizieren.

In diesem Lab migrieren Sie ein altes Ingress-Manifest von networking.k8s.io/v1beta1 auf networking.k8s.io/v1. Sie erstellen zunächst einen Service, auf den sich der Ingress beziehen kann, beobachten dann das Scheitern des alten Manifests, nutzen kubectl-Discovery-Befehle zur Untersuchung der aktuellen API, schreiben das Manifest um und wenden den korrigierten Ingress an.

Einen Service-Bezug vorbereiten

In diesem Schritt bereiten Sie einen sauberen Namespace und einen einfachen Service vor. Sowohl das alte als auch das neue Ingress-Manifest werden auf diesen Service verweisen, sodass sich die Migration auf die API-Struktur konzentriert und nicht auf die Pod-Bereitschaft oder das Traffic-Routing.

Beginnen Sie in /home/labex/project:

mkdir -p /home/labex/project
cd /home/labex/project

Überprüfen Sie, ob der Kubernetes-API-Server erreichbar ist. Falls die VM gerade erst gestartet wurde und der Node noch nicht bereit ist, warten Sie einige Sekunden und führen Sie den Befehl erneut aus.

kubectl get nodes --request-timeout=5s

Die erwartete Ausgabe enthält:

NAME         STATUS   ROLES           AGE   VERSION
labex-v135   Ready    control-plane   ...   v1.35...

Erstellen Sie einen Namespace namens ckad-prep-api-migration und legen Sie ihn als aktuellen Namespace fest:

kubectl create namespace ckad-prep-api-migration
kubectl config set-context --current --namespace=ckad-prep-api-migration

Erstellen Sie einen ClusterIP-Service namens app-web. Die Option --tcp=80:80 bedeutet, dass der Service auf Port 80 lauscht und an den Zielport 80 weiterleiten würde, falls passende Pods existieren. Für dieses Migrations-Lab reicht das Service-Objekt aus, da Sie die Ingress-API-Felder validieren und nicht den HTTP-Traffic.

kubectl create service clusterip app-web --tcp=80:80

Bestätigen Sie, dass der Service existiert:

kubectl get service app-web

Die erwartete Ausgabe enthält:

NAME      TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
app-web   ClusterIP   ...          <none>        80/TCP    ...

Das Scheitern eines veralteten Manifests beobachten

In diesem Schritt erstellen Sie ein altes Ingress-Manifest und lassen zu, dass der aktuelle Cluster es ablehnt. Dies ist eine nützliche Übung, da der erste Hinweis bei einer Migrationsaufgabe oft die Fehlermeldung des API-Servers ist.

Erstellen Sie 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

Lesen Sie den Anfang der Datei. Das Feld apiVersion teilt Kubernetes mit, welche API-Gruppe und -Version dieses Objekt verarbeiten soll.

sed -n '1,20p' old-ingress.yaml

Die erwartete Ausgabe enthält:

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
...
          serviceName: app-web
          servicePort: 80

Bitten Sie den API-Server, das Manifest zu validieren, ohne es zu erstellen. --dry-run=server sendet das Objekt zur Validierung an den API-Server, während || true das Tutorial fortsetzt, da dieser Fehler erwartet wird.

kubectl apply --dry-run=server -f old-ingress.yaml || true

Die erwartete Ausgabe enthält einen Fehler ähnlich diesem:

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"

Der entscheidende Hinweis ist no matches for kind "Ingress" in version "networking.k8s.io/v1beta1". Das bedeutet, dass der aktuelle Cluster diese API-Version nicht mehr unterstützt.

Die aktuelle Ingress-API-Struktur entdecken

In diesem Schritt untersuchen Sie die aktuelle Ingress-API, bevor Sie die Datei umschreiben. Dies ist der Teil, der die Migrationsarbeit diszipliniert hält: Raten Sie nicht bei den neuen Feldern, wenn der Cluster Ihnen die akzeptierte Struktur zeigen kann.

Listen Sie die verfügbare Ingress-Ressource auf:

kubectl api-resources | grep -i '^ingresses'

Die erwartete Ausgabe enthält:

ingresses   ing   networking.k8s.io/v1   true   Ingress

Verwenden Sie kubectl explain, um das aktuelle Backend-Service-Feld zu untersuchen. Der Pfad ist lang, da das Service-Backend unter spec.rules[].http.paths[].backend.service verschachtelt ist.

kubectl explain ingress.spec.rules.http.paths.backend.service --recursive | sed -n '1,80p'

Die erwartete Ausgabe enthält:

GROUP:      networking.k8s.io
KIND:       Ingress
VERSION:    v1

FIELD: service <IngressServiceBackend>
...
  name        <string> -required-
  port        <ServiceBackendPort> -required-

Erstellen Sie nun die migrierte current-ingress.yaml. Das neue Manifest verwendet networking.k8s.io/v1, fügt pathType hinzu und ersetzt serviceName sowie servicePort durch die verschachtelten Felder service.name und 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

Validieren Sie das migrierte Manifest mit einem serverseitigen Dry-Run:

kubectl apply --dry-run=server -f current-ingress.yaml

Erwartete Ausgabe:

ingress.networking.k8s.io/app-web created (server dry run)

Den migrierten Ingress anwenden und überprüfen

In diesem Schritt erstellen Sie den migrierten Ingress und überprüfen die von Kubernetes gespeicherten Felder. Das Anwenden der Ressource ist der endgültige Beweis dafür, dass das Manifest nun mit dem aktuellen API-Server übereinstimmt.

Wenden Sie das migrierte Manifest an:

kubectl apply -f current-ingress.yaml

Erwartete Ausgabe:

ingress.networking.k8s.io/app-web created

Listen Sie den Ingress auf:

kubectl get ingress app-web

Die erwartete Ausgabe enthält:

NAME      CLASS   HOSTS               ADDRESS   PORTS   AGE
app-web   ...     app.example.local    ...       80      ...

Untersuchen Sie die migrierten Backend-Felder direkt aus dem gespeicherten Objekt:

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"}'

Erwartete Ausgabe:

networking.k8s.io/v1 Prefix app-web:80

Diese Ausgabe beweist drei Dinge gleichzeitig: Das Objekt verwendet die aktuelle API-Version, der Pfad hat einen expliziten pathType, und das Backend verwendet die verschachtelte Service-Referenz, die für networking.k8s.io/v1 erforderlich ist.

Zusammenfassung

Sie haben einen praktischen API-Migrations-Workflow geübt. Sie haben ein altes networking.k8s.io/v1beta1 Ingress-Manifest erstellt, mittels serverseitigem Dry-Run bestätigt, dass der aktuelle Cluster es ablehnt, die bereitgestellte networking.k8s.io/v1 API untersucht, die Backend-Felder mit pathType und der verschachtelten Service-Referenz umgeschrieben und schließlich den migrierten Ingress angewendet und überprüft.