Hinzufügen eines Sidecar-Containers

KubernetesBeginner
Jetzt üben

Einführung

Ein Sidecar-Container läuft im selben Pod wie ein Anwendungscontainer und unterstützt die Anwendung während ihrer Laufzeit. Dies unterscheidet ihn von einem Init-Container, der abgeschlossen sein muss, bevor die Anwendung startet. Sidecars werden häufig für das Versenden von Protokollen (Log Shipping), als Proxy, zur Synchronisierung oder für andere Hilfsfunktionen verwendet, die den Lebenszyklus des Pods teilen sollten.

In diesem Lab erstellen Sie einen Multi-Container-Pod mit einem Anwendungscontainer, der Protokollzeilen in ein gemeinsam genutztes emptyDir-Volume schreibt, sowie einen Sidecar-Container, der diese Datei überwacht. Sie werden beide Container untersuchen, die Sidecar-Protokolle lesen und anschließend dasselbe Sidecar-Muster in eine Deployment-Vorlage übertragen.

Vorbereiten eines Sidecar-Namespaces

In diesem Schritt bereiten Sie einen sauberen Namespace für die Sidecar-Übungen vor.

Beginnen Sie im Verzeichnis /home/labex/project. Sie werden in diesem Verzeichnis ein Pod-Manifest und ein Deployment-Manifest 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 Knoten 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 Cluster-Netzwerk-Pod bereit ist, bevor Sie Workloads erstellen.

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-sidecar:

kubectl create namespace ckad-prep-sidecar

Legen Sie diesen Namespace als aktuellen Kontext-Namespace fest:

kubectl config set-context --current --namespace=ckad-prep-sidecar

Bestätigen Sie den aktuellen Namespace:

kubectl config view --minify --output 'jsonpath={..namespace}'; echo

Erwartete Ausgabe:

ckad-prep-sidecar

Erstellen eines Multi-Container-Pods

In diesem Schritt erstellen Sie einen Pod mit einem Anwendungscontainer und einem Sidecar-Container.

Beide Container mounten dasselbe emptyDir-Volume unter /var/log/shared. Der Anwendungscontainer schreibt Protokollzeilen in /var/log/shared/app.log. Der Sidecar-Container läuft gleichzeitig und verwendet tail -f, um diese Datei zu streamen. Der Befehl touch erstellt die Datei, bevor tail -f startet, sodass der Sidecar sicher warten kann, selbst wenn die Anwendung noch keine Zeile geschrieben hat.

Erstellen Sie sidecar-pod.yaml:

cat > sidecar-pod.yaml <<'EOF'
apiVersion: v1
kind: Pod
metadata:
  name: sidecar-demo
  labels:
    app: sidecar-demo
spec:
  terminationGracePeriodSeconds: 0
  volumes:
  - name: shared-logs
    emptyDir: {}
  containers:
  - name: app
    image: busybox:1.36
    command:
    - /bin/sh
    - -c
    - 'i=1; while true; do echo "app-line-${i}" >> /var/log/shared/app.log; i=$((i+1)); sleep 2; done'
    volumeMounts:
    - name: shared-logs
      mountPath: /var/log/shared
  - name: log-sidecar
    image: busybox:1.36
    command:
    - /bin/sh
    - -c
    - 'touch /var/log/shared/app.log; tail -n +1 -f /var/log/shared/app.log'
    volumeMounts:
    - name: shared-logs
      mountPath: /var/log/shared
EOF

Wenden Sie das Manifest an:

kubectl apply -f sidecar-pod.yaml

Erwartete Ausgabe:

pod/sidecar-demo created

Warten Sie, bis der Pod bereit ist. Ein Multi-Container-Pod ist erst dann bereit, wenn alle regulären Container bereit sind.

kubectl wait --for=condition=Ready pod/sidecar-demo --timeout=120s

Erwartete Ausgabe:

pod/sidecar-demo condition met

Listen Sie die Containernamen im Pod auf:

kubectl get pod sidecar-demo -o 'jsonpath={.spec.containers[*].name}{"\n"}'

Erwartete Ausgabe:

app log-sidecar

Überprüfen der Sidecar-Zusammenarbeit

In diesem Schritt bestätigen Sie, dass beide Container laufen und der Sidecar die Protokolldatei der Anwendung streamt.

Überprüfen Sie zunächst die Bereitschaft der Container. Die Ausgabe zeigt jeden Containernamen und dessen Status an.

