Lokales Anwendungs-Image erstellen und ausführen

DockerBeginner
Jetzt üben

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.