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.