kubectl get pod sidecar-demo -o 'jsonpath={range .status.containerStatuses[*]}{.name}{" "}{.ready}{"\n"}{end}'

Die erwartete Ausgabe enthält:

app true
log-sidecar true

Lesen Sie die Protokolle des Anwendungscontainers. Die Anwendung schreibt nur beim Start des Shell-Befehls etwas in die Standardausgabe (stdout); die wiederholten Zeilen landen in der gemeinsam genutzten Datei.

kubectl logs sidecar-demo -c app --tail=5

Der Anwendungscontainer gibt möglicherweise keine wiederholten Zeilen an stdout aus. Der entscheidende Nachweis befindet sich in der gemeinsam genutzten Datei und den Sidecar-Protokollen.

Lesen Sie die gemeinsam genutzte Datei über den Anwendungscontainer:

kubectl exec sidecar-demo -c app -- sh -c 'tail -n 3 /var/log/shared/app.log'

Die erwartete Ausgabe enthält die Protokollzeilen der Anwendung:

app-line-...
app-line-...
app-line-...

Lesen Sie nun die Sidecar-Protokolle. Da der Sidecar dieselbe Datei überwacht, sollten seine Protokolle dieselben Zeilen enthalten.

kubectl logs sidecar-demo -c log-sidecar --tail=3

Die erwartete Ausgabe enthält:

app-line-...
app-line-...
app-line-...

Hinzufügen des Sidecar-Musters zu einem Deployment

In diesem Schritt übertragen Sie das Sidecar-Muster in eine Deployment-Vorlage.

Einzelne Pods sind nützlich zum Lernen, aber Anwendungen laufen normalerweise über Controller. Ein Deployment kann Ersatz-Pods erstellen, und jeder Ersatz-Pod enthält sowohl den Anwendungscontainer als auch den Sidecar-Container aus der Vorlage.

Erstellen Sie sidecar-deployment.yaml:

cat > sidecar-deployment.yaml <<'EOF'
apiVersion: apps/v1
kind: Deployment
metadata:
  name: sidecar-worker
spec:
  replicas: 1
  selector:
    matchLabels:
      app: sidecar-worker
  template:
    metadata:
      labels:
        app: sidecar-worker
    spec:
      terminationGracePeriodSeconds: 0
      volumes:
      - name: shared-logs
        emptyDir: {}
      containers:
      - name: app
        image: busybox:1.36
        command:
        - /bin/sh
        - -c
        - 'i=1; while true; do echo "worker-line-${i}" >> /var/log/shared/worker.log; i=$((i+1)); sleep 2; done'
        volumeMounts:
        - name: shared-logs
          mountPath: /var/log/shared
      - name: log-sidecar
        image: busybox:1.36
        command:
        - /bin/sh
        - -c
        - 'touch /var/log/shared/worker.log; tail -n +1 -f /var/log/shared/worker.log'
        volumeMounts:
        - name: shared-logs
          mountPath: /var/log/shared
EOF

Wenden Sie das Deployment an:

kubectl apply -f sidecar-deployment.yaml

Erwartete Ausgabe:

deployment.apps/sidecar-worker created

Warten Sie, bis das Deployment verfügbar ist:

kubectl wait --for=condition=Available deployment/sidecar-worker --timeout=120s

Erwartete Ausgabe:

deployment.apps/sidecar-worker condition met

Suchen Sie den vom Deployment erstellten Pod:

worker_pod="$(kubectl get pods -l app=sidecar-worker -o 'jsonpath={.items[0].metadata.name}')"
echo "$worker_pod"

Die erwartete Ausgabe zeigt einen generierten Pod-Namen:

sidecar-worker-...

Lesen Sie die Sidecar-Protokolle des vom Deployment erstellten Pods:

kubectl logs "$worker_pod" -c log-sidecar --tail=3

Die erwartete Ausgabe enthält:

worker-line-...
worker-line-...
worker-line-...

Zusammenfassung

Sie haben einen Multi-Container-Pod mit einem Anwendungscontainer und einem Sidecar-Container erstellt, ein emptyDir-Volume zur gemeinsamen Nutzung einer Protokolldatei verwendet, bestätigt, dass beide Container zusammen laufen, und dasselbe Sidecar-Muster in eine Deployment-Vorlage übertragen. Sie wissen nun, wann ein Sidecar sinnvoll ist: Er unterstützt die Anwendung, während diese läuft.