A la découverte de CoreOS

coreosLe choix d’un OS pour une VM se limite souvent à ceux que nous connaissons pour les serveurs physiques : Ubuntu, RHEL, CentOS.

Ça fonctionne mais je suis sûr qu’il est possible de trouver mieux. N’y a-t-il pas un OS plus adapté aux VM en environnement cloud ?

Habituellement, pour fabriquer votre VM avec l’OS de votre choix, vous faites ainsi : l’installer dans une VM, faire une image de cette dernière, cloner cette image.

Mise à jour ? Gestion de packages ? déploiement d’applications ? Comme d’habitude : vous utilisez votre orchestrateur favoris qui s’interface avec le gestionnaire de package et le déployeur d’applications.

Mais les VM dans le cloud ne sont pas comme des serveurs « normaux » : il peut y en avoir beaucoup, elles sont très volatile, et n’oublions pas l’existence de Docker et autres conteneurs. Et vous commencez à sentir que vos vieux outils ne sont plus très adaptés à ces OS tournant dans des datacenters, surtout si vous voulez que votre architecture soit rapidement scalable.

Et c’est ici qu’arrive CoreOS.

Basé sur Chrome OS la première image a été diffusée le 25/07/2013. Il a pour but avoué d’être un OS taillé pour les VM, et spécialement conçu pour Docker (qui est inclus d’office dans la distribution)

En quelques mots, CoreOS est :

  • Minimaliste : ne sont installés que les composants nécessaires pour faire tourner les containers pour vos applications.
  • Fiable : j’en parlerai plus tard, mais disons pour l’instant que les mises à jour se font automatiquement.

CoreOS peut tourner sur n’importe quelle plateforme de virtualisation et fournisseur cloud. Tout se fait par le réseau. La documentation, très bien faite, vous guide dans tout le processus.

Cool !

L’installation est facile, et vous vous retrouvez rapidement avec un OS qui tourne.

Voici ce que dit la commande ps :

   1 ?        Ss     0:01 /usr/lib/systemd/systemd --switched-root --system --deserialize 19
  372 ?        Ss     0:00 /usr/lib/systemd/systemd-journald
  398 ?        Ss     0:00 /usr/lib/systemd/systemd-udevd
  449 ?        Ss     0:00 /usr/lib/systemd/systemd-logind
  453 ?        Ss     0:00 /usr/sbin/ntpd -g -n -u ntp:ntp -f /var/lib/ntp/ntp.drift
  460 ?        Ss     0:00 /usr/bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation
  473 ?        Rsl    0:14 /usr/sbin/update_engine -foreground -logtostderr -no_connection_manager
  478 ?        Ss     0:00 /usr/lib/systemd/systemd-resolved
  510 ?        Ssl    0:00 /usr/lib/locksmith/locksmithd
  554 ?        Ssl    0:00 /usr/bin/etcd
  555 tty1     Ss+    0:00 /sbin/agetty --noclear tty1 linux
  559 ?        Ssl    0:03 /usr/bin/fleetd
  661 ?        Ss     0:00 /usr/lib/systemd/systemd-networkd

Comme précisé plus haut, CoreOS est conçu pour le cloud. L’installer sur une seule VM n’a donc pas vraiment d’intérêt, et la documentation vous incite à en lancer au moins trois. Mais à quoi servent trois VM, même équipées de Docker ? Après tout, je n’aurai que … trois VM indépendantes qui tournent, comme quand je les installais avec Ubuntu/Centos/…

Et c’est ici qu’arrivent ce qui fait la force de CoreOS : etcd et fleet.

Les deux sont écrit en Go et développés par les équipes de CoreOS mais peuvent être compilés sur votre distribution Linux favorite.

Pour résumer comment tout ceci s’articule :

CoreOS

etcd

etcd est un magasin de stockage clé-valeur en haute dispo (à l’aide du protocole Raft), distribué et résilient. Son but est de partager des données entre toutes les instances de CoreOS, pour peu qu’elles utilisent etcd. Écrire et récupérer des données dans etcd se fait en utilisant l’API REST sur un des clients. Notez qu’etcd tourne sur l’hôte et non pas dans le conteneur.

etcd possède des fonctionnalité intéressantes, telles que : TTL sur des entrées ou des répertoires, attente qu’une entrée change et historique des changements, ordonnancement des clés afin de simuler une queue, répertoires cachés, statistiques sur le cluster etcd ou juste un noeud, et encore plus.

Avec un tel outils, il devient possible de diffuser une configuration sur tous les hôtes sans avoir besoin d’installer un autre logiciel.

core@core-02 ~ $ curl -X PUT -L http://127.0.0.1:4001/v2/keys/hello -d value="world"
{"action":"set","node":{"key":"/hello","value":"world","modifiedIndex":9664,"createdIndex":9664}}
core@core-03 ~ $ curl -L http://127.0.0.1:4001/v2/keys/hello
{"action":"get","node":{"key":"/hello","value":"world","modifiedIndex":9513,"createdIndex":9513}}

Mais vous pouvez aussi utiliser etcdctl :

core@core-03 ~ $ etcdctl set /hello you
you
core@core-02 ~ $ etcdctl get /hello
you

Bon, j’ai mes hôtes qui partagent des données. J’ai des conteneurs Docker qui tournent sur chacun de mes hôtes. Mais mes conteneurs sont un peu « collés » à mes hôtes, je trouve ; CoreOS me semble un OS éminemment versatile : je peux l’installer très vite, etcd me permet de partager mes données entre tous, alors pourquoi mes conteneurs ne semblent pas aussi mobiles ?

