Lab 02: Übung: Persistent Storage in AKS¶
Erzeuge dir für diese Übung einen Cluster wie in Aufgabe 1 und setze dir Umgebungsvariablen wie dort beschrieben.
Teil 1: Erkunden der vorhandenen StorageClasses¶
Liste alle verfügbaren StorageClasses in deinem AKS-Cluster auf:
kubectl get storageclasses
Untersuche die Details der Disk- und Files-StorageClasses:
kubectl describe storageclass managed-csi
kubectl describe storageclass azurefile-csi
Besonders relevant ist bei StorageClasses der VolumeBindingMode und die
ReclaimPolicy. Ersteres bestimmt, ob für ein PersistentVolumeClaim
ein PersistentVolume erzeugt wird, auch wenn niemand es verwendet. Letzteres
kontrolliert, wann das PV wieder gelöscht wird.
Erstelle um dies zu verdeutlichen eine Datei pvc-disk.yaml:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-azure-disk
spec:
accessModes:
- ReadWriteOnce
storageClassName: managed-csi
resources:
requests:
storage: 5Gi
Wende das Manifest an und überprüfe den Status:
kubectl apply -f pvc-disk.yaml
kubectl get pvc pvc-azure-disk -w
Frage: Warum bleibt der PVC im Status "Pending"? (Tipp: VolumeBindingMode)
Teil 2: StatefulSet mit Azure Disk Volume¶
Wir werden in dieser Aufgabe ein StatefulSet erzeugen, welches einen NGINX via
LoadBalancer erreichbar macht. Die Dateien des Webservers werden auf einer
Azure Disk gespeichert.
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: my-app
ports:
- protocol: TCP
port: 80
type: LoadBalancer
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: my-statefulset
spec:
serviceName: my-service
replicas: 1
selector:
matchLabels:
app: my-app
template:
metadata:
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"
volumeClaimTemplates:
- metadata:
name: my-volume
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
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 nun die index.html in diesem Verzeichnis in den Pod:
kubectl cp index.html my-statefulset-0:/usr/share/nginx/html/index.html -c my-container
Ermittle nun über kubectl die externe IP des LoadBalancers und rufe sie auf.
Du solltest obige HTML-Seite sehen können.
Aber was passiert, wenn wir den Pod löschen?
kubectl delete pod my-statefulset-0
Für eine kurze Zeit wird unsere Anwendung nicht mehr erreichbar sein. Aber wie sieht es aus, wenn der Pod wieder erstellt wird? Ist die HTML-Seite die gleiche?
Spoiler: Sie ist nach wie vor die gleiche. Das liegt daran, dass das
StatefulSet den Pod automatisch neu deployt und die Verbindung zum
PersistentVolumeClaim erneut herstellt.`
Teil 3: PVC mit Azure Files (Shared Storage)¶
Erstelle eine Datei pvc-files.yaml mit ReadWriteMany als Access Mode:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-azure-files
spec:
accessModes:
- ReadWriteMany
storageClassName: azurefile-csi
resources:
requests:
storage: 5Gi
Erstelle außerdem ein Deployment mit 3 Replicas, die alle dasselbe Volume
nutzen (deploy-files.yaml):
apiVersion: apps/v1
kind: Deployment
metadata:
name: files-demo
spec:
replicas: 3
selector:
matchLabels:
app: files-demo
template:
metadata:
labels:
app: files-demo
spec:
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: pvc-azure-files
---
apiVersion: v1
kind: Service
metadata:
name: files-demo
labels:
app: files-demo
spec:
type: LoadBalancer
selector:
app: files-demo
ports:
- name: http
port: 80
targetPort: 80
Wende die Manifeste an und ermittle einen beliebigen Pod-Namen des Deployment
kubectl apply -f pvc-files.yaml
kubectl apply -f deploy-files.yaml
kubectl get pods -l app=files-demo
Kopiere nun wieder die HTML-Datei in das Volume:
kubectl cp index.html PODNAME_BITTE_ERSETZEN:/usr/share/nginx/html/index.html -c my-container
Deploye und teste den gemeinsamen Zugriff. Egal, wie oft du Pods löschst und dadurch neu erstellen lässt: Der Zugriff auf das Azure Files-Volume sollte weiterhin funktionieren.
Bonus¶
Versuche, über das Azure Portal den erstellen File-Share zu finden und deine Datei im Portal anzeigen zu lassen. Wenn du sie gefunden hast, kannst du sie bearbeiten und live sehen, wie dein NGINX eine andere Antwort zurückgibt.