Mardi 11 avril 2017 j’ai présenté « mgmt: next generation config management » aux HumanTalks Grenoble.

Cette présentation a été principalement réalisée à base de démo. Mais voici les différentes slides que j’ai présenté (très légèrement modifiés) avec quelques commentaires et surtout des vidéos des différentes démonstrations utilisées.

Note : la présentation durant 10 minutes, je ne suis pas rentré dans les détails, le but était juste de présenter un outil que probablement beaucoup ne connaissent encore pas.

Si vous voulez avoir directement les slides, vous pouvez les retrouver à la fin de l’article.

mgmt est un système de gestion de configuration, au même titre qu’Ansible, Puppet, Chef, etc. Néanmoins il est assez différent sur beaucoup d’aspects.

Il est réalisé par @purpleidea qui est employé par Red Hat.

En général il y a deux principaux modèles de fonctionnement au niveau des outils de gestion de configuration

Un agent sur chaque machine à configurer va, avec un intervalle de temps donné, contacter un serveur contenant la configuration pour savoir quoi faire.

Ou un orchestrateur va régulièrement pousser la configuration sur chacun des noeuds à opérer.

Globalement ces deux architectures sont très similaires et possèdent un certain nombre de problèmes.

Que ce passe-t-il si le serveur ou orchestrateur est indisponible ? (reboot pour mise à jour, impossible à joindre, crash, etc)

La configuration ne pourra pas être appliquée durant l’indisponibilité

Si on prend le cas de l’orchestrateur en exemple, on va vouloir réaliser des commandes au travers de ssh sur chacune des machines. Si on a quelques machines ça peut fonctionner. Mais une fois qu’on commence à en avoir un nombre conséquent, est-ce vraiment une bonne idée ? Quelles sont les limites de parallélisation possibles ? Quelle durée pour appliquer une configuration ?

Attention je ne dis pas que ça ne peut pas scaler, juste que ce n’est pas nécessairement trivial

Et d’ailleurs, alors qu’il est aujourd’hui facile de disposer de clusters (par exemple avec CoreOS) l’approche de se connecter à chaque machine est-elle encore valable ?

Vous voulez vraiment attendre une heure que vos changements soient appliqués ? Alors même qu’on met en oeuvre des orchestrateurs pour déployer des services en quelques secondes ?

Imaginez plutôt qu’on puisse avoir des changements en temps réel : on parle de délais inférieurs à la seconde, du même ordre de grandeur que les autres composants que vous opérez, containers, serverless, etc.

Pour commencer, prenons un example tout simple. Voici un fichier yaml qui va décrire la configuration. Pour info, ce format sera probablement changé par la suite.

---
graph: mygraph
resources:
  file:
  - name: file1
    path: "/tmp/mgmt/f1"
    content: |
      i am f1
    state: exists
  - name: file2
    path: "/tmp/mgmt/f2"
    content: |
      i am f2
    state: exists
  - name: file3
    path: "/tmp/mgmt/f3"
    content: |
      i am f3
    state: exists
  - name: file4
    path: "/tmp/mgmt/f4"
    content: |
      i am f4 and i should not be here
    state: absent

Ce fichier file1.yaml décrit trois fichiers /tmp/mgmt/f1, /tmp/mgmt/f2 et /tmp/mgmt/f3 ainsi que leurs contenu. Il décrit égalemment que /tmp/mgmt/f4 sera absent.

Dans la vidéo qui suit, vous pouvez voir que /tmp/mgmt/ est dans un premier temps vide. Au lancement de mgmt les trois fichiers vont être créés.

Dans un second temps on peut voir que modifier les fichiers n’a pas d’impact visible, y compris en rafraichissant la liste de fichiers leur contenu toutes les 0.1 seconde.

On remarque aussi qu’il nous est impossible de rajouter un fichier f4, dès qu’il est détecté par mgmt celui-ci le supprime aussi tôt.

