Comment redimensionner les volumes d’un Kubernetes StatefulSet
Les StatefulSets Kubernetes sont utilisés pour déployer des applications avec état dans votre cluster. Chaque pod du StatefulSet peut accéder aux volumes persistants locaux qui s’y tiennent même après sa reprogrammation. Cela permet aux pods de conserver un état individuel séparé de leurs voisins dans l’ensemble.
Malheureusement, ces volumes sont livrés avec une grande limitation : Kubernetes ne fournit pas de moyen de les redimensionner à partir de l’objet StatefulSet. La spec.resources.requests.storage
propriété du StatefulSet volumeClaimTemplates
est immuable, ce qui vous empêche d’appliquer les augmentations de capacité dont vous avez besoin. Cet article vous montrera comment contourner le problème.
Sommaire
Créer un StatefulSet
Copiez ce YAML et enregistrez-le dans ss.yaml
:
apiVersion: v1 kind: Service metadata: name: nginx labels: app: nginx spec: selector: app: nginx ports: - name: nginx port: 80 clusterIP: None --- apiVersion: apps/v1 kind: StatefulSet metadata: name: nginx spec: selector: matchLabels: app: nginx replicas: 3 serviceName: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:latest ports: - name: web containerPort: 80 volumeMounts: - name: data mountPath: /usr/share/nginx/html volumeClaimTemplates: - metadata: name: data spec: accessModes: ["ReadWriteOnce"] resources: requests: storage: 1Gi
Appliquez le YAML à votre cluster avec Kubectl :
$ kubectl apply -f ss.yaml service/nginx created statefulset.apps/nginx created
Vous aurez besoin d’une classe de stockage et d’un approvisionneur dans votre cluster pour exécuter cet exemple. Il crée un StatefulSet qui exécute trois répliques d’un serveur Web NGINX.
Bien que cela ne soit pas représentatif du moment où StatefulSets doit être utilisé, il convient comme démonstration des problèmes de volume auxquels vous pouvez être confronté. Une réclamation de volume avec 1 Gi de stockage est montée dans le répertoire de données de NGINX. Votre contenu Web pourrait dépasser cette allocation relativement faible à mesure que votre service évolue. Cependant essayer de modifier le volumeClaimTemplates.spec.resources.requests.storage
champ à 10Gi
signalera l’erreur suivante lors de l’exécution kubectl apply
:
$ kubectl apply -f ss.yaml service/nginx unchanged The StatefulSet "nginx" is invalid: spec: Forbidden: updates to statefulset spec for fields other than 'replicas', 'template', 'updateStrategy', 'persistentVolumeClaimRetentionPolicy' and 'minReadySeconds' are forbidden
Cela se produit car presque tous les champs du manifeste d’un StatefulSet sont immuables après la création.
Redimensionnement manuel des volumes StatefulSet
Vous pouvez contourner la restriction en redimensionnant manuellement la demande de volume persistant (PVC). Vous devrez ensuite recréer le StatefulSet pour libérer et relier le volume à partir de vos pods. Cela déclenchera l’événement de redimensionnement du volume réel.
Utilisez d’abord Kubectl pour trouver les PVC associés à votre StatefulSet :
$ kubectl get pvc NAME STATUS VOLUME CAPACITY ACCESS MODES data-nginx-0 Bound pvc-ccb2c835-e2d3-4632-b8ba-4c8c142795e4 1Gi RWO data-nginx-1 Bound pvc-1b0b27fe-3874-4ed5-91be-d8e552e515f2 1Gi RWO data-nginx-2 Bound pvc-4b7790c2-3ae6-4e04-afee-a2e1bae4323b 1Gi RWO
Il existe trois PVC car il y a trois réplicas dans le StatefulSet. Chaque pod obtient son propre volume individuel.
Utilisez maintenant kubectl edit
pour régler la capacité de chaque volume :
$ kubectl edit pvc data-nginx-0
Le manifeste YAML du PVC apparaîtra dans votre éditeur. Trouvez le spec.resources.requests.storage
champ et changez-le en votre nouvelle capacité souhaitée :
# ... spec: resources: requests: storage: 10Gi # ...
Enregistrez et fermez le fichier. Kubectl devrait signaler que la modification a été appliquée à votre cluster.
persistentvolumeclaim/data-nginx-0 edited
Répétez maintenant ces étapes pour les PVC restants du StatefulSet. La liste des volumes persistants de votre cluster doit alors afficher la nouvelle taille pour chacun :
$ kubectl get pv NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM pvc-0a0d0b15-241f-4332-8c34-a24b61944fb7 10Gi RWO Delete Bound default/data-nginx-2 pvc-33af452d-feff-429d-80cd-a45232e700c1 10Gi RWO Delete Bound default/data-nginx-0 pvc-49f3a1c5-b780-4580-9eae-17a1f002e9f5 10Gi RWO Delete Bound default/data-nginx-1
Les revendications conserveront l’ancienne taille pour le moment :
$ kubectl get pvc NAME STATUS VOLUME CAPACITY ACCESS MODES data-nginx-0 Bound pvc-33af452d-feff-429d-80cd-a45232e700c1 10Gi RWO data-nginx-1 Bound pvc-49f3a1c5-b780-4580-9eae-17a1f002e9f5 10Gi RWO data-nginx-2 Bound pvc-0a0d0b15-241f-4332-8c34-a24b61944fb7 10Gi RWO
En effet, le volume ne peut pas être redimensionné tant que les pods l’utilisent encore.
Recréer le StatefulSet
Terminez le redimensionnement en libérant la revendication de volume du StatefulSet qui la contient. Supprimez le StatefulSet mais utilisez le orphan
mécanisme en cascade afin que ses pods restent dans votre cluster. Cela aidera à minimiser les temps d’arrêt.
$ kubectl delete statefulset --cascade=orphan nginx statefulset.apps "nginx" deleted
Ensuite, modifiez votre fichier YAML d’origine pour inclure la nouvelle taille de volume dans le spec.resources.requests.storage
dossier. Utilisez ensuite kubectl apply
pour recréer le StatefulSet dans votre cluster :
$ kubectl apply -f ss.yaml service/nginx unchanged statefulset.apps/nginx created
Le nouveau StatefulSet assumera la propriété des pods précédemment orphelins, car ils répondront déjà à ses exigences. Les volumes peuvent être redimensionnés à ce stade, mais dans la plupart des cas, vous devrez lancer manuellement un déploiement qui redémarre vos pods :
$ kubectl rollout restart statefulset nginx
Le déploiement se déroule de manière séquentielle, ciblant un pod à la fois. Cela garantit que votre service reste accessible partout.
Vos PVC doivent maintenant afficher la nouvelle taille :
$ kubectl get pvc NAME STATUS VOLUME CAPACITY ACCESS MODES data-nginx-0 Bound pvc-33af452d-feff-429d-80cd-a45232e700c1 10Gi RWO data-nginx-1 Bound pvc-49f3a1c5-b780-4580-9eae-17a1f002e9f5 10Gi RWO data-nginx-2 Bound pvc-0a0d0b15-241f-4332-8c34-a24b61944fb7 10Gi RWO
Essayez de vous connecter à l’un de vos pods pour vérifier que l’augmentation de capacité est visible de l’intérieur :
$ kubectl exec -it nginx-0 bash root@nginx-0:/# df -h /usr/share/nginx/html Filesystem Size Used Avail Use% Mounted on /dev/disk/by-id/scsi-0DO_Volume_pvc-33af452d-feff-429d-80cd-a45232e700c1 9.9G 4.5M 9.4G 1% /usr/share/nginx/html
Le pod signale les 10 Gio de stockage attendus.
Sommaire
Les StatefulSets Kubernetes vous permettent d’exécuter des applications avec état dans Kubernetes avec des volumes de stockage persistants limités à des pods individuels. Cependant, la flexibilité que cela permet prend fin lorsque vous devez redimensionner l’un de vos volumes. Il s’agit d’une fonctionnalité manquante qui nécessite actuellement plusieurs étapes manuelles à suivre en séquence.
Les mainteneurs de Kubernetes sont conscients du problème. Il existe une demande de fonctionnalité ouverte pour développer une solution qui devrait éventuellement vous permettre d’initier des redimensionnements de volume en modifiant le manifeste d’un StatefulSet. Ce sera beaucoup plus rapide et plus sûr que la situation actuelle.
Une dernière mise en garde est que les redimensionnements de volume dépendent d’un pilote de stockage qui permet une expansion dynamique. Cette fonctionnalité n’est devenue généralement disponible que dans Kubernetes v1.24 et tous les pilotes, distributions Kubernetes et plates-formes cloud ne la prendront pas en charge. Vous pouvez vérifier si le vôtre le fait en exécutant kubectl get sc
et à la recherche true
dans le ALLOWVOLUMEXPANSION
colonne du pilote de stockage que vous utilisez avec vos StatefulSets.