Persister les conteneurs

Isoler

Les conteneurs permettent d’isoler les ressources utilisées par des services, et avec un peu de discipline, offrent la promesse d’utiliser au mieux un groupe de machines.

Distribuer

Distribuer des services est maintenant un classique, pour ne pas dire un prérequis. Par contre, il faut ensuite assumer; surdimensionner pour assurer quelques pics devient rapidement un problème de place, mais surtout de puissance électrique.

La distribution permet d’avoir plus de ressources à disposition, mais aussi d’assurer plus de résilience, en proposant plusieurs instances de chaque service, capable de prendre le relai en cas d’incident, ou tout simplement de démarrer un nouveau service sans états, pour remplacer un autre défaillant.

L’élastique dans le nuage

Le cloud nous promet cette élasticité, mais la taille efficace d’une machine virtuelle est bien trop grosse pour un découpage propre, alors que le conteneur a lui, la taille et la mobilité requise.

Les ressources nécessaires fournies par la machine aux services sont le classique triplet : processeur, mémoire, stockage. Triplet que sait bien border un conteneur. En faisant attention à avoir du code immuable et versionné, il est possible d’avoir plusieurs instances d’un même conteneur, sur une ou plusieurs machines. Mobilité et ubiquité que sait bien gérer un conteneur.

Orchestrer l’utilisation des ressources

Il est possible de gérer un ensemble de conteneurs, avec un nombre d’instances fluctuant.

Pouvoir optimiser cette fluctuation permet de dépasser le taux ridicule d’utilisation de la plupart des datacenters : 15%. Une gestion efficace des ressources est l’arme secrète de Google, Borg. Enfin, l’une des armes secrètes.

Le principe est simple : on met à disposition un ensemble de ressources, on commande ensuite des ressources, et un planning est établi. Des outils sont mis à disposition permettant la coordination ou la découverte de services, qui, couplés à des proxyies, permet la mise à disposition publique des services.

Google a publié, sur le tard (une dizaine d’année après sa mise en place), leur approche avec de la gestion de cluster avec Borg. Ils insistent beaucoup sur la différence entre les tâches longues (qui ne doivent pas s’arrêter), et les taches éphémères (sensibles aux latences).

Mesos a été une des premières implémentations libres de planification de ressources, mais il vise gros, et propose de généraliser ce que proposait le YARN de Hadoop. Si vous ne comptez pas vos ressources en rack ou en datacenter, il faut chercher autre chose.

Des choses comme Nomad (le sage), Swarm (le tonitruant), ou Kubernetes (le conquérant).

Ces outils sont utilisables sur une poignée de serveur, et en se basant sur des serveurs dédiés, ou des clouds frustres, il est possible d’être bien moins cher que des clouds toutes options.

Persister

La partie pénible dans l’usage des clusters est la persistance, distribuer le travail n’est finalement pas si complexe : le loadbalancing naïf est la première étape, avant de passer à de la parallélisation et au fameux map-reduce.

Le stockage dans un environnement distribué est un problème de cohérence, latence, et de débit.

Il n’existe pas de réponse absolue, mais un ensemble de choix et de tuning. Le théorème du CAP résume cet ensemble de contraintes, et l’obligation d’en choisir deux parmi les trois lettres Consistency, Availabiliy et Partition tolerance.

Le cas du conteneur

Docker (et rkt) proposent gentiment d’emballer une application, pour pouvoir la versionner, et la déployer simplement. Une généralisation du WAR de Java, quoi. Le prérequis est d’avoir une application en lecture seule. Il est ensuite possible de monter des volumes au sein des conteneurs, pour proposer des dossiers en lecture/écriture. Sauf que ces volumes montés n’apportent ni l’ubiquité, ni la distribution, et seront liés à un serveur. Un conteneur permet d’abstraire et de généraliser plein de choses, mais pas la persistance. Pour un système distribué, c’est ballot.

Qui est le responsable du stockage?

Première décision, la persistance est-elle de la responsabilité du système d’exploitation l’application ?