fleet

fleet contrôle le démon systemd des instances CoreOS via d-bus, et est accessible par socket (Unix ou réseau). Il utilise etcd (celui qui écoute sur localhost, par défaut) pour communiquer avec les autres instances fleet sur les autres hôtes.

Systemd est une alternative au système de démarrage hérité de System V, mais il fait plus de choses. En discuter ne fait pas partie du sujet de cet article, mais retenez juste qu’il remplace les scripts shell par des fichiers de configuration appelés « units ».

Fleet déploie les units (et les conteneurs Docker peuvent être gérés par des units) selon certaines stratégies :

  • Déploiement des units sur tous les hôte qui font tourner fleet. Ce sont les global units.
  • Déploiement d’une unit sur un hôte si une certaine unit n’y est pas. Utile pour la haute dispo.
  • Ou au contraire, forcer deux units à tourner sur le même hôte.
  • Déploiement d’une unit sur un hôte taggé : chaque démon fleet peut être taggé afin de le catégoriser : position géographique, fonction, … Ces tags peuvent être positionnés via cloud-config.

Quand vous ne faites rien de particulier, si vous demandez à fleet de faire tourner une unit, il le fait sur l’hôte sur lequel vous êtes. Si vous détruisez (ou éteignez) cet hôte, l’unit (le service, donc) sera lancé sur un autre hôte sans que vous n’ayez à faire quoi que ce soit.

Bien sûr, vous pouvez voir sur quel hôte tourne votre unit.

Un petit tour dans notre cluster fleet :

core@core-01 ~ $ fleetctl list-machines
MACHINE         IP              METADATA
1aaab8e5...     172.17.8.102    -
379ba5b7...     172.17.8.101    -
57d0cc63...     172.17.8.103    -

Voici mon fichier unit. C’est celui fourni comme exemple dans la doc CoreOS :

core@core-01 ~ $ cat m.service
[Unit]
Description=MyApp
After=docker.service
Requires=docker.service

[Service]
TimeoutStartSec=0
ExecStartPre=-/usr/bin/docker kill busybox1
ExecStartPre=-/usr/bin/docker rm busybox1
ExecStartPre=/usr/bin/docker pull busybox
ExecStart=/usr/bin/docker run --name busybox1 busybox /bin/sh -c "while true; do echo Hello World; sleep 1; done"
ExecStop=/usr/bin/docker stop busybox1

Lançons-le :

core@core-01 ~ $ fleet start m.service

Voyons voir où il tourne :

core@core-01 ~ $ fleetctl list-unit-files
UNIT            HASH    DSTATE          STATE           TARGET
m.service       391d247 launched        launched        379ba5b7.../172.17.8.101

172.17.8.101 est l’IP de l’hôte sur lequel je suis.

Tuons-le :

Capture d’écran 2014-11-05 à 11.29.13

Attendons un peu (quelques secondes) puis, sur un autre hôte :

core@core-02 ~ $ fleetctl list-unit-files
UNIT HASH DSTATE STATE TARGET
m.service 391d247 launched launched 1aaab8e5.../172.17.8.102

Mon service s’est déplacé !

Mais pas ses données. Pour ça, vous pouvez jeter un œil à flocker, qui fait de la migration de données d’environnements conteneurisés.

Bon, mes conteneurs se déplacent enfin, je peux jouer avec (et d’un coup j’ai envie de mettre CoreOS sur  une armée de Raspberry Pi), mais que puis-je faire avec les hôtes ?

Mise à jour automatique

Pour faire court : rien de plus.

En plus long : et ce n’est pas le but. CoreOS et conçu pour que jouiez avec des conteneurs. L’équipe de CoreOS veut que vous vous concentriez sur les conteneurs, et ils s’occupent de l’hôte. Il n’y a ni man page ni gestionnaire de paquet. Frustrant, non ?

En fait, il y a exactement ce dont vous avez besoin, pas plus pas moins et la mise à jour est faite automatiquement et de manière transparente. Toutes les briques sont là pour ça : vous vous occupez des conteneurs (leur vie, leur migration, leur mort), CoreOS gère le reste. Vous donnez juste quelques indications : redémarre l’hôte quand la mise à jour est effectuée, redémarre les hôtes un par un, ne redémarre pas. Rappelez-vous que fleet fait migrer vos conteneurs automatiquement (si vous utilisez fleet pour gérer vos conteneurs, bien sûr)

La mise à jour se fait en swappant entre une partition active et un partition passive. La mise à jour est installé sur la partition passive, au redémarrage elle devient active.

Doutes

Que se passe-t-il si CoreOS n’a pas accès à internet, comme c’est la plupart du temps le cas avec un cloud privé ? Peut-il être mis à jour ? Peut-il seulement fonctionner ?

Vu que CoreOS se met à jour tout seul, peut-on se passer de Chef /Puppet ?

D’un autre côté, je me sens mal à l’aise que ma distribution Linux appartiennent à une société, surtout quand cette dernière effectue les mises à jour elle-même. Que se passe-t-il si la société ferme ? Ou si ses repository sont piratés ? Même si les mises à jour sont signées, je n’aime pas l’idée de dépendre d’une seule entité pour l’update de mon OS. Ca me rappelle les doutes que j’avais à propos de RHN, qui, avec le temps, n’apparaissent plus justifiés …

Que fournit la société CoreOS ? Que puis-je attendre d’elle ? Je répondrai à ces questions dans un futur article.