For AI agents: the complete documentation index is available at https://docs.ovhcloud.com/fr/llms.txt, the full documentation bundle is available at https://docs.ovhcloud.com/fr/llms-full.txt, and this page is available as Markdown at https://docs.ovhcloud.com/fr/guides/public-cloud/containers-orchestration/managed-kubernetes/formating-nvme-disk-iops-nodes.md.

Formater des disques NVMe sur des nœuds IOPS

Voir en Markdown

Découvrez comment partitionner et formater des disques NVMe sur des nœuds IOPS OVHcloud Managed Kubernetes

Lorsque vous commandez des nœuds IOPS pour votre cluster OVHcloud Managed Kubernetes, les disques NVMe ne sont ni partitionnés ni formatés, et ne peuvent donc pas être utilisés pour créer des volumes persistants Kubernetes. Ce tutoriel vous guide pas à pas pour partitionner et formater facilement vos disques NVMe, sur vos nœuds existants comme sur les futurs.

Pourquoi utiliser des nœuds IOPS Kubernetes ?

Les nœuds IOPS Kubernetes sont très utiles pour exécuter des applications fortement dépendantes des performances disque, car les nœuds IOPS disposent d'un ou plusieurs disques SSD NVMe locaux. Des applications comme Elasticsearch pour l'indexation ou Spark pour le big data en sont de bons exemples.

Avant de commencer

Ce tutoriel suppose que vous disposez déjà d'un cluster OVHcloud Managed Kubernetes fonctionnel et de connaissances de base sur son fonctionnement. Pour en savoir plus sur ces sujets, consultez la documentation sur le déploiement d'une application Hello World.

Créer un daemonset pour partitionner et formater les disques NVMe disponibles

Pour vous assurer que tous vos nœuds disposant de disques NVMe sont correctement préparés, vous allez créer un daemonset. Ce daemonset crée un nouveau pod sur chaque nœud du cluster portant le label disktype=nvme. Si le nœud est un nœud IOPS et que les disques NVMe ne sont pas déjà partitionnés, le pod procède au partitionnement et au formatage des disques NVMe. Un des grands avantages de cette méthode est que, si vous ajoutez ultérieurement un nouveau nœud IOPS au cluster, le disque sera automatiquement préparé par le daemonset dès que vous ajouterez le label disktype=nvme au nouveau nœud.

Créez un fichier format-nvme-configmap.yaml :

apiVersion: v1
kind: ConfigMap
metadata:
  name: format-nvme-config
  namespace: kube-system
data:
  partition_number: "3"

Dans cet exemple, les disques NVMe sont répartis en 3 partitions de taille égale. Chaque partition pourra ensuite être associée à un volume persistant Kubernetes. Vous pourrez ainsi créer trois volumes persistants NVMe locaux par nœud. Si vous avez besoin de plus ou moins de partitions, modifiez le paramètre partition_number dans la définition de la configmap.

Créez la configmap :

kubectl apply -f format-nvme-configmap.yaml

Créez un fichier format-nvme-daemonset.yaml :

apiVersion: v1
kind: ConfigMap
metadata:
  name: format-nvme-script
  namespace: kube-system
data:
  format-nvme.sh: |
   #!/bin/bash
   set -e

   if [ -b /dev/nvme0n1 ] && [ ! -d /dev/nvme ]
   then
     echo "Installing LVM tools"
     apt-get -qq update
     apt-get -y -qq -o Dpkg::Options::="--force-confold" install lvm2
     echo "Disable LVM lock"
     sed -i 's/locking_type = 1/locking_type = 0/' /etc/lvm/lvm.conf

     pv_list=""
     for disk_name in /dev/nvme[0-9]n1
     do
       echo "Creating physical volume for $disk_name"
       pvcreate "$disk_name"
       pv_list="$pv_list$disk_name "
     done

     echo "Creating virtual group nvme"
     vgcreate nvme $pv_list

     PERCENT=$(( 100 / PARTITION_NUMBER ))

     for i in $(seq 1 "$PARTITION_NUMBER")
     do
       echo "Creating logical volume nvme$i"
       lvcreate -Zn -n "nvme$i" -l $PERCENT%VG nvme
       while [ ! -b "/dev/nvme/nvme$i" ]
       do
         echo "Wait for logical volume /dev/nvme/nvme$i"
         sleep 1
       done
       echo "Creating filesystem ext4 on nvme$i"
       mkfs -t ext4 "/dev/nvme/nvme$i"
     done

     echo "Enable LVM lock"
     sed -i 's/locking_type = 0/locking_type = 1/' /etc/lvm/lvm.conf
   fi