Disques distants

Le moyen le plus simple pour déporter le stockage est d’utiliser un disque distant. Ce disque pourra être démonté puis remonté sur un autre serveur, il est mobile, mais n’existera qu’en un seul exemplaire. Pour peu que le serveur propose des instantanés, il sera possible d’avoir du COW, et de monter des réplicats du disque sur d’autres noeuds.

Tous les clouds proposent un service de ce genre, avec de l’iSCSI par exemple. Openstack fournit une liste indigeste des disques qu’il peut utiliser en mode bloc. Il est possible de redonder ce genre de disque, côté client, avec un simple RAID, ou côté serveur, avec de la magie, si c’est un SAN.

Il n’existe pas grand-chose en libre comme serveur iSCSI. Il existe le vénérable NBD, et le plus récent xNBD, prévu initialement pour du netboot. Coreos bosse sur Torus, un serveur NBD distribué, utilisable dans quelques années?.

Le Graal étant le rdb de Ceph (qui a rejoint le giron de RedHat), montable en NBD ou en Fuse. OVH propose maintenant du Ceph as a service.

Pour les aventuriers, il existe des systèmes de fichiers distribués(OCFS2 d’Oracle, GFS2 de Red Hat… ), permettant l’ubiquité d’un même disque monté sur plusieurs serveurs. En dehors du calcul scientifique, on trouve peu d’exemples d’usage de cette approche. Pour garantir la cohérence des données, un serveur de verrou est utilisé, garantissant des problèmes de performance pour les écritures concourantes.

Il existe des abstractions exposant une API unique vers diverses implémentations, comme Flocker ou Cinder.

Fichiers distants

Le partage en mode fichier permet un accès à distance, mais aussi multiple, à un ensemble de fichiers. NFS et Samba, que seul Azure préconise en sont les exemples les plus classiques.

Le partage de fichier est fort pratique, mais, pour assurer des performances correctes, certains raccourcis sont pris : une partie des engagements requis pour un système de fichier UNIX ne sont plus assumés.

Toutes les bases de données dédient une page de la documentation pour promettre d’atroces souffrances à qui osera mélanger NFS et base de donnée : Postgres et NFS, Cassandra et NFS

L’architecture de NFS commence à dater, et ce n’est pas un, mais un ensemble de services qui sont utilisés, pas forcément prévu pour un environnement hostile comme l’est le cloud. NFS ne prévoit rien pour la distribution du stockage.

Les serveurs NAS haute dispo, comme celui proposé par OVH, sont souvent des baies de disques connectés en optique avec deux serveurs, l’un ou l’autre serveur pourra utiliser la baie, du RAID assurera la redondance des disques, une double alimentation, la redondance d’énergie, mais en cas d’incident sur la baie, bah, pas de bol, vous avez perdu.

Des implémentations propriétaires, comme l’EFS d’Amazon permettent d’avoir de la redondance et de la distribution.

Pour les acharnés du partage en mode fichier, il existe le tant redouté GlusterFS, récemment racheté par RedHat. La prochaine version majeur, GlusterFS 4 sera d’ailleurs en Go et utilisera Etcd. On voit son nom apparaitre de temps en temps, comme l’offre un poil daté d’Acquia.

L’incontournable Ceph propose aussi un partage en mode fichier, mais cette option semble un peu boudé, c’est pour le mode bloc qu’il est réputé. Gitlab l’utilise pour son offre SAAS mais ils ont souffert de la non-homogénéité des IO des clouds publiques, et sont passé à du bare metal.

Objets distants

Assurer un stockage distribué, aussi à l’aise en lecture qu’en écriture, sans corrompre les données, fut une des premières questions que Google dut résoudre, et surtout la première révélation des secrets de Google. Le white paper sur le Google File System fut publié en 2003. Il servit de base à la création du HDFS du projet Hadoop.

Le principe est simple, les fichiers sont immuables, mais versionnés. Il n’est pas possible de modifier un fichier existant, on va en créer une nouvelle version, et par défaut, on lira la dernière version disponible.

