Zum Inhalt

Mehrere Container im Pod nutzen

Ziel

  • initContainer anwenden
  • Sidecars nutzen

Hilfsmittel

  • Versuchen Sie, die unten stehenden Aufgaben mit Hilfe der Folien und der Cheatsheets eigenständig zu lösen.
  • Sollten Sie dabei Probleme haben, finden Sie bei jeder Aufgabe einen ausklappbaren Block, in dem der Lösungsweg beschrieben wird.

Init-Container nutzen

  1. Erstellen Sie eine Datei init.yaml, die die Beschreibung für einen Pod mit dem Namen pod-with-init enthält. Verwenden Sie das nginx-Image wie zuvor.
  2. Der Pod sollte ein persistentes Volume verwenden, so dass die Dateien in /usr/share/nginx/html geaendert werden koennen
  3. Der Pod sollte einen zusätzlichen initContainer enthalten, der:
    • Das gleiche persistente Volume-Setup wie der Container verwendet
    • die folgenden Befehle ausführt:
    • echo „Overriding index.html file...“
    • echo „Hello from $(Hostname)“ | tee /usr/share/nginx/html/index.html
  4. Fügen Sie ein Label exercise: initcontainer zu den Pod-Metadaten hinzu.
  5. Wenden Sie den Pod mit kubectl apply an.
  6. Listen Sie das Ergebnis auf und prüfen Sie es.
Lösung (Klicken Sie auf den Pfeil, falls Sie nicht weiterkommen)
  • Erstellen Sie eine Datei init.yaml mit dem folgenden Inhalt:
    ---
    apiVersion: v1
    kind: Pod
    metadata:
      name: pod-with-init
      labels:
        app: nginx
        exercise: initcontainer
    spec:
      volumes:
      - name: data
        emptyDir: {}
      initContainers:
      - name: init
        image: nginx
        command:
        - bash
        - -c
        args:
        - |
          echo "Overriding index.html file..." && echo "Hello from $(hostname)" | tee /usr/share/nginx/html/index.html
        volumeMounts:
        - mountPath: /usr/share/nginx/html
          name: data
      containers:
      - name: web
        image: nginx
        volumeMounts:
        - mountPath: /usr/share/nginx/html
          name: data
    
  • Wenden Sie den Pod an:
    kubectl apply -f init.yaml
    
  1. Untersuchen Sie die Protokolle des initContainers mit kubectl logs mit der Option -c
  2. Untersuchen Sie den Pod mit kubectl describe
  3. Untersuchen Sie die Abschnitte Init Container und Container und vergleichen Sie die Unterabschnitte State
  4. Untersuchen Sie die Ereignisse, die mit kubectl events oder seinem Äquivalent kubectl get events --sort-by='.metadata.creationTimestamp' passiert sind
  5. Machen Sie sich mit kubectl events vertraut und probieren Sie einige weitere Optionen aus, z.B. kubectl events -o yaml
Lösung (Klicken Sie auf den Pfeil, falls Sie nicht weiterkommen)
  • Logs anschauen:
    $ kubectl logs pod-with-init -c init
    
    Overriding index.html file...
    
  • Pod anschauen:
    $ kubectl describe pod
    
    Name:             pod-with-init
    (...)
    Init Containers:
      init:
        (...)
        Command:
          bash
          -c
        Args:
          echo "Overriding index.html file..." && echo "Hello from $(hostname)" | tee /usr/share/nginx/html/index.html
        State:          Terminated
          Reason:       Completed
          Exit Code:    0
          Started:      Thu, 29 Feb 2024 14:49:45 +0100
          Finished:     Thu, 29 Feb 2024 14:49:45 +0100
        Ready:          True
        Restart Count:  0
        Environment:    <none>
        Mounts:
          /usr/share/nginx/html from data (rw)
    Containers:
      web:
        (...)
        State:          Running
          Started:      Thu, 29 Feb 2024 14:49:47 +0100
        Ready:          True
        Restart Count:  0
        Environment:    <none>
        Mounts:
          /usr/share/nginx/html from data (rw)
    
  • Events anschauen:
    $ kubectl events
    
    LAST SEEN   TYPE     REASON      OBJECT              MESSAGE
    8m9s        Normal   Scheduled   Pod/pod-with-init   Successfully assigned default/pod-with-init to code-0-worker-stgdw-22kll.
    8m9s        Normal   Pulling     Pod/pod-with-init   Pulling image "nginx"
    8m8s        Normal   Pulled      Pod/pod-with-init   Successfully pulled image "nginx" in 1.331s (1.331s including waiting)
    8m8s        Normal   Created     Pod/pod-with-init   Created container init
    8m8s        Normal   Started     Pod/pod-with-init   Started container init
    8m6s        Normal   Pulling     Pod/pod-with-init   Pulling image "nginx"
    8m6s        Normal   Pulled      Pod/pod-with-init   Successfully pulled image "nginx" in 815ms (815ms including waiting)
    8m6s        Normal   Created     Pod/pod-with-init   Created container web
    8m6s        Normal   Started     Pod/pod-with-init   Started container web
    
  1. Führen Sie den Befehl curl localhost innerhalb des Pods mit kubectl exec aus
