Tutorial

Comment mettre en place des volumes persistants de ReadWriteMany (RWX) avec NFS sur les kubernetes de DigitalOcean

Block StorageKubernetesDigitalOcean Managed Kubernetes

Introduction

Avec la nature distribuée et dynamique des conteneurs, la gestion et la configuration statique du stockage est devenue un problème difficile sur les Kubernetes, les charges de travail pouvant désormais passer d'une machine virtuelle (VM) à une autre en quelques secondes. Pour y remédier, Kubernetes gère les volumes avec un système de volumes persistants (PV), d'objets API qui représentent une configuration/un volume de stockage, et de PersistentVolumeClaims (PVC), une demande de stockage à satisfaire par un volume persistant. En outre, les pilotes d'interface de stockage de conteneurs (CSI) peuvent aider à automatiser et à gérer la manipulation et l'approvisionnement du stockage pour les charges de travail conteneurisées. Ces pilotes sont chargés d'approvisionner, de monter, de démonter, de retirer et de photographier les volumes.

Le digitalocean-csi intègre un cluster Kubernetes avec le produit DigitalOcean Block Storage. Un développeur peut s'en servir pour fournir dynamiquement des volumes de stockage de blocs pour des apps conteneurisées dans Kubernetes. Cependant, les apps peuvent parfois exiger que les données soient persistantes et partagées entre plusieurs Droplets. La solution CSI de stockage de blocs par défaut DigitalOcean est incapable de supporter le montage d'un volume de stockage de blocs sur plusieurs Droplets simultanément. Cela signifie qu'il s'agit d'une solution de type ReadWriteOnce (RWO), puisque le volume est confiné à un seul node. Le protocole NFS (Network File System), en revanche, permet d'exporter la même part à de nombreux consommateurs. Ce système est appelé ReadWriteMany (RWX), car de nombreux nodes peuvent augmenter le volume en lecture-écriture. Nous pouvons donc utiliser un serveur NFS au sein de notre cluster pour fournir un stockage qui peut tirer parti du support fiable de DigitalOcean Block Storage avec la flexibilité des parts NFS.

Dans ce tutoriel, vous allez configurer le provisionnement dynamique pour les volumes NFS dans un cluster DigitalOcean Kubernetes (DOKS) dans lequel les exportations sont stockées sur des volumes de stockage DigitalOcean Block. Vous allez ensuite déployer plusieurs instances d'une application Nginx de démonstration et tester le partage des données entre chaque instance.

Conditions préalables

Avant de commencer ce guide, vous aurez besoin des éléments suivants :

  • L'interface de ligne de commande kubectl installée sur votre machine locale. Vous pouvez en savoir plus sur l'installation et la configuration de kubectl dans sa documentation officielle.

  • Un cluster DigitalOcean Kubernetes avec votre connexion configurée comme kubectl par défaut. Pour créer un cluster Kubernetes sur DigitalOcean, voir notre Kubernetes Quickstart. Les instructions sur la façon de configurer kubectl sont indiquées dans l'étape Se connecter à votre cluster lorsque vous créez votre cluster.

  • Le gestionnaire de paquets Helm installé sur votre machine locale, et Tiller installé sur votre cluster. Pour ce faire, suivez les étapes 1 et 2 du tutoriel Comment installer un logiciel sur les clusters de Kubernetes avec le gestionnaire de paquets de Helm.

Remarque : à partir de la version 3.0 de Helm, il n'est plus nécessaire d'installer Tiller pour que Helm fonctionne. Si vous utilisez la dernière version de Helm, consultez la documentation d'installation de Helm pour obtenir des instructions.

Étape 1 - Déployez le serveur NFS avec Helm

Pour déployer le serveur NFS, vous utiliserez un tableau Helm. Le déploiement d'un tableau Helm est une solution automatisée qui est plus rapide et moins sujette aux erreurs que la création manuelle du déploiement du serveur NFS.

Tout d'abord, assurez-vous que le dépôt de tableaux stable par défaut est à votre disposition en ajoutant le repo :

  • helm repo add stable https://kubernetes-charts.storage.googleapis.com/

Ensuite, tirez les métadonnées pour le dépôt que vous venez d'ajouter. Cela permettra d'assurer la mise à jour du client Helm :

  • helm repo update

Pour vérifier l'accès au repo stable, effectuez une recherche sur les tableaux :

  • helm search repo stable

Vous obtiendrez ainsi une liste des tableaux disponibles, semblables à ceux qui suivent :