Le premier service d’AWS, au-delà de la simple VM, fut un service de persistance distribué, S3. Le Dynamo paper expliquant la notion d’anneau virtuelle pour une architecture sans maître avec de la redondance, fut publié en 2007.

Pour S3, les fichiers sont immuables, versionnés, redondés, accessibles directement en HTTP.

Aucun cloud digne de ce nom n’ose sortir sans proposer un clone plus ou moins compatible de S3.

Tous les frameworks webs décents sont maintenant capables de gérer les uploads sur des stockage objets, avec des bibliothèques comme CarrierWave ou paperclip.

Toutes les bases de données savent (ou devraient savoir) maintenant faire des snapshots dans des stockages à la S3.

Swift

Le clone de référence est Swift d’OpenStack. Son architecture est extrêmement simple, à la limite du naïf, en python très classique. Ils ont une excellente réputation sur la qualité de leur API, et la fidélité avec l’API du S3 d’AWS.

Riak-S2

Il existe aussi le moins connu Riak-S2, une surcouche au Riak de Basho, libéré il y a quelque temps. C’est une architecture Erlang contemporaine, au code particulièrement pédagogique et étonnamment lisible, compte tenu de la complexité du bestiau.

LeoFS

Pour les fans d’Erlang, il y a aussi LeoFS. Par contre, je ne sais pas trop qui l’utilise en dehors de Rakuten, leur sponsor.

Minio

En ce moment est en train d’émerger Minio, il propose une belle UI Web, mais surtout un serveur, en Go, ce qui change du Java et de l’Erlang.

Son accueil enthousiaste vient du fait qu’il scale bien à un. Ce serveur est utilisable sur un seul serveur, et son image Docker juste marche.

Il gère tellement bien un seul serveur que la version distribuée n’est pas encore finie.

Par contre, il est capable de gérer une grappe de disque, et d’assurer de la redondance avec le code de Reed-Solomon, utilisé par le système RAID pour les disques, et vulgarisé dans un article par Backblaze, le plus grandiose des entasseurs de disques durs. En gérant eux même la parité, plutôt que la délégué à du RAID comme tout le monde, ils peuvent réparer objet par objet, et pas par volume.

RADOS Gateway, de Ceph

Le dernier, et pas des moindres, est RADOS Gateway de Ceph. Ceph met à disposition sa solution de stockage RADOS, sous les trois approches : blocs/fichiers/objets.

Base de données

Le stockage objet met un pied dans le plat. Il casse la compatibilité du système de fichier UNIX, pour proposer quelque chose de plus adapté aux environnements distribués. Du coup, l’application continue d’écrire sur un disque local (les essais de stockage sans FS d’Oracle ou Mysql ont fait un flop), mais vont se charger de la distribution avec réplication, répartition, cohérence, réparation…

Avoir une application distribuée, correctement implémentée est difficile. Le projet Jepsen propose un framework d’analyse et publie ses analyses de différentes versions d’applications. Le résultat des analyses est souvent “call me maybe”, et il y a ensuite des corrections de l’application autopsiée.

Base de données relationnelle

Les bases de données relationnelles sont toutes capables de gérer de la réplication, en utilisant le très classique modèle maître-esclave. Postgresql a quand même attendu la version 9 pour proposer ça en natif, sans passer par un produit tiers.

Pour répartir les données sur plusieurs machines, il faut passer par du sharding, ce qui va poser des problèmes pour faire des jointures sur des données dispersées. Le sharding est traditionnellement applicatif, et fonctionne mieux sur des données bien isolées, comme des utilisateurs, par exemple.

Citusdata propose d’améliorer Postgresql en lui mettant à disposition :

Les conteneurs adorent les applications sans états, indifférenciées. Ce qui est l’opposé des bases de données relationnelles.

Multi-maître

Pour ne pas avoir à gérer la différence maitre/esclave, et la complexité de la promotion de maître à esclave, puis de créer un nouvel esclave, il est possible d’utiliser de la réplication multi maître.