---

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: format-nvme
  namespace: kube-system
  labels:
    k8s-app: format-nvme
spec:
  selector:
    matchLabels:
      name: format-nvme
  template:
    metadata:
      labels:
        name: format-nvme
    spec:
      nodeSelector:
        disktype: nvme
      containers:
      - name: format-nvme
        image: ubuntu
        command: ["/bin/sh","-c"]
        args: ["/script/format-nvme.sh; while true; do echo Sleeping && sleep 3600; done"]
        env:
          - name: PARTITION_NUMBER
            valueFrom:
              configMapKeyRef:
                name: format-nvme-config
                key: partition_number
        volumeMounts:
          - name: format-nvme-script
            mountPath: /script
          - name: dev
            mountPath: /dev
          - name: etc-lvm
            mountPath: /etc/lvm
        securityContext:
          allowPrivilegeEscalation: true
          privileged: true
      volumes:
        - name: format-nvme-script
          configMap:
            name: format-nvme-script
            defaultMode: 0755
        - name: dev
          hostPath:
            path: /dev
        - name: etc-lvm
          hostPath:
            path: /etc/lvm

Puis déployez le daemonset sur le cluster :

kubectl apply -f format-nvme-daemonset.yaml

À ce stade, le daemonset ne doit avoir démarré aucun pod dans votre cluster, car aucun de vos nœuds ne porte le label disktype=nvme.

Ajoutez le label disktype=nvme sur vos nœuds IOPS pour remédier à cela. Dans cet exemple, les nœuds IOPS se nomment node-nvme-1 et node-nvme-2 ; adaptez cette commande à votre configuration.

kubectl label nodes node-nvme-1 node-nvme-2 disktype=nvme

Vous devriez maintenant avoir un pod format-nvme en cours d'exécution sur chaque nœud du cluster portant le label disktype=nvme :

kubectl get pod -n kube-system -l 'name=format-nvme' -o wide

En interne, tous vos nœuds IOPS devraient désormais avoir trois partitions /dev/nvme/nvme1, /dev/nvme/nvme2 et /dev/nvme/nvme3 créées sur leur disque NVMe, et ces partitions devraient être de taille égale.

Créer et utiliser un volume persistant NVMe local

Vous devez d'abord créer une nouvelle storage class. Créez un fichier local-nvme-storage-class.yaml :

kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: local-nvme
provisioner: kubernetes.io/no-provisioner
allowVolumeExpansion: true
volumeBindingMode: Immediate

Puis appliquez-la à votre cluster :

kubectl apply -f local-nvme-storage-class.yaml

Créez ensuite un nouveau volume persistant sur la première partition de votre premier nœud IOPS, en utilisant votre storage class NVMe locale. Dans cet exemple, le nœud se nomme node-nvme-1 et la partition utilisée est la première, /dev/nvme/nvme1 ; adaptez cela à votre configuration. Pour cela, créez un fichier local-nvme-persistent-volume.yaml :

apiVersion: v1
kind: PersistentVolume
metadata:
  name: local-pv
spec:
  capacity:
    storage: 50Gi
  accessModes:
  - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  storageClassName: local-nvme
  local:
    path: /dev/nvme/nvme1
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: kubernetes.io/hostname
          operator: In
          values:
          - node-nvme-1

Puis appliquez-le pour créer le volume persistant :

kubectl apply -f local-nvme-persistent-volume.yaml

Vous devez ensuite créer une revendication de volume persistant (persistent volume claim). Créez un fichier local-nvme-persistent-volume-claim.yaml :

kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: local-pvc
spec:
  accessModes:
  - ReadWriteOnce
  storageClassName: local-nvme
  resources:
    requests:
      storage: 50Gi

Puis appliquez-le pour créer une revendication de 50Gi :

kubectl apply -f local-nvme-persistent-volume-claim.yaml

Créez maintenant un pod Nginx utilisant la revendication de volume persistant comme dossier racine web (webroot). Pour cela, créez un fichier local-nvme-nginx-pod.yaml :

apiVersion: v1
kind: Pod
metadata:
  name: local-nvme-nginx
spec:
  volumes:
    - name: local-volume
      persistentVolumeClaim:
        claimName: local-pvc
  containers:
    - name: local-volume-container
      image: nginx
      ports:
        - containerPort: 80
          name: "http-server"
      volumeMounts:
        - mountPath: "/usr/share/nginx/html"
          name: local-volume

Puis déployez le pod Nginx :

kubectl apply -f local-nvme-nginx-pod.yaml

Accédez au conteneur Nginx pour créer un fichier sur le volume persistant NVMe :

kubectl exec -it local-nvme-nginx -- bash

Créez un nouveau fichier index.html :

echo "NVMe disk!" > /usr/share/nginx/html/index.html

puis quittez le conteneur Nginx :

exit

Vérifiez ensuite l'accès à votre nouvelle page web :

kubectl proxy

et ouvrez l'URL http://localhost:8001/api/v1/namespaces/default/pods/http:local-nvme-nginx:/proxy/

Vérifiez maintenant la persistance des données en supprimant le pod Nginx actuel :

kubectl delete -f local-nvme-nginx-pod.yaml

Puis recréez-en un nouveau :

kubectl apply -f local-nvme-nginx-pod.yaml

Vous devez maintenant vérifier que votre page web est toujours accessible :

kubectl proxy

et accédez à la même URL http://localhost:8001/api/v1/namespaces/default/pods/http:local-nvme-nginx:/proxy/

Nettoyer votre cluster

Supprimez le pod Nginx utilisé pour les tests :

kubectl delete -f local-nvme-nginx-pod.yaml

Supprimez la revendication de volume persistant utilisée pour les tests :

kubectl delete -f local-nvme-persistent-volume-claim.yaml

Enfin, supprimez le volume persistant utilisé pour les tests :

kubectl delete -f local-nvme-persistent-volume.yaml

Bien que le volume persistant soit supprimé du cluster Kubernetes, les données restent présentes sur le disque du nœud.

Identifiez le nom du pod format-nvme en cours d'exécution sur votre nœud node-nvme-1 :

kubectl get pods -n kube-system -o wide -l 'name=format-nvme' --field-selector spec.nodeName=node-nvme-1
$ kubectl get pods -n kube-system -o wide -l 'name=format-nvme' --field-selector spec.nodeName=node-nvme-1
NAME                READY   STATUS    RESTARTS   AGE     IP         NODE              NOMINATED NODE   READINESS GATES
format-nvme-ct84s   1/1     Running   0          8m13s   10.2.0.6   node-nvme-1

Puis accédez au conteneur :

kubectl exec -it format-nvme-ct84s -n kube-system -- bash

Vous pouvez maintenant reformater le volume logique /dev/nvme/nvme1 :

mkfs -t ext4 /dev/nvme/nvme1

Puis quittez le conteneur :

exit

Si vous ne prévoyez pas d'ajouter d'autres nœuds IOPS à votre cluster, supprimez le daemonset. Il reste bien sûr possible de le redéployer plus tard sans reformater automatiquement les partitions existantes.

kubectl delete -f format-nvme-daemonset.yaml
kubectl delete -f format-nvme-configmap.yaml

Aller plus loin

  • Si vous avez besoin d'une formation ou d'une assistance technique pour la mise en oeuvre de nos solutions, contactez votre commercial ou cliquez sur ce lien pour obtenir un devis et demander une analyse personnalisée de votre projet à nos experts de l’équipe Professional Services.

  • Échangez avec notre communauté d'utilisateurs.

Cette page vous a-t-elle aidé ?