Kubernetes - les volumes et le stockage
Cette annexe s'efforce de donner une vue d'ensemble du stockage avec Kubernetes. Elle a pour objectif premier d'illustrer la complexité du sujet et de montrer qu'héberger les données non jetables d'applications dans Kubernetes ne sera pas une mince affaire.
- Les volumes
- Les pilotes pour le stockage
- Provisionnement statique et dynamique
- Les modes d'accès
- Cas des StatefulSet
- Mise en garde
Les volumes
Kubernetes distingue plusieurs types de volumes répondant à différents cas d'utilisation :
- Les volumes persistants (PersistentVolume) avec plusieurs types dont :
- Les volumes projetés
- Les volumes éphémères :
- emptyDir pour stocker les données temporaires propres à chaque Pod
Les pilotes pour le stockage
Kubernetes dispose d'un mécanisme de plugin permettant d'intégrer différentes solutions de stockage (c.f. kubernetes-csi.github.io - CSI Drivers) dont :
Dans les cas où nous utilisons Kubernetes en mode SaaS, nous soulignerons que les possibilités offertes par défaut seront fonctions de l'infrastructure :
- Des volumes Cinder si nous utilisons Managed Kubernetes Service d'OVH qui s'appuie sur OpenStack.
- Des GCE Persistent Disk si nous utilisons Google Kubernetes Engine.
Provisionnement statique et dynamique
Le concept de PersistentVolumeClaim permettra de faire abstraction sur la commande d'un volume persistant :
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-nginx
spec:
accessModes:
- ReadWriteOnce
storageClassName: fast
resources:
requests:
storage: 30Gi
Le concept de StorageClass permettra de répondre à cette demande avec deux cas de figure :
- La création du PersistentVolume correspondant par un administrateur du cluster (provisionnement statique)
- La création automatique du PersistentVolume via l'utilisation d'une classe de stockage prévue à cet effet (provisionnement dynamique)
La commande kubectl get storageclass
renverra la liste des classes de stockage mise à disposition pour le provisionnement dynamique.
Les modes d'accès
Nous soulignerons que tous les types de stockage n'offrent pas les mêmes possibilités. En particulier, Kubernetes distinguera plusieurs modes d'accès dont :
- ReadWriteOnce (RWO) indiquant que le volume peut être utilisé en lecture/écriture par des Pods s'exécutant sur un même noeud.
- ReadWriteMany (RWX) dans le cas où les Pods s'exécutent sur plusieurs noeuds.
Ainsi :
- ReadWriteOnce sera le reflet d'une contrainte : Il n'est généralement pas possible d'attacher un disque virtuel à plusieurs machines virtuelles.
- ReadWriteMany correspondra à l'utilisation d'un stockage de fichier en réseau ou système de stockage distribué.
En règle générale, il sera préférable de ne pas avoir recours à un stockage ReadWriteMany pour des raisons de performance et éventuellement de coût (mais se libérer de cette contrainte pourra demander des efforts de refonte importants).
Cas des StatefulSet
La propriété volumeClaimTemplates
sur les StatefulSet permettra de laisser Kubernetes se charger de la création d'un PVC par Pod (postgres-0, postgres-1,...
) :
Il convient de noter qu'il n'y aura pas de suppression automatique sur les PVC créés automatiquement pour les Pod d'un StatefulSet (ils survivront à la suppression des Pods et du StatefulSet).
Mise en garde
- La suppression d'un PersistentVolumeClaim se traduit généralement par la suppression du PersistentVolume correspondant (voir kubernetes.io - Change the Reclaim Policy of a PersistentVolume)
- Si vous utilisez Helm pour créer des PVC,
helm uninstall mon-application
incluera la suppression des PVC (voir helm.sh - Tell Helm Not To Uninstall a Resource et créer les PVC en amont du déploiment) - L'utilisation de volumes persistants dans un cluster Kubernetes induira une prudence particulière et une complexité accrue dans l'exploitation d'un cluster Kubernetes.
Par exemple, la suppression brutale d'un Pod récalcitrant à la suppression (status=Terminating
) se traduira par le démontage incomplet de ces volumes et le blocage du redémarrage du Pod sur un autre noeud.