Einführung
Container verfügen über beschreibbare Dateisysteme, doch dieser Speicher ist fest an den jeweiligen Container gebunden. Kubernetes-Volumes bieten Pods eine übersichtlichere Methode zur Dateiverwaltung. Einige Volumes sind ephemer (flüchtig) und für temporäre Daten innerhalb eines einzelnen Pods gedacht. Andere Volumes sind persistent und können Daten auch dann vorhalten, wenn ein Pod gelöscht und neu erstellt wird.
In diesem Lab verwenden Sie ein emptyDir-Volume für temporäre Pod-lokale Daten. Anschließend erstellen Sie einen PersistentVolumeClaim und binden diesen in zwei verschiedene Pods ein, um nachzuweisen, dass die Daten den Austausch eines Pods überdauern.
Vorbereiten eines Namespaces für Volume-Übungen
In diesem Schritt bereiten Sie einen sauberen Namespace vor und stellen sicher, dass der Cluster über die für dieses Lab erforderlichen Speicherkomponenten verfügt.
Beginnen Sie im Verzeichnis /home/labex/project. Sie werden die Pod- und PVC-Manifeste in diesem Verzeichnis 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 Node 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-Networking-Pod bereit (Ready) ist:
kubectl wait --namespace kube-system --for=condition=Ready pod -l k8s-app=calico-node --timeout=120s
Erwartete Ausgabe:
pod/calico-node-... condition met
Dieses Lab verwendet später einen PersistentVolumeClaim. Bestätigen Sie, dass die standardmäßige standard-StorageClass existiert, und warten Sie dann auf den Storage-Provisioner-Pod von minikube.
kubectl get storageclass standard
kubectl wait --namespace kube-system --for=condition=Ready pod/storage-provisioner --timeout=120s
Die erwartete Ausgabe enthält:
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ...
standard (default) k8s.io/minikube-hostpath Delete Immediate ...
pod/storage-provisioner condition met
Erstellen Sie einen Namespace namens ckad-prep-volumes:
kubectl create namespace ckad-prep-volumes
Setzen Sie diesen Namespace als aktuellen Kontext-Namespace:
kubectl config set-context --current --namespace=ckad-prep-volumes
Überprüfen Sie den aktuellen Namespace:
kubectl config view --minify --output 'jsonpath={..namespace}'; echo
Erwartete Ausgabe:
ckad-prep-volumes
Verwendung von emptyDir für Pod-lokale temporäre Daten
In diesem Schritt erstellen Sie einen Pod, der ein emptyDir-Volume verwendet.
Ein emptyDir-Volume ist beim Erstellen des Pods leer. Container innerhalb desselben Pods können es als gemeinsamen Zwischenspeicher, Cache oder temporäres Arbeitsverzeichnis nutzen. Es ist nicht dafür vorgesehen, Daten nach dem Entfernen des Pods beizubehalten.
Erstellen Sie die Datei emptydir-pod.yaml:
cat > emptydir-pod.yaml <<'EOF'
apiVersion: v1
kind: Pod
metadata:
name: scratch-worker
labels:
app: scratch-worker
spec:
terminationGracePeriodSeconds: 0
volumes:
- name: scratch-space
emptyDir: {}
containers:
- name: worker
image: busybox:1.36
command:
- /bin/sh
- -c
- 'echo scratch-ready > /scratch/status.txt; sleep 3600'
volumeMounts:
- name: scratch-space
mountPath: /scratch
EOF
Wenden Sie das Manifest an:
kubectl apply -f emptydir-pod.yaml
Erwartete Ausgabe:
pod/scratch-worker created
Warten Sie, bis der Pod bereit ist:
kubectl wait --for=condition=Ready pod/scratch-worker --timeout=120s
Erwartete Ausgabe:
pod/scratch-worker condition met
Lesen Sie die Datei aus dem eingebundenen emptyDir-Volume:
kubectl exec scratch-worker -c worker -- cat /scratch/status.txt
Erwartete Ausgabe:
scratch-ready
Überprüfen Sie den Volume-Typ des Pods. Der jsonpath-Ausdruck gibt den Volume-Namen aus und bestätigt, dass es sich um ein emptyDir handelt.
kubectl get pod scratch-worker -o 'jsonpath={.spec.volumes[0].name}{" emptyDir\n"}'
Erwartete Ausgabe:
scratch-space emptyDir
Schreiben von Daten in einen PersistentVolumeClaim
In diesem Schritt erstellen Sie einen PersistentVolumeClaim (PVC) und binden ihn in einen Writer-Pod ein.
Ein PersistentVolumeClaim ist eine Anforderung einer Anwendung nach Speicherplatz. In diesem Lab stellt die standard-StorageClass dynamisch Speicher für diesen Claim bereit. Ihr Pod bindet den Claim unter /data ein und schreibt dort eine Datei hinein.
Erstellen Sie die Datei notes-pvc.yaml:
cat > notes-pvc.yaml <<'EOF'
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: notes-pvc
spec:
accessModes:
- ReadWriteOnce
storageClassName: standard
resources:
requests:
storage: 1Mi
EOF
Wenden Sie den PVC an:
kubectl apply -f notes-pvc.yaml
Erwartete Ausgabe:
persistentvolumeclaim/notes-pvc created
Warten Sie, bis der PVC den Status Bound erreicht:
kubectl wait --for=jsonpath='{.status.phase}'=Bound pvc/notes-pvc --timeout=120s
Erwartete Ausgabe:
persistentvolumeclaim/notes-pvc condition met
Erstellen Sie einen Writer-Pod, der den PVC einbindet:
cat > pvc-writer-pod.yaml <<'EOF'
apiVersion: v1
kind: Pod
metadata:
name: pvc-writer
labels:
app: pvc-writer
spec:
terminationGracePeriodSeconds: 0
volumes:
- name: notes-storage
persistentVolumeClaim:
claimName: notes-pvc
containers:
- name: writer
image: busybox:1.36
command:
- /bin/sh
- -c
- 'echo persistent-note > /data/note.txt; sleep 3600'
volumeMounts:
- name: notes-storage
mountPath: /data
EOF
Wenden Sie den Writer-Pod an und warten Sie, bis er bereit ist:
kubectl apply -f pvc-writer-pod.yaml
kubectl wait --for=condition=Ready pod/pvc-writer --timeout=120s
Erwartete Ausgabe:
pod/pvc-writer created
pod/pvc-writer condition met
Lesen Sie die Datei vom PVC-Mount:
kubectl exec pvc-writer -c writer -- cat /data/note.txt
Erwartete Ausgabe:
persistent-note
Wiederverwenden des PVC in einem neuen Pod
In diesem Schritt löschen Sie den Writer-Pod, erstellen einen neuen Reader-Pod, der denselben PVC einbindet, und bestätigen, dass die Datei weiterhin vorhanden ist.
Dies verdeutlicht den praktischen Unterschied zwischen Pod-lokalen temporären Daten und persistentem Speicher. Der Writer-Pod kann entfernt werden, aber der PVC bleibt bestehen. Ein neuer Pod kann denselben Claim einbinden und die Daten lesen.
Löschen Sie den Writer-Pod:
kubectl delete pod pvc-writer
Erwartete Ausgabe:
pod "pvc-writer" deleted
Erstellen Sie einen Reader-Pod, der denselben PVC einbindet:
cat > pvc-reader-pod.yaml <<'EOF'
apiVersion: v1
kind: Pod
metadata:
name: pvc-reader
labels:
app: pvc-reader
spec:
terminationGracePeriodSeconds: 0
volumes:
- name: notes-storage
persistentVolumeClaim:
claimName: notes-pvc
containers:
- name: reader
image: busybox:1.36
command:
- /bin/sh
- -c
- 'cat /data/note.txt; sleep 3600'
volumeMounts:
- name: notes-storage
mountPath: /data
EOF
Wenden Sie den Reader-Pod an und warten Sie, bis er bereit ist:
kubectl apply -f pvc-reader-pod.yaml
kubectl wait --for=condition=Ready pod/pvc-reader --timeout=120s
Erwartete Ausgabe:
pod/pvc-reader created
pod/pvc-reader condition met
Lesen Sie die Datei vom neuen Pod aus:
kubectl exec pvc-reader -c reader -- cat /data/note.txt
Erwartete Ausgabe:
persistent-note
Überprüfen Sie den PVC. Er sollte weiterhin Bound sein, obwohl der ursprüngliche Writer-Pod gelöscht wurde.
kubectl get pvc notes-pvc
Die erwartete Ausgabe enthält:
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE
notes-pvc Bound ... 1Mi RWO standard <unset> ...
Zusammenfassung
Sie haben ein emptyDir-Volume für Pod-lokale temporäre Daten verwendet, einen PVC für persistenten Speicher erstellt, Daten über einen Pod geschrieben, diesen Pod gelöscht und dieselben Daten von einem neuen Pod aus gelesen, der denselben Claim eingebunden hat. Sie wissen nun, wann ephemerer Speicher für temporäre Pod-Daten zu verwenden ist und wann persistenter Speicher für Daten angefordert werden sollte, die einen Pod-Austausch überdauern müssen.