Output
NAME CHART VERSION APP VERSION DESCRIPTION stable/acs-engine-autoscaler 2.2.2 2.1.1 DEPRECATED Scales worker nodes within agent pools stable/aerospike 0.3.2 v4.5.0.5 A Helm chart for Aerospike in Kubernetes stable/airflow 5.2.4 1.10.4 Airflow is a platform to programmatically autho... stable/ambassador 5.3.0 0.86.1 A Helm chart for Datawire Ambassador ...

Ce résultat signifie que votre client Helm fonctionne et est à jour.

Maintenant que vous avez configuré Helm, installez le tableau Helm nfs-server-provisioner pour configurer le serveur NFS. Si vous souhaitez examiner le contenu du tableau, jetez un œil à sa documentation sur GitHub.

Lorsque vous déployez le tableau Helm, vous allez définir quelques variables pour votre serveur NFS afin de préciser davantage la configuration de votre application. Vous pouvez également étudier d'autres options de configuration et les modifier pour les adapter aux besoins de l'application.

Pour installer le tableau Helm, utilisez la commande suivante :

  • helm install nfs-server stable/nfs-server-provisioner --set persistence.enabled=true,persistence.storageClass=do-block-storage,persistence.size=200Gi

Cette commande fournit à un serveur NFS les options de configuration suivantes :

  • Ajoute un volume persistant pour le serveur NFS avec le drapeau --set. Cela permet de s'assurer que toutes les données partagées par le NFS persistent lors des redémarrages des modules.
  • Pour le stockage persistant, utilise la classe de stockage do-block-storage.
  • Prévoit un total de 200Gi pour que le serveur NFS puisse être divisé en exportations.

Remarque : L'option persistence.size déterminera la capacité totale de tous les volumes de SNF que vous pouvez fournir. Au moment de cette publication, seules les versions 1.16.2-do.3 et ultérieures de DOKS prennent en charge l'expansion du volume. Le redimensionnement de ce volume sera donc une tâche manuelle si vous êtes sur une version antérieure. Si c'est le cas, assurez-vous de paramétrer cette taille en tenant compte de vos besoins futurs.

Une fois cette commande terminée, vous obtiendrez un résultat similaire à ce qui suit :

Output
NAME: nfs-server LAST DEPLOYED: Thu Feb 13 19:30:07 2020 NAMESPACE: default STATUS: deployed REVISION: 1 TEST SUITE: None NOTES: The NFS Provisioner service has now been installed. A storage class named 'nfs' has now been created and is available to provision dynamic volumes. You can use this storageclass by creating a PersistentVolumeClaim with the correct storageClassName attribute. For example: --- kind: PersistentVolumeClaim apiVersion: v1 metadata: name: test-dynamic-volume-claim spec: storageClassName: "nfs" accessModes: - ReadWriteOnce resources: requests: storage: 100Mi

Pour voir le serveur NFS que vous avez provisionné, exécutez la commande suivante :

  • kubectl get pods

Cela montrera ce qui suit :

Output
NAME READY STATUS RESTARTS AGE nfs-server-nfs-server-provisioner-0 1/1 Running 0 11m

Ensuite, vérifiez la storageclass que vous avez créée :

  • kubectl get storageclass

Cela donnera un résultat similaire à ce qui suit :

Output
NAME PROVISIONER AGE do-block-storage (default) dobs.csi.digitalocean.com 90m nfs cluster.local/nfs-server-nfs-server-provisioner 3m

Vous avez maintenant un serveur NFS qui fonctionne, ainsi qu'une storageclass que vous pouvez utiliser pour le provisionnement dynamique des volumes. Ensuite, vous pouvez créer un déploiement qui utilisera ce stockage et le partagera entre plusieurs instances.

Étape 2 - Déployez une demande au moyen d'un PersistentVolumeClaim partagé

Dans cette étape, vous allez créer un exemple de déploiement sur votre cluster DOKS afin de tester votre configuration de stockage. Il s'agira d'une application de serveur web Nginx appelée web.

Pour déployer cette application, il faut d'abord écrire le fichier YAML pour spécifier le déploiement. Ouvrez un fichier nginx-test.yaml avec votre éditeur de texte ; ce tutoriel utilisera nano :

  • nano nginx-test.yaml

Dans ce fichier, ajoutez les lignes suivantes pour définir le déploiement avec un PersistentVolumeClaim nommé nfs-data :

nginx-test.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: web
  name: web
spec:
  replicas: 1
  selector:
    matchLabels:
      app: web
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: web
    spec:
      containers:
      - image: nginx:latest
        name: nginx
        resources: {}
        volumeMounts:
        - mountPath: /data
          name: data
      volumes:
      - name: data
        persistentVolumeClaim:
          claimName: nfs-data
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: nfs-data
spec:
  accessModes:
  - ReadWriteMany
  resources:
    requests:
      storage: 2Gi
  storageClassName: nfs