Lösung (Klicken Sie auf den Pfeil, falls Sie nicht weiterkommen)
  • Führen Sie curl innerhalb des Pods aus:
    $ kubectl exec -it pod-with-init -- curl localhost
    
    Defaulted container "web" out of: web, init (init)
    Hello from pod-with-init
    

Sidecar nutzen

  1. Erstellen Sie eine Datei secret.yaml, die die Beschreibung für ein Secret mit dem Namen db enthält. Das Secret sollte eine Bezeichnung exercise: sidecar haben und die Daten sollten einen Schlüssel mysql-root-password mit dem Wert not-the-secret enthalten.
  2. Wenden Sie das Secret mit kubectl apply an.
  3. Erstellen Sie eine Datei pod.yaml, die die Beschreibung für einen Pod mit dem Namen mysql enthält. Verwenden Sie das mysql:5 Image wie zuvor.
  4. Fügen Sie ein Label exercise: sidecar zu den Metadaten des Pods hinzu.
  5. Der Pod sollte einen Hauptcontainer enthalten, der:
    • eine env-Variable MYSQL_ROOT_PASSWORD enthält, die auf das Secret mysql-root-password zeigt
    • einen Port für den Container öffnetPort 3306
  6. Der Pod sollte auch einen zusätzlichen Container (Sidecar) mit dem Namen metrics enthalten, der Metriken aus der mysql-Datenbank exportiert. Er sollte:
    • das Image prom/mysqld-exporter:v0.15.1 verwenden
    • eine env-Variable MYSQLD_EXPORTER_PASSWORD enthalten, die auf das Secret mysql-root-password zeigt
    • einen Port zum ContainerPort 9104 öffnen.
    • den folgenden Befehl ausführen:
      sh
      -c
      /bin/mysqld_exporter --mysqld.address=mysql:3306 --mysqld.username=root
      
  7. Wenden Sie den Pod mit kubectl apply an.
  8. Erstellen Sie eine Datei service.yaml, die die Beschreibung für einen Service mit dem Namen db enthält. Sie sollte die folgenden TCP-Port-Zuordnungen enthalten:
    - Port: 3306
      targetPort: 3306
    - port: 9104
      targetPort: 9104
    
  9. Wenden Sie den Service mit kubectl apply an.
Lösung (Klicken Sie auf den Pfeil, falls Sie nicht weiterkommen)
  • Erstellen Sie eine Datei secret.yaml mit dem folgenden Inhalt:
    ---
    apiVersion: v1
    kind: Secret
    metadata:
      name: db
      labels:
        exercise: sidecar
    type: Opaque
    stringData:
      mysql-root-password: "not-the-secret"
    
  • Secret anwenden:
    kubectl apply -f secret.yaml
    
  • Erstellen Sie eine Datei pod.yaml mit dem folgenden Inhalt:
    ---
    apiVersion: v1
    kind: Pod
    metadata:
      name: mysql
      labels:
        app: mysql
        exercise: sidecar
    spec:
      containers:
      - name: mysql
        image: mysql:5
        env:
        - name: MYSQL_ROOT_PASSWORD
          valueFrom:
            secretKeyRef:
              name: db
              key: mysql-root-password
        ports:
        - name: mysql
          containerPort: 3306
      - name: metrics
        image: prom/mysqld-exporter:v0.15.1
        env:
        - name: MYSQLD_EXPORTER_PASSWORD
          valueFrom:
            secretKeyRef:
              name: db
              key: mysql-root-password
        command:
        - sh
        - -c
        - /bin/mysqld_exporter --mysqld.address=mysql:3306 --mysqld.username=root
        ports:
        - name: metrics
          containerPort: 9104
    
  • Pod anwenden:
    kubectl apply -f pod.yaml
    
  • Erstellen Sie eine Datei service.yaml mit dem folgenden Inhalt:
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: db
      labels:
        exercise: sidecar
    spec:
      selector:
        app: mysql
      ports:
      - name: mysql
        protocol: TCP
        port: 3306
        targetPort: 3306
      - name: metrics
        protocol: TCP
        port: 9104
        targetPort: 9104
    
  1. Untersuchen Sie die Container des Pods mit kubectl describe
  2. Untersuchen Sie die Logs der beiden Container des Pods mit kubectl logs mit der Option -c für jeden Container
  3. Verwenden Sie curl, um die Metriken vom mysqld_exporter abzufragen
