Zum Inhalt

Lab 09: Persistent Volumes

Die folgende Übungsaufgabe soll dir dabei helfen, ein grundlegendes Verständnis für Volumes in Kubernetes (k8s) zu erhalten. In dieser Übung erstellst du eine Applikation, die in einem Pod läuft und persistenten Speicherplatz in Form eines Volumes verwendet.

Erstelle die k8s-Ressourcen

manifest.yaml:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-claim
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
---
apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    app: my-app
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
      nodePort: 30080
  type: NodePort
---
apiVersion: v1
kind: Pod
metadata:
  name: my-pod
  labels:
    app: my-app
spec:
  securityContext:
    seccompProfile:
      type: RuntimeDefault
  containers:
    - name: my-container
      image: nginx:1.29.4
      ports:
        - containerPort: 80
      readinessProbe:
        tcpSocket:
          port: 80
        initialDelaySeconds: 5
        periodSeconds: 10
      livenessProbe:
        tcpSocket:
          port: 80
        initialDelaySeconds: 10
        periodSeconds: 20
      volumeMounts:
        - mountPath: "/usr/share/nginx/html"
          name: my-volume
      resources:
        requests:
          cpu: "100m"
          memory: "128Mi"
        limits:
          cpu: "200m"
          memory: "256Mi"
  volumes:
    - name: my-volume
      persistentVolumeClaim:
        claimName: my-claim

Wie auch in den letzten Beispielen kannst du alle nötigen Ressourcen für diese Übung über die manifest.yaml anlegen:

kubectl apply -f manifest.yaml

Angelegt werden ein Pod mit NGINX, ein Service des Typs NodePort der diesen Pod unter Port 30080 auf dem Host verfügbar macht und ein PersistentVolumeClaim, mit welchem der Pod ein PersistentVolume anfragen wird.

Verwende die folgenden Befehle, um den Status deiner Kubernetes-Ressourcen zu überprüfen:

kubectl get pv,pvc
kubectl get pods

Typische Beispielausgaben:

# kubectl get pv,pvc
NAME                                                        CAPACITY   ACCESSMODES   RECLAIMPOLICY   STATUS   CLAIM             STORAGECLASS   REASON   AGE
persistentvolume/pvc-60108e64-6d15-11ec-af1d-0242ac110002   1Gi        RWO           Delete          Bound    default/my-claim  standard                2m

NAME                     STATUS   VOLUME                                     CAPACITY   ACCESSMODES   STORAGECLASS   AGE
persistentvolumeclaim/my-claim   Bound    pvc-60108e64-6d15-11ec-af1d-0242ac110002   1Gi        RWO            standard       2m

# kubectl get pods
NAME     READY   STATUS    RESTARTS   AGE
my-pod    1/1     Running   0          1m

Wenn du eine ähnliche Ausgabe erhältst du der Pod den Status running hat, kannst du fortfahren. Das kann etwas dauern!

Erstelle eine index.html-Datei auf deinem lokalen Rechner

Du kannst auch die index.html-Datei verwenden, die in diesem Verzeichnis liegt.

index.html:

<!doctype html>
<html lang="de">
  <head>
    <meta charset="UTF-8" />
    <title>Meine persönliche Webseite</title>
  </head>
  <body>
    <h1>Hallo, das ist meine persönliche Webseite!</h1>
    <p>
      Willkommen auf meiner Webseite, die in einem Kubernetes-Pod mit einem
      Persistent Volume läuft.
    </p>
  </body>
</html>

Kopiere die index.html-Datei in den nginx-Container

kubectl cp index.html my-pod:/usr/share/nginx/html/index.html -c my-container

In diesem Befehl ersetzt du index.html durch den Pfad zur Datei auf deinem lokalen Rechner. my-pod ist der Name des Pods, in den die Datei kopiert werden soll, und my-container der Namen des Containers innerhalb des Pods (hier ist es der nginx-Container). Der Zielordner /usr/share/nginx/html/index.html ist der in der pod.yaml definierte Speicherort innerhalb des Containers.

Überprüfe, ob die index.html-Datei erfolgreich übertragen wurde**

Für Minikube

Wenn wir minikube einsetzen, können wir leider nicht einfach mit http://localhost:30080 auf den Service zugreifen, obwohl wir diesen Port im Service als NodePort definiert haben. Wir führen also aus:

minikube service my-service

Im Browser sollten nun die Webseite erscheinen, die wir oben angelegt haben.

Für Azure Kubernetes Service (AKS)

Startet einen Load-Balancer-Service auf eurem Cluster, um den Pod zu erreichen:

aks-lb.yaml:

apiVersion: v1
kind: Service
metadata:
  name: my-service
  labels:
    app: my-app
spec:
  type: LoadBalancer
  selector:
    app: my-app
  ports:
    - name: http
      port: 80
      targetPort: 80
kubectl apply -f aks-lb.yaml

Ruft daraufhin die externe IP des Load-Balancer-Dienstes ab, um NGINX zu erreichen:

kubectl get svc my-service -o wide 

Pod löschen und neu anlegen

Lösche nun den Pod my-pod und wende das Manifest neu an, damit der Pod wieder angelegt wird. Starte nun wieder den Service-Tunnel und prüfe, ob die Webseite immer noch erscheint.

kubectl delete pod my-pod
kubectl apply -f manifest.yaml
minikube service my-service

Um zu verstehen, warum das so ist, kannst du dir die PersistentVolumes anschauen. Lösche noch einmal den Pod und lass' dir anzeigen, ob das PV noch existiert:

kubectl delete pod my-pod
kubectl get pv

Aufräumen

Um die erstellten Ressourcen vollständig zu entfernen, gehen wir diesmal den einfachen Weg:

minikube delete
minikube start

Dadurch wird der Cluster komplett gelöscht und neu aufsetzt.