Postgres sait maintenant faire ça avec BDR.

Mysql propose des outils similaires, comme Galera et proxysql, ou des trucs plus emballé comme XtraDB Cluster de Percona.

Ces outils sont sympathiques, mais rien de prévu pour pour pouvoir redimensionner simplement.

Pourtant, des solutions propriétaires existent, comme Aurora d’Amazon, basé sur Mysql, avec de gros efforts pour conserver la compatibilité et disponible dans leur offre RDS, ou le mystérieux F1 de Google, reservé à AdWords.

Le modèle relationnel n’est juste pas prévu pour fonctionner de manière distribuée, mais de gros efforts sont faits pour, par contre, les applications vont devoir faire des compromis pour s’adapter. En posant un Wordpress sur un Cloud, on ne pourra pas s’attendre à de miracle.

Je fait bien la différence entre le modèle relationnel et le SQL, le langage, qui lui peut parfaitement être distribué. Des outils comme Drill de la fondation Apache, Presto de Facebook ou même Spark SQL.

Base de données NoSQL

Les bases NoSQL ont été inventées pour remettre en cause le dogme relationnel.

Bon, elles ont ensuite fournis baucoup d’efforts pour s’en rapprocher, le SQL restant une lingua franca pour explorer des données, et pouvoir se brancher dessus en JDBC/ODBC est toujours appréciable.

Le NoSQL a aussi été conçu pour pouvoir profiter d’un hébergement distribué.

Le monde du NoSQL est tout récent, Darwin n’a pas eu le temps de faire le tri pour trouver ses champions. Voici une sélection arbitraire de bases de données, qui fonctionnent à des tailles raisonnables. La partie élection, pour avoir une archi sans maître, peut être plus ou moins laborieuse.

La première chose que va sacrifier une base NoSQL est la notion de transaction.

Mongodb est la plus visible des bases NoSQL, et avant la version 3 et le stockage Tiger, est plutôt pénible à administrer. Le pattern de distribution est classique, un système d’élection pour avoir un master, et un proxy qui va assurer le routage vers le bon serveur. La distribution du travail se fait avec du classique map-reduce.

Cassandra est une base de données orientée colonnes, avec un presque SQL, le CQL, sans jointures ni sous-requêtes, mais avec du map-reduce. Créé par Facebook pour manger du log, il fut ensuite confié à la fondation Apache, pour passer à autre chose : Presto et Hbase, et une autre stack pour avaler leurs logs. Cassandra, même s’il est civilisé, reste une base conçue et dimensionnée pour du big data.

Scylladb est un clone C++, agressif et ambitieux de Cassandra, mettant un point d’honneur à saturer des réseaux 10Go, le kernel, les CPUs et des disques NVMe tout en conservant la compatibilité avec Cassandra.

Elasticsearch est une base orientée documents, distribués, avec des beaux index et une interface REST. Initialement conçu pour la recherche full text, il a évolué vers les calculs d’agrégations, et poursuit vers le machage de logs. Elasticsearch est parfaitement à l’aise avec les principes de distribution et de réplication, tout en restant crédible à partir de 2 noeuds.

Le stockage se distribue bien, se réplique bien, mais se bouge mal

Les containers sont tout à fait capables d’assurer la persistance, locale ou sur du partage en mode blocs. Par contre, les orchestrateurs ont bien envie de rééquilibrer le cluster en déplaçant les containers dans tous les sens. C’est tout à fait légitime pour des containers sans états, un contre sens pour du stockage.

Il faut alors revenir aux vieux principes décrits par Borg et Hadoop : les données sont fixes, les process peuvent bouger.

Les orchestrateurs sont maintenant capables de faire attention à ne pas déplacer les données, pour pouvoir profiter pleinement des performances locales.

Le stockage local est le plus performant, le mode bloc offre une simplification et un confort appréciable, le mode objet permet une pérennité incomparable et un scaling sans trop de limites, le mode fichier n’a plus sa place dans un environnement web.

blogroll

social