Einführung
In den vorangegangenen Deployment-Übungen wurden Images verwendet, die bereits in einer Registry oder im Cluster-Cache vorhanden waren. Anwendungsentwickler müssen jedoch auch den lokalen Image-Workflow beherrschen: ein Image aus Anwendungsdateien erstellen, dieses Image für den Kubernetes-Node verfügbar machen und ein Deployment anweisen, es zu verwenden.
In dieser Übung erstellen Sie lokal mit Minikube ein kleines Webanwendungs-Image, stellen es mit imagePullPolicy: Never bereit und erstellen anschließend die Anwendung als zweites Image-Tag neu, um ein Rolling Update durchzuführen. Dies spiegelt eine typische Aufgabe im CKAD-Stil wider: die Verbindung zwischen dem Anwendungs-Artefakt und der Kubernetes-Workload, die es ausführt, herzustellen.
Arbeitsumgebung für lokale Images vorbereiten
In diesem Schritt bereiten Sie einen sauberen Namespace vor und stellen sicher, dass der Pfad für den Image-Build verfügbar ist.
Beginnen Sie im Verzeichnis /home/labex/project. In diesem Verzeichnis werden Sie die Anwendungsdateien, die Build-Dateien für das Image und die Kubernetes-Manifeste erstellen.
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 sieht in etwa so aus:
NAME STATUS ROLES AGE VERSION
labex-v135 Ready control-plane ... v1.35...
Warten Sie, bis der Pod für das Cluster-Netzwerk den Status "Ready" erreicht hat. Da die Anwendung über einen Service getestet wird, muss die Netzwerkkonfiguration einwandfrei funktionieren.
kubectl wait --namespace kube-system --for=condition=Ready pod -l k8s-app=calico-node --timeout=120s
Erwartete Ausgabe:
pod/calico-node-... condition met
Erstellen Sie einen Namespace namens ckad-prep-local-image und legen Sie diesen als aktuellen Namespace fest:
kubectl create namespace ckad-prep-local-image
kubectl config set-context --current --namespace=ckad-prep-local-image
Bestätigen Sie den Namespace und überprüfen Sie den Minikube-Image-Befehl. Der Befehl minikube image build erstellt ein Image direkt für das Minikube-Profil, sodass Pods es verwenden können, ohne dass es in eine Registry hochgeladen werden muss.
kubectl config view --minify --output 'jsonpath={..namespace}'; echo
minikube image build --help | sed -n '1,4p'
Die erwartete Ausgabe enthält:
ckad-prep-local-image
Build a container image...
Erstes lokales Image erstellen
In diesem Schritt erstellen Sie eine kleine Webanwendung und bauen diese als local-message-app:v1.
Das Image verwendet BusyBox httpd, um eine statische Datei bereitzustellen. Der Inhalt der Datei entspricht der sichtbaren Anwendungsversion, sodass Sie später nachweisen können, welches Image-Tag in Kubernetes ausgeführt wird.
Erstellen Sie das Anwendungsverzeichnis und die erste Webseite:
mkdir -p local-message-app/www
cat > local-message-app/www/index.html <<'EOF'
local-image-v1
EOF
Erstellen Sie ein Dockerfile. Die COPY-Anweisung fügt Ihre lokale www/index.html-Datei in das Image ein, und CMD startet den BusyBox-Webserver auf Port 8080, sobald ein Container aus dem Image gestartet wird.
cat > local-message-app/Dockerfile <<'EOF'
FROM busybox:1.36
COPY www/index.html /www/index.html
EXPOSE 8080
CMD ["httpd", "-f", "-p", "8080", "-h", "/www"]
EOF
Erstellen Sie das Image für das aktive Minikube-Profil. Die Option -t weist dem Image ein lokales Tag zu, und der letzte Pfad ist das Verzeichnis des Build-Kontexts.
minikube image build --profile labex-v135 -t local-message-app:v1 ./local-message-app
Die erwartete Ausgabe enthält:
naming to docker.io/library/local-message-app:v1 done
Listen Sie die Minikube bekannten Images auf und suchen Sie nach Ihrem neuen Tag:
minikube image ls --profile labex-v135 | grep local-message-app
Erwartete Ausgabe:
docker.io/library/local-message-app:v1
Lokales Image bereitstellen
In diesem Schritt führen Sie das lokale Image in Kubernetes aus.
Da local-message-app:v1 nicht in eine externe Registry hochgeladen wurde, verwendet das Deployment imagePullPolicy: Never. Dies weist den Kubelet an, ein Image zu verwenden, das bereits auf dem Node vorhanden ist, anstatt zu versuchen, es aus dem Netzwerk zu laden.
Erstellen Sie local-image-app.yaml:
cat > local-image-app.yaml <<'EOF'
apiVersion: apps/v1
kind: Deployment
metadata:
name: local-message-app
spec:
replicas: 2
selector:
matchLabels:
app: local-message-app
template:
metadata:
labels:
app: local-message-app
spec:
terminationGracePeriodSeconds: 0
containers:
- name: web
image: local-message-app:v1
imagePullPolicy: Never
ports:
- containerPort: 8080
readinessProbe:
httpGet:
path: /
port: 8080
initialDelaySeconds: 1
periodSeconds: 2
---
apiVersion: v1
kind: Service
metadata:
name: local-message-app
spec:
selector:
app: local-message-app
ports:
- port: 80
targetPort: 8080
EOF
Wenden Sie das Manifest an und warten Sie auf das Deployment:
kubectl apply -f local-image-app.yaml
kubectl rollout status deployment/local-message-app --timeout=120s
Die erwartete Ausgabe enthält:
deployment.apps/local-message-app created
service/local-message-app created
deployment "local-message-app" successfully rolled out
Erstellen Sie einen Client-Pod und testen Sie den Service:
kubectl run image-client --image=busybox:1.36 --restart=Never --command -- sleep 3600
kubectl wait --for=condition=Ready pod/image-client --timeout=120s
kubectl exec image-client -- wget -qO- http://local-message-app
Erwartete Ausgabe:
local-image-v1
Neues lokales Image erstellen und ausrollen
In diesem Schritt erstellen Sie die Anwendung als zweites Image-Tag neu und führen ein Rollout des Deployments auf dieses Tag durch.
Das Ändern einer Datei auf der Festplatte ändert nicht automatisch ein laufendes Image. Sie müssen ein neues Image-Tag erstellen und das Deployment aktualisieren, damit Kubernetes neue Pods basierend auf diesem Tag startet. Dies macht die Versionsänderung nachvollziehbar und vermeidet die Abhängigkeit von veränderbaren lokalen Image-Inhalten.
Ersetzen Sie den Inhalt der Webseite durch Version zwei:
cat > local-message-app/www/index.html <<'EOF'
local-image-v2
EOF
Erstellen Sie das zweite Image-Tag:
minikube image build --profile labex-v135 -t local-message-app:v2 ./local-message-app
Die erwartete Ausgabe enthält:
naming to docker.io/library/local-message-app:v2 done
Aktualisieren Sie das Deployment-Image und warten Sie auf das Rollout:
kubectl set image deployment/local-message-app web=local-message-app:v2
kubectl rollout status deployment/local-message-app --timeout=120s
Die erwartete Ausgabe enthält:
deployment.apps/local-message-app image updated
deployment "local-message-app" successfully rolled out
Überprüfen Sie sowohl das Image-Tag als auch die Antwort der Anwendung:
kubectl get deployment local-message-app -o jsonpath='{.spec.template.spec.containers[0].image}'; echo
kubectl exec image-client -- wget -qO- http://local-message-app
Erwartete Ausgabe:
local-message-app:v2
local-image-v2
Zusammenfassung
Sie haben ein kleines Anwendungs-Image für das Minikube-Profil erstellt, es mit imagePullPolicy: Never bereitgestellt, über einen Kubernetes-Service getestet, die Anwendung anschließend als neues Image-Tag neu erstellt und das Deployment aktualisiert. Der entscheidende Workflow besteht darin, das Image für den Node verfügbar zu machen, bevor Pods es ausführen können.



