Zum Inhalt

Volumes

Ziel

  • Volumes erstellen und inspizieren
  • Dateien aus ConfigMaps und Secrets mounten

Hilfsmittel

Aufgabe 1: emptyDir Volumes

  1. Betrachten Sie die offizielle Dokumentation für emptyDir Volumes
  2. Erstellen Sie eine Datei emptydir.yaml, die einen Pod mit dem Namen volume-emptydir beschreibt.
  3. Die Pod-Spezifikation sollte ein Volume des Typs emptyDir mit dem Namen cache enthalten.
  4. Mounten Sie das Volume in der Container-Spezifikation unter dem Pfad /cache.
  5. Fügen Sie ein Label exercise: volumes zu den Pod-Metadaten hinzu.
  6. Wenden Sie den Pod mit kubectl apply an.
  7. Prüfen Sie den Pod.
  8. Überprüfen Sie die Mounts innerhalb des Pod-Containers.
Lösung (Klicken Sie auf den Pfeil, falls Sie nicht weiterkommen)
  • Erstellen Sie ein YAML file emptydir.yaml mit dem folgenden Inhalt:
    ---
    apiVersion: v1
    kind: Pod
    metadata:
      name: volume-emptydir
      labels:
        exercise: volumes
    spec:
      volumes:
      - name: cache
        emptyDir: {}
      containers:
      - name: web
        image: nginx
        volumeMounts:
        - mountPath: /cache
          name: cache
    
  • Wenden Sie den Pod an:
    kubectl apply -f emptydir.yaml
    
  • Inspizieren Sie das Ergebnis:
    $ kubectl describe pod volume-emptydir
    
    Name:             volume-emptydir
    (...)
    Containers:
      web:
        (...)
        Mounts:
          /cache from cache (rw)
    (...)
    Volumes:
      cache:
        Type:       EmptyDir (a temporary directory that shares a pod's lifetime)
        Medium:
        SizeLimit:  <unset>
    
  • Überprüfen Sie ob /cache gemounted wurde
    $ kubectl exec -it volume-emptydir -- df --exclude-type=tmpfs
    
    Filesystem     1K-blocks    Used Available Use% Mounted on
    overlay        619139212 8908236 584839800   2% /
    /dev/sda1      619139212 8908236 584839800   2% /cache
    

Aufgabe 2: hostpath Volumes

  1. Betrachten Sie die offizielle Dokumentation für hostPath Volumes
  2. Erstellen Sie eine Datei hostpath.yaml, die einen Pod mit dem Namen volume-hostpath beschreibt.
  3. Die Pod-Spezifikation sollte ein Volume des Typs hostPath mit dem Namen data enthalten.
  4. Mounten Sie das Volume in der Container-Spezifikation unter dem Pfad /data.
  5. Fügen Sie den Pod-Metadaten ein Label exercise: volumes hinzu.
  6. Wenden Sie den Pod mit kubectl apply an.
  7. Prüfen Sie den Pod.
  8. Überprüfen Sie die Mounts innerhalb des Pod-Containers.
Lösung (Klicken Sie auf den Pfeil, falls Sie nicht weiterkommen)
  • Erstellen Sie ein YAML file emptydir.yaml mit dem folgenden Inhalt:
    ---
    apiVersion: v1
    kind: Pod
    metadata:
      name: volume-hostpath
      labels:
        exercise: volumes
    spec:
      volumes:
      - name: data
        hostPath:
          path: /data
          type: DirectoryOrCreate
      containers:
      - name: web
        image: nginx
        volumeMounts:
        - mountPath: /data
          name: data
    
  • Wenden Sie den Pod an:
    kubectl apply -f hostpath.yaml
    
  • Inspizieren Sie das Ergebnis:
    $ kubectl describe pod volume-hostpath
    
    Name:             volume-hostpath
    (...)
    Containers:
      web:
        (...)
        Mounts:
          /data from data (rw)
    (...)
    Volumes:
      data:
        Type:          HostPath (bare host directory volume)
        Path:          /data
        HostPathType:  DirectoryOrCreate
    
  • Überprüfen Sie ob /data gemounted wurde
    $ kubectl exec -it volume-hostpath -- df --exclude-type=tmpfs
    
    Filesystem     1K-blocks    Used Available Use% Mounted on
    overlay        619139212 9021932 584726104   2% /
    /dev/sda1      619139212 9021928 584726108   2% /data
    
  1. Verwenden Sie kubectl exec, um eine Datei innerhalb von /data des volume-hostpath Pods zu erstellen
  2. Sehen Sie sich den volume-hostpath-Pod an, um herauszufinden, auf welchem NODE er ausgerollt wurde
  3. Löschen Sie den Pod volume-hostpath mit kubectl delete.
  4. Überprüfen Sie die Liste der Pods, um sicherzustellen, dass der Pod entfernt wurde.
  5. Wenden Sie den Pod erneut an mit kubectl apply.
  6. Prüfen Sie, ob der Pod auf demselben NODE erstellt wurde.
  7. Prüfen Sie, ob die Datei im Pod noch existiert.

Hinweis

  • Daten in hostPath-Mounts werden auf einem bestimmten Knoten gespeichert
  • Pods können auf jedem verfügbaren Clusterknoten erstellt werden.
  • Wenn Sie mehr als einen Knoten haben, wird die Verwendung von hostPath für die Persistenz von Dateien während des Pod-Lebenszyklus unzuverlässig.
Lösung (Klicken Sie auf den Pfeil, falls Sie nicht weiterkommen)
  • Erstellen Sie eine Datei /data/foo:
    kubectl exec -it volume-hostpath -- sh -c "echo '# here we go' > /data/foo"
    
  • Überprüfen Sie, dass die Datei erstellt wurde:
    $ kubectl exec -it volume-hostpath -- cat /data/foo
    
    # here we go
    
  • Inspizieren Sie den Pod und merken Sie sich, auf welchem NODE der Pod ausgerollt wurde:

    $ kubectl get pod volume-hostpath -o wide
    NAME             READY  STATUS   RESTARTS  AGE    IP            NODE                              NOMINATED NODE    READINESS GATES
    volume-hostpath  1/1    Running  0         3m31s  10.42.139.55  code-0-worker-wppfn-v5vts  <none>            <none>
    
    Ein Knoten ist der Host, auf dem Kubernetes-Objekte erstellt werden. Einfach ausgedrückt: Vergleichen Sie Kubernetes-Hosts mit Docker-Hosts. Ihre Workshop-Umgebung enthält 3 Worker Nodes. Nodes werden später im Workshop erklärt.

  • Löschen Sie den Pod

    kubectl delete -f hostpath.yaml
    

  • Überprüfen Sie, dass der Pod tatsächlich gelöscht wurde
    kubectl get pods
    
  • Erstellen Sie den Pod erneut
    kubectl apply -f hostpath.yaml
    
  • Prüfen Sie den aktuellen Pod erneut und vergleichen Sie den NODE mit dem vorherigen Pod
    $ kubectl get pod volume-hostpath -o wide
    NAME             READY  STATUS   RESTARTS  AGE    IP            NODE                              NOMINATED NODE    READINESS GATES
    volume-hostpath  1/1    Running  0         3m31s  10.42.139.55  code-0-worker-wppfn-v5vts  <none>            <none>
    
  • Wenn der NODE derselbe ist wie zuvor, sollte die Testdatei in Ihrem neuen Pod zu finden sein
    kubectl exec -it volume-hostpath -- cat /data/foo
    # here we go
    
  • Wenn der NODE NICHT derselbe ist wie zuvor, sollte die Testdatei in Ihrem neuen Pod nicht zu finden sein
    $ kubectl exec -it volume-hostpath -- cat /data/foo
    
    cat: /data/foo: No such file or directory
    command terminated with exit code 1
    

Aufgabe 3: Mount ConfigMap

  1. Erstellen Sie eine Datei configmap-mount.yaml, die eine ConfigMap namens my-mount enthält.
  2. Die ConfigMap-Daten sollten einen Schlüssel index.html mit dem folgenden Wert enthalten:
    <html><body>Hooray!</body></html>
    
  3. Fügen Sie den Metadaten die Bezeichnung exercise: mounts hinzu.
  4. Wenden Sie die ConfigMap mit kubectl apply an.
  5. Listen Sie das Ergebnis auf und prüfen Sie es.
Lösung (Klicken Sie auf den Pfeil, falls Sie nicht weiterkommen)
  • Das YAML-File configmap-mount.yaml sieht folgendermaßen aus:
    ---
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: my-mount
      labels:
        exercise: mount
    data:
      index.html: |
        <html><body>Hooray!</body></html>
    
  • Anwenden:
    kubectl apply -f configmap-mount.yaml
    
  • Ergebnis auflisten:
    $ kubectl get configmap my-mount -o yaml
    
    apiVersion: v1
    data:
      index.html: |
        <html><body>Hooray!</body></html>
    kind: ConfigMap
    (...)
    
  1. Lesen Sie das Kapitel "Using ConfigMaps as files from a pod"
  2. Erstellen Sie einen Pod namens web in pod-web-mount.yaml unter Verwendung des Images nginx (ähnlich wie in den Übungen zuvor)
  3. Fügen Sie ein Label exercise: mounts zu den Metadaten hinzu, das zum Aufräumen am Ende benötigt wird.
  4. Fügen Sie dem Pod ein Volume hinzu, das auf die ConfigMap my-mount zeigt.
  5. Mappen Sie das Volume auf den mountPfad /usr/share/nginx/html.
  6. Wenden Sie es mit kubectl apply an.
  7. Überprüfen Sie den Dateimount im Pod.
Lösung (Klicken Sie auf den Pfeil, falls Sie nicht weiterkommen)
  • Das YAML-File pod-web-mount.yaml sieht folgendermaßen aus:
    ---
    apiVersion: v1
    kind: Pod
    metadata:
      name: web-mount
      labels:
        exercise: mount
    spec:
      volumes:
      - name: html-files
        configMap:
          name: my-mount
      containers:
      - name: web
        image: nginx:stable-alpine
        volumeMounts:
        - mountPath: /usr/share/nginx/html
          name: html-files
    
  • Anwenden:
    kubectl apply -f pod-web-mount.yaml
    
  • Ergebnis anzeigen:
    $ kubectl describe pod web-mount
    (...)
    Containers:
      env:
        (...)
        Mounts:
          /usr/share/nginx/html from html-files (rw)
    (...)
    Volumes:
      html-files:
        Type:      ConfigMap (a volume populated by a ConfigMap)
        Name:      my-mount
        Optional:  false
    (...)
    
  1. Verwenden Sie kubectl exec, um sich mit dem Pod web-mount zu verbinden
  2. Führen Sie df -a im Pod aus, um den Einhängepunkt /usr/share/nginx/html zu sehen
  3. Führen Sie ls -l /usr/share/nginx/html in der Gruppe aus, um die gemounteten Dateien zu sehen
  4. Führen Sie curl -s localhost in der Gruppe aus, um die Antwort des Webservers zu prüfen
Lösung (Klicken Sie auf den Pfeil, falls Sie nicht weiterkommen)
  • Mountpoint innerhalb des Pods:
    $ kubectl exec -it web-mount -- df -a
    
    /dev/sda1            619139212   8467828 585280208   1% /usr/share/nginx/html
    
  • Dateien auflisten:
    $ kubectl exec -it web-mount -- ls -l /usr/share/nginx/html
    
    total 0
    lrwxrwxrwx    1 root     root            17 Feb 28 10:14 index.html -> ..data/index.html
    
  • Mit curl die Antwort des Webservers prüfen:
    $ kubectl exec -it web-mount -- curl -s localhost
    
    <html><body>Hooray!</body></html>
    

Aufgabe 4: Mount Secret

Wenn Sie Dateien mounten wollen, die Geheimnisse enthalten, verwenden Sie besser ein Secret anstelle einer ConfigMap. Das Einbinden eines Secrets in einen Pod funktioniert im Grunde genauso wie das Einbinden einer ConfigMap.

  1. Lesen Sie sich das Kubernetes-Tutorial "Credentials sicher verteilen mit Secrets"
  2. Erstellen Sie eine Datei secret-mount.yaml, die die Beschreibung für ein Secret mit dem Namen my-secret-mount enthält.
  3. Die Secret-Daten sollten zwei Schlüssel enthalten:
    • secret.txt mit dem Wert "abracadabra"
    • passphrase.txt mit dem Wert "open sesame".
  4. Fügen Sie den Metadaten ein Label exercise: mounts hinzu.
  5. Verteilen Sie das Secret mit kubectl apply.
  6. Erstellen Sie einen neuen Pod mit einem Volume, das auf das Secret my-secret-mount zeigt und alle Daten aus dem Secret in den mountPfad /secrets mounted.
  7. Überprüfen Sie den Pod und die eingehängten Dateien.
Lösung (Klicken Sie auf den Pfeil, falls Sie nicht weiterkommen)
  • Das YAML-File secret-mount.yaml sieht folgendermaßen aus:
    ---
    apiVersion: v1
    kind: Secret
    metadata:
      name: my-secret-mount
      labels:
        exercise: mount
    type: Opaque
    stringData:
      secrets.txt: "abracadabra"
      passphrase.txt: "open sesame"
    
  • Secret anwenden:
    kubectl apply -f secret-mount.yaml
    
  • Ergebnis anzeigen:
    $ kubectl get secret my-secret-mount -o yaml
    
    apiVersion: v1
    data:
      passphrase.txt: b3BlbiBzZXNhbWU=
      secrets.txt: YWJyYWNhZGFicmE=
    kind: Secret
    (...)
    
  • Die Datei pod-secret-mount.yaml hat folgenden Inhalt:
    ---
    apiVersion: v1
    kind: Pod
    metadata:
      name: secret-mount
      labels:
        exercise: mount
    spec:
      volumes:
      - name: secret-files
        secret:
          secretName: my-secret-mount
      containers:
      - name: web
        image: nginx:stable-alpine
        volumeMounts:
        - mountPath: /secrets
          name: secret-files
    
  • Anwenden:
    kubectl apply -f pod-secret-mount.yaml
    
  • Ergebnis anzeigen:
    $ kubectl describe pod secret-mount
    
    (...)
    Containers:
      web:
    (...)
        Mounts:
          /secrets from secret-files (rw)
    Volumes:
      secret-files:
        Type:        Secret (a volume populated by a Secret)
        SecretName:  my-secret-mount
        Optional:    false
    (...)
    
  • Mount-Files anzeigen:
    $ kubectl exec -it secret-mount -- ls -l /secrets
    
    total 0
    lrwxrwxrwx    1 root     root            21 Feb 28 11:18 passphrase.txt -> ..data/passphrase.txt
    lrwxrwxrwx    1 root     root            18 Feb 28 11:18 secrets.txt -> ..data/secrets.txt
    
  • Inhalt der Dateien anzeigen:
    $ kubectl exec -it secret-mount -- cat /secrets/passphrase.txt
    
    open sesame
    
    $ kubectl exec -it secret-mount -- cat /secrets/secrets.txt
    
    abracadabra
    

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=volumes
kubectl delete pods --selector exercise=mount
kubectl delete configmaps --selector exercise=mount
kubectl delete secrets --selector exercise=mount