Dernier détail sur cet aspect, mgmt surveille égalemment son fichier yaml de config. Ainsi si le contenu est modifié, l’état est automatiquement changé. Voici par exemple la modification du contenu d’un des fichiers créé par mgmt au travers du fichier de configuration.

Dans cette démonstration, 3 machines vont être simulées. Elles sont différentiées par le paramètre --hostname de mgmt et par leur répertoire de travail, /tmp/mgmtA, /tmp/mgmtB et /tmp/mgmtC

Chaque machine va créer un fichier et va permettre aux autres de récupérer ce fichier.

Les machines vont être lancées successivement pour bien voir ce qui va se passer :

  • au lancement de la première machine, un fichier va être créé dans /tmp/mgmtA
  • au lancement de la deuxième machine, un fichier va être créé dans /tmp/mgmtB, fichier qui va aussi se retrouver dans /tmp/mgmtA tout comme le fichier de la première machine va se retrouver dans l’emplacement de la deuxième
  • la troisième machine va rajouter un fichier dans /tmp/mgmtC et chaque machine va maintenant avoir les 3 fichiers

Toute cette synchronisation est réalisée de pair à pair, sans intervention d’un serveur central ou d’un orchestrateur. Cette synchronisation passe par etcd qui est un système de clé/valeur distribué.

Voici le fichier de la première machine, les autres étant similaires:

---
graph: mygraph
resources:
  file:
  - name: "@@filea"
    path: "/tmp/mgmtA/fA"
    content: |
      i am fA, exported from host A
    state: exists
collect:
- kind: file
  pattern: "/tmp/mgmtA/"
edges: []

La communication entre les différents mgmt se fait grace à --seeds qui va indiquer le serveur etcd à utiliser.

mgmt crée son propre cluster etcd mais il est possible d’utiliser un cluster etcd existant. C’est une solution lorsqu’on utilise déjà des clusters CoreOS par exemple.

Dans la vidéo qui suit vous pouvez voir l’exécution des trois mgmt et les différents fichiers apparaissant dans les trois environnements.

Cette différence de fonctionnement, via etcd et donc une discussion de pair à pair au lieu du passage par un point central est une importante différence de fonctionnement par rapport aux autres solutions. Et si vous opérez déjà des clusters cela vous semblera aussi terriblement logique !

Dans cette dernière démonstration on va pouvoir créer un service au niveau de systemd. Le service va être composé d’un fichier de service ainsi que du contrôle de ce service:

---
graph: svc
resources:
  file:
  - name: mgmt-test.service
    path: "/etc/systemd/system/mgmt-test.service"
    content: |
      [Unit]
      Description=Test service

      [Service]
      ExecStart=/bin/sh -c "while true; do echo plop; sleep 2s; done"
  svc:
  - name: mgmt-test
    state: running
    startup: enabled

La partie svc va s’assurer que le service mgmt-test (dont la description est dans le fichier juste au dessus) est bien exécuté.

Le point critique à comprendre est surtout que, comme pour les fichiers, mgmt va s’assurer que l’état ne change pas. Si on arrête le service, mgmt va le détecter et appliquer la correction, à savoir que le service va être redémarré. Attention tout de même, ça peut être perturbant quand, pour des question de debug, vous tentez d’arrêter un service directement sur une machine…

Il faut par contre noter que la gestion des services est pour le moment assez réduite, entre autre un changement du fichier de service ne va pas redémarrer le service correspondant.

mgmt est (très) jeune. Il n’en est pas encore à une version 0.1. Néanmoins nous croyons beaucoup dans son potentiel ! La manière proposée nous semble correspondre aux nouveaux besoins auxquels il faut faire face lorsqu’on opère de multiples clusters entre autre.

Un point hyper important à noter : il est très simple d’aller discuter de mgmt avec son créateur, que ce soit au travers d’irc #mgmtconfig, github ou twitter.

specifiquement marquées pour quiconque voudrait contributer facilement
#mgmtlove
our quiconque voudrait contributer facilement
#mgmtlove

Slides

Si vous préférez voici la version pdf.