Containerus Bellum, ou la chronique des hostilités dans l’écosystème Docker

Saison 1 : Previously…

Dans les épisodes précédents, nous avions vu naître la guerre sanglante des orchestrateurs de containers. Les deux principaux candidats à la première place étaient Docker Swarm et Kubernetes. Le premier, simple et limité, est porté par la jeune startup éponyme : Docker Inc. Le second, puissant et complexe, est soutenu par l’alliance d’un géant du Web et d’un mastodonte de l’open source : Google et Red Hat.

Le premier tour des débats avait porté sur le format de la brique de containerisation en elle-même. Google, par la main de CoreOS, avait tenté de déstabiliser l'hégémonie de Docker Container Engine en lançant rkt (Rocket) comme un contre-pouvoir.

L’Open Container Initiative (OCI) était un autre croche-pied fait à la jeune Docker Inc. En effet, derrière la noble idée de constituer un standard de conteneurisation à la fois universel et indépendant, la réalité pour Docker Inc. a été plus épineuse. La publication des spécifications et l’émergence des premières implémentations s’est faite au détriment de la vélocité habituelle de la startup pour le développement de nouvelles features.

Saison 2 - La cigale est devenue fourmi

Si l’argent ne fait pas le bonheur, il n’en reste pas moins le nerf de la guerre. Étonnamment, c’est assez tardivement que Docker Inc. s’est soucié de cette question (“l’intendance suivra” comme disait le Général de Gaulle). Victime de son succès, la startup se retrouve propulsée en orbite via une valorisation boursière vertigineuse d’un milliard de dollars et des levées de fonds successives formant un trésor de guerre de près de 180 millions de dollars. Seul bémol, le business model basé sur la vente de support sur l’Engine et la formation ne génère pas les revenus à hauteur des espérances (et de la probable pression des investisseurs sur la rentabilité).

Nous sommes à San Francisco le 22 juin 2015, il fait 21°C.

C’est par cette douce après-midi d’été que Solomon Hykes annonce le lancement du projet ORCA à son événement alors biannuel : la DockerCon. ORCA, c’est le nom de code d’un produit qui deviendra Docker Universal Control Plane (UCP), puis il sera packagé dans la suite Docker Datacenter.

La startup se dote enfin d’un produit commercial à destination des grands comptes. L’ambition affichée est d’offrir une solution clé en main pour faire du Docker en production, “pour de vrai”.

Oui mais voilà, vendre aux grandes entreprises ne s’improvise pas. Il faut une force de vente aguerrie, un véritable réseau chez les grands-comptes et une capacité à fournir un effort d’avant-vente et de support soutenu.

C’est probablement à ce moment-là de l’histoire que les choses ont commencé à basculer pour Docker Inc. : la cigale est devenue fourmi.

La jeune startup, autrefois un peu idéaliste, dont le leitmotive était d’offrir gracieusement des exploits techniques qui changent le monde, s’est confronté aux dures réalités qu’imposent la rentabilité. Si la recherche de croissance est l’essence même d’une startup, il n’en demeure pas moins que Docker a fait l’un des changements de cap les plus conséquents de son histoire.

Lorsque le business se mêle de la technique

Conscient du retard fonctionnel accumulé sur son orchestrateur Swarm, Docker Inc. a tenté un coup d’éclat pour rendre ce dernier incontournable et conserver ses parts de marché. Ainsi, en prenant la décision de fusionner Swarm dans le coeur du Docker Engine (dans sa release 1.12), l’entreprise s’est attirée les foudres de la communauté.

