Une bonne gestion des volumes NFS dans un cluster Docker Swarm

closeCet article a été publié il y a 4 ans 4 mois 18 jours, il est donc possible qu’il ne soit plus à jour. Les informations proposées sont donc peut-être expirées.

Quand j’ai monté mon cluster chez moi sur le micro serveur, j’ai fait pas mal de boulettes, au final, l’une des seules qui mérite encore vraiment des claques c’est ma gestion des volumes persistants. J’ai donc pris le temps de chercher comment tout refaire, et de vous partager tout ça car c’est pas si trivial, et ça a pris du temps pour tout identifier.

Pas besoin de rappeler qu’il vous faut des volumes pour gérer les données persistantes de vos containers docker. L’outil dispose même d’une fonction native, avec une extensibilité certaine pour pouvoir gérer tous les types de stockage possibles.

Mais quand je découvre un truc j’ai toujours tendance à commencer par faire de la grosse merde, et en l’occurrence je ne me suis pas servi tout de suite de cette fonction. À la place, j’ai créé un « gros » partage global sur mon NAS, que j’ai monté ensuite dans un dossier sur chaque machine du cluster; chaque « volume » est un dossier dans ce partage, et j’ai indiqué dans la déclaration de la stack le chemin vers ce dossier. Ouais je suis comme ça, parfois.

Mais j’avais un gros problème avec ça : lors de micro-coupures de courant, le serveur redémarre en moins de 30 secondes, pareil pour les VMs du cluster qui du coup tentent de relancer tous les services. Sauf que le NAS met trois bonnes minutes à démarrer, ce qui fait que les VMs démarrent sans leurs volumes, et donc les containers n’ont pas leurs données. Au mieux, ça redémarre à blanc, au pire ça plante en boucle. Quand tout est revenu, il faut que je redémarre chaque VM pour rétablir le service (j’ai même fait un playbook ansible pour ça…)

Docker volume et NFS, foire à la saucisse

L’idée est donc de conserver ces partages, mais de les redéfinir en tant que volume Docker, on sépare ainsi la gestion des volumes de celles des stacks, c’est plus propre, ça réduit la dépendance à l’OS sous-jacent, enfin bref, vous avez compris à quel point c’est mieux.

Au début, vu le peu de documentation je pensais qu’il fallait un plugin pour gérer quelque chose d’aussi basique que le NFS, j’avais même commencé à écrire le brouillon de cet article en ce sens. Et en fait non c’est bien géré en natif, ça a juste une « forme » dégueulasse. Tellement dégueulasse que rien que pour la déclaration des volumes, ça m’a pris plusieurs essais, notamment parce que contrairement aux services, les volumes déclarés dans une stack ne sont pas supprimés avec elle. Et si vous tentez de redéfinir un volume existant, ben il n’en tient pas compte et garde la définition existante. Qui est probablement moisie. Il faut donc, entre chaque essai, supprimer les volumes fautifs sur tous les nœuds du cluster.

Pratique non ?

Passons à la pratique

Attention, pensez à bien tout sauvegarder avant, on est jamais a l’abri d’un effet de bord malencontreux lorsqu’on modifie un stockage avec donc des permissions particulières.

Commençons par détailler l’existant. Pour l’exemple je vais prendre les volumes de smokeping, c’est le moins critique de tous. Voici le partage sur le NAS :

Et sur chaque vm, j’ai un dossier monté via /etc/fstab :

Aucun commentaire sur le chemin de destination s’il vous plaît 😀 Quant à la stack, les volumes sont déclarés et utilisés de la sorte :

Comme je l’ai dit, basique mais ça fonctionne, mais c’est pas pour autant que je suis content de cette situation. Le mieux est quand même de pouvoir monter uniquement le dossier au lancement du service, sans impact pour la VM en dessous.

On va donc déclarer chaque volume dans les stacks avec les options de montage directement. Parmi les contraintes à relever :

  • Version de compose minimum à 3.2 (j’utilisais généralement 3, donc insuffisant)
  • Le volume de destination, autrement dit le dossier, n’est pas créé automatiquement, il faut le créer manuellement en amont
  • Attention aux options, soft et nolock doivent être présents, sinon vous plantez docker en cas de problème avec le partage réseau (un peu con)

Là où j’ai galéré, c’est pour ce connard de NAS. En effet, vous avez vu, je monte /Docker depuis ce NAS, mais pour une raison que j’ignore, /Docker/registry ne fonctionne pas, alors qu’il est bien présent. Et pourtant j’en fait des palanquées des montages NFS comme ça, à cibler un sous-dossier, sur plusieurs environnements, Debian, CentOS, mix des deux, même de l’EFS AWS, c’est dire. Et ça, que je teste en v3 ou v4.

Il aura fallu plusieurs essais ratés, des recherches frustrantes, une investigation en SSH directement sur le NAS, pour finir par demander un point de vue extérieur sur le forum NXI, pour avoir la solution, une solution qui me convient dans la mesure où elle fonctionne mais pas dans la logique qu’on doit appliquer. En effet, pour accéder aux sous-dossiers directement via NFS, c’est /volume1/Docker qui doit service de base, et pas /Docker. Me demandez pas pourquoi, oui c’est /volume1/Docker qui est déclaré dans le fichier /etc/exports sur le NAS, mais j’ai toujours pas compris pourquoi monter /Docker fonctionne quand même.