Lösung (Klicken Sie auf den Pfeil, falls Sie nicht weiterkommen)
  • Pod untersuchen:
    $ kubectl describe pod mysql
    
    Name:             mysql
    (...)
    Containers:
      mysql:
        Image:          mysql:5
        Port:           3306/TCP
        State:          Running
          Started:      Thu, 28 Mar 2024 15:19:19 +0100
        (...)
    (...)
      metrics:
        Image:         prom/mysqld-exporter:v0.15.1
        Port:          9104/TCP
        Command:
          sh
          -c
          /bin/mysqld_exporter --mysqld.address=mysql:3306 --mysqld.username=root
        State:          Running
          Started:      Thu, 28 Mar 2024 15:19:19 +0100
        (...)
    
  • mysql Containerlogs anzeigen:
    $ kubectl logs pods/mysql -c mysql
    
    2024-03-28T14:19:25.812799Z 0 [Note] mysqld (mysqld 5.7.44) starting as process 1 ...
    (...)
    2024-03-28T14:19:25.930134Z 0 [Note] mysqld: ready for connections.
    Version: '5.7.44'  socket: '/var/run/mysqld/mysqld.sock'  port: 3306  MySQL Community Server (GPL)
    
  • metrics Containerlogs anzeigen:
    $ kubectl logs pods/mysql -c metrics
    
    ts=2024-03-28T14:19:19.300Z caller=mysqld_exporter.go:220 level=info msg="Starting mysqld_exporter" version="(version=0.15.1, branch=HEAD, revision=cc349684494b5038ec5a52233bdca9eb9291e6f2)"
    (...)
    ts=2024-03-28T14:19:19.301Z caller=tls_config.go:274 level=info msg="Listening on" address=[::]:9104
    ts=2024-03-28T14:19:19.301Z caller=tls_config.go:277 level=info msg="TLS is disabled." http2=false address=[::]:9104
    
  • Mit curl die Metriken von mysqld_exporter anzeigen
    kubectl run -it --image=cmd.cat/bash/curl --rm --command -- curl db:9104/metrics
    
    # HELP process_open_fds Number of open file descriptors.
    # TYPE process_open_fds gauge
    process_open_fds 9
    # HELP process_resident_memory_bytes Resident memory size in bytes.
    # TYPE process_resident_memory_bytes gauge
    process_resident_memory_bytes 6.766592e+06
    # HELP process_start_time_seconds Start time of the process since unix epoch in seconds.
    # TYPE process_start_time_seconds gauge
    process_start_time_seconds 1.7092851009e+09
    # HELP process_virtual_memory_bytes Virtual memory size in bytes.
    # TYPE process_virtual_memory_bytes gauge
    (...)
    

Cleanup

  • Löschen Sie alle Objekte, die wir mit kubectl delete erstellt haben, indem Sie den Label-Selektor für diese speziellen Übungen verwenden.
  • Beobachten Sie, wie sie mit watch kubectl get all verschwinden.
Lösung (Klicken Sie auf den Pfeil, falls Sie nicht weiterkommen)
kubectl delete pods --selector exercise=initcontainer
kubectl delete services --selector exercise=initcontainer
kubectl delete services --selector exercise=sidecar
kubectl delete pods --selector exercise=sidecar
kubectl delete secrets --selector exercise=sidecar