Sauvegardez le fichier et quittez l'éditeur de texte.

Ce déploiement est configuré pour utiliser le PersistentVolumeClaim nfs-data qui l'accompagne et le monter dans /data.

Dans la définition du PVC, vous trouverez que le storageClassName est réglé sur nfs. Cela indique au cluster de satisfaire ce stockage en utilisant les règles du nfs storageClass que vous avez créé à l'étape précédente. La nouvelle demande de PersistentVolumeClaim sera traitée, puis une part de NFS sera provisionnée pour satisfaire la demande sous la forme d'un PersistentVolume. Le module tentera de monter ce PVC une fois qu'il aura été approvisionné. Une fois le montage terminé, vous vérifierez la fonctionnalité ReadWriteMany (RWX).

Exécutez le déploiement avec la commande suivante :

  • kubectl apply -f nginx-test.yaml

Cela donnera le résultat suivant :

Output
deployment.apps/web created persistentvolumeclaim/nfs-data created

Ensuite, regardez le module web tourner :

  • kubectl get pods

Il en résultera ce qui suit :

Output
NAME READY STATUS RESTARTS AGE nfs-server-nfs-server-provisioner-0 1/1 Running 0 23m web-64965fc79f-b5v7w 1/1 Running 0 4m

Maintenant que l'exemple de déploiement est opérationnel, vous pouvez l'étendre à trois instances en utilisant la commande kubectl scale :

  • kubectl scale deployment web --replicas=3

Cela donnera le résultat :

Output
deployment.extensions/web scaled

Maintenant, lancez à nouveau la commande kubectl get :

  • kubectl get pods

Vous trouverez les instances de déploiement à grande échelle :

Output
NAME READY STATUS RESTARTS AGE nfs-server-nfs-server-provisioner-0 1/1 Running 0 24m web-64965fc79f-q9626 1/1 Running 0 5m web-64965fc79f-qgd2w 1/1 Running 0 17s web-64965fc79f-wcjxv 1/1 Running 0 17s

Vous avez maintenant trois instances de votre déploiement Nginx qui sont connectées dans le même volume persistant. Dans l'étape suivante, vous veillerez à ce qu'ils puissent échanger des données entre eux.

Étape 3 - Validez le partage des données du SNF

Pour l'étape finale, vous validerez le fait que les données soient partagées entre toutes les instances qui sont montées sur le partage du NFS. Pour ce faire, vous allez créer un fichier sous le répertoire /data dans l'un des modules, puis vérifier que le fichier existe dans le répertoire /data d'un autre module.

Pour valider cela, vous utiliserez la commande kubectl exec. Cette commande permet de spécifier un module et d'exécuter une commande à l'intérieur de ce module. Pour en savoir plus sur l'inspection des ressources à l'aide de kubectl, consultez notre fiche de triche kubectl.

Pour créer un fichier nommé hello_world dans l'un de vos modules web, utilisez l'exécuteur kubectl pour transmettre la commande touch. Notez que le nombre après web dans le nom du module sera différent pour vous, donc assurez-vous de remplacer le nom du module surligné par un de vos propres modules que vous avez trouvé comme résultat de kubectl get pods au cours de la dernière étape.

  • kubectl exec web-64965fc79f-q9626 -- touch /data/hello_world

Ensuite, changez le nom du module et utilisez la commande ls pour lister les fichiers du répertoire /data d'un module différent :

  • kubectl exec web-64965fc79f-qgd2w -- ls /data

Votre sortie montrera le fichier que vous avez créé dans le premier module :

Output
hello_world

Cela montre que tous les modules partagent des données en utilisant NFS et que votre installation fonctionne correctement.

Conclusion

Dans ce tutoriel, vous avez créé un serveur NFS qui était soutenu par DigitalOcean Block Storage. Le serveur NFS a ensuite utilisé ce stockage en bloc pour fournir et exporter les parts NFS vers des charges de travail dans un protocole compatible RWX. Ce faisant, vous avez pu contourner une limitation technique du stockage en bloc de DigitalOcean et partager les mêmes données PVC sur de nombreux modules. En suivant ce tutoriel, votre cluster DOKS a pu être configuré pour accueillir un ensemble beaucoup plus large de cas d'utilisation de déploiement.

Si vous souhaitez en savoir plus sur Kubernetes, consultez notre programme Kubernetes pour les développeurs Full Stack, ou consultez la documentation produit de DigitalOcean Kubernetes.

Creative Commons License