Enfin bon, voici donc la même stack, adaptée avec des volumes NFS bien déclarés :

Quand Swarm lance un déploiement, il va créer un volume local sur le nœud sélectionné, dont le détail aura cette forme (via docker inspect) :

On retrouve bien nos éléments, et Docker gère le volume dans son arborescence comme un grand. On s’en occupe plus nous-même, c’est un peu mieux question erreurs possibles.

Road to Kubernetes

En soi, et depuis que j’ai l’onduleur, je n’ai plus de problèmes majeur avec le NFS, à part que sur un des nœuds, quand la VM redémarre, le montage NFS ne se fait pas (ses voisines avec strictement la même configuration n’ont pas ce problème). Du coup, il ne démarre dessus que les containers qui n’ont pas besoin de volume. Ça déséquilibre un peu la conso de RAM entre les VMs, mais c’est pas la mort.

L’objectif réel de tout ça est de pouvoir mettre à la retraite Docker Swarm pour jouer avec Kubernetes, via le projet K3S de Rancher qui est parfait pour les petites ressources de mon serveur (pour rappel on peu s’en servir sur un Raspberry Pi 3 ou 4). Je ne me voyais pas faire le sale à utiliser des volumes en host-path pour celui-ci, et pour exploiter déjà la solution NFS sur Azure parce que leurs outils de volumes sont à chier, ça marche très bien. En plus, avec cette syntaxe, je vais pouvoir tester d’utiliser Kompose pour faire le feignant et éviter d’écrire tous les manifestes à la main 🙂

Des alternatives au NFS ?

Si tant est que l’espace disque n’est pas une contrainte réelle sur les VMs (le SSD sous-jacent est pas non plus extensible à l’infini), il est possible d’utiliser d’autres solutions. Par exemple, l’homme qui a changé ma vie a publié un article sur Rook, qui se base sur une autre techno de stockage distribué, Ceph. Je suis tombé aussi sur Longhorn, un projet de stockage distribué au sein du cluster qui permet ensuite d’exporter sur un autre type de stockage. C’est encore un peu jeune, mais ça passera peut-être en test.

Une solution qu’a tenté aussi de me faire tester Nicolas Simond, c’est iSCSI. On sent le mec un peu trop habitué à VMWare 😀 Ceci dit, la techno est supportée sur Docker et Kubernetes donc vous pourriez éventuellement pouvoir l’exploiter en fonction de votre environnement. En parlant de VMware, j’ai vu un client nous demander si on pouvait supporter vSphere Storage for Docker, une extension pour gérer des volumes Docker sur les datastores VMware.

Tout ça pour dire que les options ne manquent pas pour vous adapter à votre environnement. Sur ce, j’ai mes autres stacks à refaire, je vous laisse 😉

8 Commentaires
Le plus ancien
Le plus récent
Commentaires en ligne
Afficher tous les commentaires
Djimmy
Djimmy
12/12/2019 12:24

Hey salut tu utilises quels types de souris ?

jotux
jotux
12/12/2019 13:48

Dans ton article, tu parles d’un « micro serveur ». Qu’entends-tu par là ? Un cluster de Raspberry ?
Peut-être en as-tu parlé avant, mais je n’ai pas trouvé d’article.
En tout cas, un article très détaillé qui s’apparente un peu à du chinois pour moi qui n’utilise pas du tout docker. 😉
Je suis plutôt LXC avec des points de montage « en dur ».
Merci !

jotux
jotux
13/12/2019 10:05
Répondre à  Seboss666

Merci pour ta réponse 😉 Effectivement, comme dit dans ton article sur ton micro serveur, le choix du pentium est étonnant. Mais je comprends très bien les problématiques de bruit, de chaleur et de consommation. Le principal c’est que ce soit dimensionné pour tes besoins. J’avais fait le choix il y a quelques temps, d’un I5 et d’un boitier Lian-li en alu, qui permet un bon refroidissement de l’ensemble. Mais par contre ce n’est pas le plus silencieux à cause des disques durs. Je n’ai pas de nas à côté, c’est cette même machine sur laquelle j’ai des partages réseau… Lire la suite »

Dough
25/02/2020 18:36

Hello ! Je débarque du blog de Zwindler et je tombe sur ce sujet très intéressant et qui me concerne pleinement : je fais aussi des montages NFS via fstab sur mes nodes… **beurk** Je viens de modifier un 1er service pour passer sur la méthode décrite ici : ça fonctionne au poil et c’est effectivement beaucoup plus propre ! Au passage j’avais testé le driver docker-volume-netshare pour les accès NFS aussi et je vous le déconseille grandement : j’ai eu des comportements aléatoires où le conteneur se voyait alloué la racine du share NFS = selon ce que fait… Lire la suite »

Fremul0n
Fremul0n
11/03/2020 17:03

Hello! Merci de ton article super intéressant!
J’ai une question relative au passage suivant;
> Attention aux options, soft et nolock doivent être présents, sinon vous plantez docker en cas de problème avec le partage réseau (un peu con)

Si le mount est essentiel, genre config, est-ce qu’il ne vaut pas mieux que le service ne foire plutôt que de rester dans un état inutilisable?
A+