Préparation à la CKA - 07 - StorageClass

Publié le 24/09/2024 par Ali Sanhaji

Storage Class

Dans la première partie de cet article, nous avons vu les notions de volumes dans k8s avec les PV, PVC et StorageClass. Nous avons créé des PV manuellement et nous avons lié un PVC à ce dernier, en passant par une StorageClass qui décrit les caractéristiques de notre volume (type, paramètres, etc.).

Tout ça est bien statique, et contraignant. Heureusement qu’on ne fait pas comme ça d’habitude ! En effet, bien que le provisionnement statique des volumes se fait parfois dans des cas spécifiques, la plupart du temps, nous avons recours à du provisionnement statique. C’est-à-dire qu’on déclare un PVC avec la taille qu’on veut, et on dit quelle StorageClass on veut utiliser, et le provisioner associé à cette StorageClass s’occupe de créer le PV dynamiquement. alt text

Le provisioner est un contrôleur k8s qui écoute toutes les demandes qui lui sont associées, et traite ces demandes en conséquence. Quand on crée une StorageClass, on définit quel provisioner va lui être associé :

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: Standard
provisioner: kubernetes.io/azure-disk
parameters:
  storageaccounttype: StandardSSD_LRS
  kind: managed

Dans cet exemple, on déclare une StorageClass qui utilise le provisioner “kubernetes.io/azure-disk”. Cette StorageClass nous permet de créer des disques Azure de type StandardSSD_LRS, c’est-à-dire des disques SSD qui sont répliqués localement dans une availability zone (un data center) d’une région Azure.

Pour que ce provisioner fonctionne, il faut que notre cluster Kubernetes soit installé sur Azure bien évidemment, qu’il soit déployé via un cluster AKS (Azure Kubernetes Service), ou qu’il soit déployé sur des VMs Azure.

Pour l’histoire, ce provisioner en particulier “kubernetes.io/azure-disk” et tous les provisioners qui commencent par kubernetes.io font partie du code de base de kubernetes (on dit in-tree), plus particulièrement du controller manager. Mais déjà depuis plusieurs années, la décision a été prise au sein de la communauté k8s d’enlever ces bouts de contrôleurs du code de base de kubernetes, et de permettre à tous ceux qui veulent créer des contrôleurs de volumes (AWS, Azure, GCP, etc.) de les intégrer via la nouvelle interface CSI (Container Storage Interface). Cela permet à la communauté Kubernetes de ne pas avoir à maintenir le code de chaque provisioner à chaque release de Kubernetes, car les contrôleurs viennent maintenant en tant que plugin (voici la liste), des pods déployés en plus sur Kubernetes.

Par exemple pour demander des PV Azure Disks, au lieu d’utiliser kubernetes.io/azure-disk dans la StorageClass, on doit utiliser disk.csi.azure.com, car le premier sera supprimé du code de base de k8s à la version 1.26. Le contrôleur de disk.csi.azure.com est déjà déployé pour nous sur AKS, et si on veut déployer Kubernetes sur des VMs Azure, on doit déployer ce contrôleur en plus.

Création dynamique d’un Persistent Volume

Nous allons donc créer un volume persistant dynamiquement via une Storage Class.

Pour cette démonstration, nous allons utiliser être sur un cluster AKS pour pouvoir demander dynamiquement des disques Azure.

Pour pouvoir le faire sur notre cluster installé à la main, il nous faudrait installer un gestionnaire de disques comme Ceph par exemple, pour qu’il puisse nous provisionner des disques dynamiquement.

Ici vous pouvez voir la StorageClass que nous allons utiliser :

kubectl describe storageclass managed-csi
Name:                  managed-csi
IsDefaultClass:        No
Annotations:           <none>
Provisioner:           disk.csi.azure.com
Parameters:            skuname=StandardSSD_LRS
AllowVolumeExpansion:  True
MountOptions:          <none>
ReclaimPolicy:         Delete
VolumeBindingMode:     WaitForFirstConsumer
Events:                <none>

Voici l’explication pour les paramètres de cette storage class: Name : vous avez compris IsDefaultClass : si on ne précise pas de StorageClass dans un PVC, la Storage Class par défaut va répondre. La nôtre n’est pas celle par défaut. Annotations : pour ajouter des options spécifiques que comprennent les contrôleurs Provisioner : le contrôleur qui voit les nouvelles demandes de disques et y répond quand on utilise cette StorageClass AllowVolumeExpansion : est-ce que c’est possible d’augmenter la taille du volume MountOptions : les options qu’on met lors du montage comme des droits d’accès ou autre ReclaimPolicy : qu’est-ce qu’on fait d’un PV lorsqu’on supprime son PVC ? VolumeBindingMode : quand est-ce qu’on provisionne le PV ? Dès qu’on demande le PVC ? Ou lorsqu’il y a un consommateur (pod) qui veut utiliser le PVC ?

Nous allons d’abord créer un PVC :

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc-data
spec:
  storageClassName: "managed-csi"
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi

On lance notre fichier :

kubectl apply -f pvc-data.yaml
persistentvolumeclaim/pvc-data created

Si on regarde le PVC, on voit qu’il est dans l’état Pending. Parce qu’on a un VolumeBindingMode de WaitForFirstConsumer, et qu’il n’y a toujours pas de pod qui utilise ce PVC :

kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
pvc-data Pending                        managed-csi 15s

Nous allons créer un pod qui va monter ce PVC :

apiVersion: v1
kind: Pod
metadata:
  labels:
    run: pvc-pod
  name: pvc-pod
spec:
  containers:
  - image: busybox:latest
    name: pvc-pod
    args:
      - sleep
      - "3600"
    volumeMounts:
    - name: data
      mountPath: "/data"
  volumes:
  - name: data
    persistentVolumeClaim:
      claimName: pvc-data
kubectl apply -f pod-data.yaml
pod/pvc-pod created

Si on revoit notre PVC, on voit qu’il y a bien un volume qui a été créé et associé :

kubectl get pvc
NAME       STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
pvc-data   Bound    pvc-e9bb459c-46e9-4fe0-a819-3f6e79ae351e   1Gi        RWO            managed-csi    5m38s

Et on peut retrouver notre PV :

kubectl get pv
NAME CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM STORAGECLASS
pvc-e9bb459c-46e9-4fe0-a819-3f6e79ae351e   1Gi  RWO   Delete  Bound    test/pvc-data   managed-csi

Notre pod est bien lancé avec le PVC :

kubectl get pods
NAME      READY   STATUS    RESTARTS   AGE
pvc-pod   1/1     Running   0          4m49s

Si on supprime le pod et le PVC, notre PV va disparaître aussi parce qu’il est en ReclaimPolicy Delete.

Conclusion

Dans la majorité des environnements, nous allons utiliser du provisionnement dynamique de volumes, car c’est beaucoup plus simple et efficace. Le provisionnement statique est uniquement là pour des cas spécifiques comme lorsque le provisionnement dynamique n’est pas possible.