Il est important de comprendre qu'un container possède un système de fichier éphémère. Les fichiers existent uniquement pendant l'existence du container.
Si le container est supprimé/recrée dans k8s, toutes les données seront perdues.
Mais comment faire si nous avons besoin de faire persister les données ?
Nous allons utiliser ce qu'on appelle un volume, ce qui va nous permettre de stocker les données en dehors d'un container pendant que celui-ci tourne.
Les Volumes Persistants (Persistent Volumes) sont une forme un peu plus forme avancée de volume. Ils vous permettent de traiter le stockage comme une ressource abstraite et de le consommer en utilisant vos pods.
Types de volume :
Chaque volume possède différents types de volumes comme :
Les volumes sont faciles à mettre en place dans un pod :
apiVersion: v1
kind: Pod
metadata:
name: volume-pod
spec:
restartPolicy: Never
containers:
- name: busybox
image: busybox
command: ['sh', '-c', 'echo Success! > /output/success.txt']
volumeMounts:
- name: my-volume
mountPath: /output
volumes:
- name: my-volume
hostPath:
path: /var/data
On spécifie donc :
k8s-control:~$ kubectl get pod volume-pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
volume-pod 0/1 Completed 0 12m 192.168.194.125 k8s-worker1 <none> <none>
# Sur le worker1
k8s-worker1:~$ cat /var/data/success.txt
Success!
On peut aussi partager le même volume entre deux containers d'un pod :
apiVersion: v1
kind: Pod
metadata:
name: shared-volume-pod
spec:
containers:
- name: busybox1
image: busybox
command: ['sh', '-c', 'while true; do echo Success! > /output/output.txt; sleep 5; done']
volumeMounts:
- name: my-volume
mountPath: /output
- name: busybox2
image: busybox
command: ['sh', '-c', 'while true; do cat /input/output.txt; sleep 5; done']
volumeMounts:
- name: my-volume
mountPath: /input
volumes:
- name: my-volume
emptyDir: {}
Types de volume important pour le CKA :
$ kubectl logs shared-volume-pod -c busybox2
Success!
Success!
Success!
Success!
apiVersion: v1
kind: PersistentVolume
metadata:
name: my-pv
spec:
storageClassName: localdisk # Référence à la StorageClass
persistentVolumeReclaimPolicy: Recycle
capacity:
storage: 1Gi
accessModes:
- ReadWriteOnce # Le volume peut être monté en lecture-écriture par un seul nœud
hostPath:
path: /var/output
La StorageClass doit être créée avant le PersistentVolume.
Le paramètre persistentVolumeReclaimPolicy
défini ce que k8s doit faire du volume une fois la persistentVolumeClaim
est supprimée :
On peut lister toutes les PVs :
$ kubectl get persistentvolume
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
my-pv 1Gi RWO Recycle Available localdisk 18s
On voit que le statut est Available. On peut donc associer un PVC.
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: localdisk
provisioner: kubernetes.io/no-provisioner
allowVolumeExpansion: true # Permet le redimensionnement de disque à la volée
On pourrait par exemple créer une StorageClass "lent" pour prévenir qu'on utilise des disques lents mais peu couteux. Une autre appelée "rapide" qui utiliserait des disques SSD plus couteux.
$ kubectl get storageclasses.storage.k8s.io
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
localdisk kubernetes.io/no-provisioner Delete Immediate true 5s
Quand un PersistentVolumeClaim est créé, il va chercher un PersistentVolume qui rencontre les critères du PVC. S'il trouve un PV éligible, cela va automatiquement bound le PVC au PV.
Pour utiliser un PVC il faut ensuite le déclarer dans la définition du pod.
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: my-pvc
spec:
storageClassName: localdisk
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 100Mi
On va maintenant voir que le PV est bound :
$ kubectl get persistentvolume
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
my-pv 1Gi RWO Recycle Bound default/my-pvc localdisk 3m52s
$ kubectl get persistentvolumeclaims
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
my-pvc Bound my-pv 1Gi RWO localdisk 7s
On va maintenant associer un pod au PVC :
apiVersion: v1
kind: Pod
metadata:
name: pv-pod
spec:
restartPolicy: Never
containers:
- name: busybox
image: busybox
command: ['sh', '-c', 'echo Success! > /output/success.txt']
volumeMounts:
- name: pv-storage
mountPath: /output
volumes:
- name: pv-storage
persistentVolumeClaim:
claimName: my-pvc
On peut facilement étendre un PVC (si allowVolumeExpansion: true
dans la StorageClass). Pour se faire, il faut éditer le pod.