Car c’est probablement au détriment de ses convictions techniques basées sur la philosophie UNIX (ne faire qu'une seule chose, et la faire bien), que Docker a basculé d’une stratégie de composant à une stratégie de produit. Docker passerait donc du slogan “Batteries included but removable” à “Batteries not removable but not enabled”.

La blogosphère ne manque pas d’articles expliquant comment des changements a priori anodins ont cassé les intégrations de Docker avec son écosystème au fur et à mesure des montées de version (voir références en bas de page). Docker Inc. s’est empêtré dans une schizophrénie délicate, tenter de conserver la compatibilité tout en opérant des changements (nécessaires au demeurant pour améliorer son offre).

Un des exemples frappants est l’évolution du comportement d’un même fichier Compose exécuté en local et sur un environnement distribué utilisant Docker Network. On passe d’une gestion des enregistrements via modification dynamique de  /etc/hosts  à un DNS dynamique. Cela peut avoir un impact important sur l’application, voire nécessiter de repackager l’image et l’application. Dommage, la promesse de la portabilité sans couture au sein de l’écosystème Docker Inc. en prend pour son grade.

Par ailleurs, Red Hat a dénoncé il y a peu, un recouvrement de fonctionnalités entre Docker Engine et systemd. Docker et Red Hat se reprochent mutuellement de tirer la couverture à soi. Selon eux, il ne peut y avoir qu’un gestionnaire de processus et chacun prétend fournir LA solution :

  • Docker avec une approche centrée sur les conteneurs, mais riche pour être portable au-delà des OS et des distributions Linux.
  • De son côté, Red Hat, fervent adepte de systemd, souhaite que le pilotage des conteneurs Docker soit le plus « synchrone » et basique possible pour laisser à systemd le soin de gérer finement les dépendances entre services.

Les API instables, des pages de documentation qui génèrent de la confusion (l’implémentation de Swarm historique vs Swarm Mode en est le plus bel exemple), alourdissement régulier du démon Docker, il n’en fallait pas plus pour que les menaces de forks du Docker Engine s’enchaînent sur Twitter.

C’est dans cet état d’esprit qu’est né OCID, une tentative de Red Hat pour proposer un remplaçant au démon Docker, utilisant la couche OCI et encapsulant RunC.

En réponse à cela, Docker a fraîchement annoncé la création de containerd. Outre une réponse à la menace de fork, il semble que cette annonce s’ancre dans un déplacement de fond des features des briques en question.

Là où Swarm était associé à des fonctions avancées comme l’orchestration et Docker Engine à un simple moteur d’exécution, il semblerait y avoir une translation : Docker Engine pourrait devenir le “vaisseau amiral” avec ses fonctions avancées (le Swarm Mode natif) et containerd la brique unitaire, utilisable par des orchestrateurs de plus haut niveau.

Est-ce pour autant une annonce faite pour détendre les relations entre les acteurs majeurs de ce mélodrame ? Est-ce uniquement un effet d’annonce ? Nous y voyons plutôt une tentative pour contrer le projet OCID en proposant un composant alternatif simple, léger, standard, exempt des reproches que l’on fait au Docker Engine. Une intention qui ne verra pas le jour immédiatement, et qui va certainement provoquer une belle onde de choc comme en témoignent les signes annonciateurs visibles dans les différences d’architectures entre containerd 0.2.4 (version actuellement utilisée dans Docker) et 1.0 (à venir).

Kubernetes face à ce brouhaha joue la carte de la prudence en prenant un peu de distance vis-à-vis du Docker Engine. En effet, k8s est actuellement capable d’utiliser dockerd ou rkt de façon quasi transparente. Depuis la version 1.5, Kubernetes introduit une première version, non finalisée de la Container Runtime Interface. Il s’agit d’une couche permettant de s’isoler du moteur réellement utilisé (Docker, rkt voire même un hyperviseur).

Une façon de montrer que le moteur d’exécution n’est qu’un simple détail d’implémentation et qu’il sera possible à l’avenir d’en changer sans remettre en question toute la topologie applicative. Rien n’est stable à ce jour, mais le vent souffle clairement dans cette direction.

Devant l’évidente complexité de la situation, tentons de résumer l’intégration de nos solutions favorites.

Le nouveau combat de nos belligérants : les conteneurs persistants (stateful)

Pour finir mentionnons le rachat par Docker d’Infinit, startup Parisienne qui construit une solution de stockage distribué multi-protocoles. Que penser de cette acquisition ?

L’offre est encore en version alpha. On parle donc d’un travail qui ne portera probablement pas ses fruits avant plusieurs mois avant d’être considérée comme “production-ready”.

Toutefois, projetons-nous quelques instants sur son potentiel. Avec la suppression de la dépendance à un annuaire distribué externe (ZooKeeper, Etcd, Consul) et l’intégration du Swarm Mode en natif dans l’Engine, Docker propose une offre de gestion distribuée de conteneurs très simple (réseau + traitement). En partant de l’hypothèse qu’Infinit pourrait être intégré nativement dans le moteur Docker, nous serions alors en face d’une offre puissante, simple mais parfaitement « convergée » (réseau + traitement + stockage). Une affaire à suivre de près...

CoreOS semble s’intéresser au même sujet avec l’émergence du projet Torus. Fortement couplé au monde CoreOS (notamment etcd), Torus offre une solution de stockage distribué (scalable et hautement disponible) pour Kubernetes, vraisemblablement à destination des clusters on-premise.

De son côté, Kubernetes confirme son intérêt sur la question en avançant sur son implémentation des PetSets, renommés en StatefulSets avec k8s 1.5. Au programme, une gestion fine et précise des conteneurs, au nommage déterministe, avec la capacité de gérer proprement l’initialisation. Concernant la gestion des volumes, l’approche de K8s n’est pas de viser une architecture nécessairement convergée mais bien de capitaliser sur l’offre de Google Cloud Platform avec les volumes persistants ou toute offre de stockage distribuée déjà utilisée en entreprise.

Mesos, que nous n’avons que très peu abordé suit également cette tendance. Après une mise en œuvre de fonction de DNS dynamique, de load-balancing et de SDN, l’orchestrateur travaille comme ses concurrents à gérer efficacement des volumes de stockages persistants.

Interlude : “Pendant ce temps, à Vera Cruz...”

Les compétiteurs continuent leurs travaux de conquête de l’univers et un élément de mesure de leur activité se base sur le dynamisme des projets open source sous-jacents.

La carte des dépendances et des contributeurs entre les projets majeurs (il en existe beaucoup d’autres) ressemble à une partie de Risk. Ajoutez par dessus les compatibilités avec des systèmes de stockages externes (Ceph, EBS, NFS, iSCSI...) ou les SDN compatibles (Weave, Calico, Romana, …) et vous obtenez à peu près la cartographie des connexions synaptiques d’un cerveau humain.

Voici une tentative de résumé des contributions aux principales initiatives open source autour de l’orchestration de conteneurs.

Officiellement, tout le monde contribue à rendre le monde meilleur, mieux intégré, mieux interconnecté.

Dans cette nébuleuse de projets et d’interactions, le positionnement des grands cloud providers est intéressant :

- AWS : fort de son offre ECS, Amazon propose une implémentation relativement simple mais parfaitement intégrée d’une gestion de conteneurs sur plusieurs nœuds. Cette offre, qui lui est spécifique et non disponible comme une solution open source, peut apparaître comme (encore) une stratégie de vendor-locking. Pour les partisans d’une approche plus ouverte, bonne nouvelle Kubernetes s’installe très bien sur AWS, et son intégration est native avec les organes principaux d’EC2 (instances, Autoscaling groups, ELB, volumes persistants sur EBS).

- Google : Naturellement dans la ligne de son vaisseau étendard Kubernetes, l’offre GKE (Google Container Service) implémente simplement de manière managée une instance de Kubernetes dans le tenant des utilisateurs. La réversibilité entre une implémentation on-premise et la version GKE n’est alors qu’une formalité. Attention toutefois, la gestion des ressources tierces (les volumes notamment) ne sont pas nécessairement transposables aussi simplement. Dernier point intéressant, au-delà de son offre Openshift Online, Red Hat annonce un rapprochement d’Openshift avec la Google Cloud Platform.

- Azure : qui tient à faire acte de présence sur le marché du CaaS (Container as a Service) joue sur plusieurs tableaux, en offrant une capacité à monter des clusters Mesos ou Swarm et travaillant également à incorporer Kubernetes parmi les solutions supportées. Une façon de ne pas se mouiller tout en misant sur tous les chevaux pour maximiser ses chances de ramasser la mise. Une stratégie qui pourrait s’avérer payante, au prix d’une déperdition d’énergie certaine.

Epilogue de la saison (cliffhanger ending)

Quels enseignements tirer de ces derniers rebondissements ? Clairement les tensions ne sont pas retombées, loin s’en faut.

Docker tente donc - tant bien que mal - de conserver son image de système simple, et l’intégration de Swarm en natif y contribue (sans la nécessité d’y ajouter un annuaire distribué : ZooKeeper, Etcd, Consul). De plus en plus simple à installer et pourtant de plus en plus riche fonctionnellement, le Docker Engine tend à grossir inéluctablement au gré des ajouts fonctionnels.

Pendant ce temps, Kubernetes poursuit sa course aux fonctions avancées (gestion des StatefulSets, fédération de clusters, implémentation de politiques de filtrage réseau fines avec les SDN compatibles…). Conscient de son image de système toujours complexe à installer, l’apparition de minikube vient remplacer kmachine et vise toujours le même objectif de mettre en œuvre un premier environnement Kubernetes minimaliste mais opérationnel. kubeadm vient également faciliter le déploiement des clusters on-premise. Ces avancées seront-elles suffisantes pour égaler la simplicité de docker-compose ? À ce jour, nombreux sont les projets open source qui fournissent dans leur dépôt de code un fichier  docker-compose.yml , rares sont ceux qui fournissent son équivalent au format k8s (svc, rc, pods…). Par l’introduction de la couche d’abstraction CRI, Kubernetes se distance de Docker et montre ainsi une volonté évidente de “commoditiser” les moteurs d’exécution.

Si vis pacem para bellum - si tu veux la paix, prépare la guerre

Pour la suite, nous ne pouvons qu’espérer que l’histoire s'écrira dans un climat plus pacifique. Nous rêvons d’ailleurs que les intérêts locaux des uns et des autres cessent de nuire à ces bijoux technologiques et à la philosophie même de l’open source auxquels nous tenons tant !  “La première victime d'une guerre, c'est la vérité”, Kipling

Nous souhaitons un repositionnement rapide des acteurs et d’ici quelques mois un apaisement des conflits sur la couche des moteurs d’exécution. La saine course à la fonctionnalité sur les couches hautes de l’orchestration et la robustesse en production pourra alors reprendre plus sereinement. Qui vivra verra.


Source images citations série House of Cards : http://www.hypable.com/house-of-cards-best-quotes

Références :

  1. http://www.infoworld.com/article/3123412/application-development/new-red-hat-project-looks-a-lot-like-a-docker-fork.html
  2. https://blog.docker.com/2016/12/introducing-containerd/
  3. http://thenewstack.io/oci-building-way-kubernetes-run-containers-without-docker/
  4. https://twitter.com/cmcluck/status/769316920961146880
  5. http://thenewstack.io/docker-fork-talk-split-now-table/
  6. https://techcrunch.com/2015/11/21/i-want-to-run-stateful-containers-too/
  7. http://www.infoworld.com/article/3106416/cloud-computing/containerizing-stateful-applications.html
  8. http://thenewstack.io/mesospheres-container-2-0-unites-stateless-stateful-workloads/
  9. http://blog.traintracks.io/solving-the-stateful-service-problem-in-container-orchestration/
  10. http://searchitoperations.techtarget.com/news/450302619/Stateful-applications-spark-container-management-debate
  11. http://containerd.io/