Le stockage a été refait en 2018 par Romain Cherré (Prez 2017-2018) et Nicolas Bonnet (VP pipo askip 2017-2018) et debuggé pendant un été entier par (Emmanuel Allaire, Etienne Lamouret, Clément Tarverne et Yohan Pipereau) parce que ça a été lâché à la pisse comme tous les projets cassiopet Minet. Nous avons fait passer ce projet dans le cadre d'un projet Cassiopée.
L'intitulé du projet Cassiopée était plus vague que juste “installer ceph sur les noeuds de prod'”, il s'agissait d'abord de faire passer MiNET sur une infrastructure hautement disponible. Nous avons donc étudié plusieurs moyen de stockage (et débattu pendant de longues soirées). Cet article a pour but de vous faire part d'une part des réflexions importantes que nous avons eu avant de faire les choix que nous avons fait.
Notre cahier des charges était plutôt simple, il nous fallait différentes propriétés:
Nous voulons une architecture redondée pour ne jamais perdre de données. Avant Ceph, il y avait du RaidZ (équivalent de Raid5) sur les disques dans chaque NAS. Si un disque était perdu, la grappe de disque devait travailler intensivement pour compenser (et donc potentiellement accélérer leur vieillissement). On ne pouvait tolérer que la panne d'un seul disque, et il fallait le remplacer le plus rapidement possible.
De plus, Charybde et Scylla, les anciens NAS n'étaient pas redondant entre eux, ils stockaient chacun la moitié des VMs, si un tombait, on perdait la moitié des données.
Charybde et Scylla étaient aussi placés dans la même salle (la salle serveur), donc si un incendie s'y déclarait on avait beaucoup de chance de perdre les deux en même temps. Il nous fallait donc, en plus de la redondance au niveau des disques, une redondance au niveau des serveurs.
Charybde et Scylla ont été conçus pour offrir un maximum de performances, tout en gardant une redondance limitée des données (voir article sur le wiki). Nous avons jugé que la disponibilité et la redondance étaient plus important que la performance. Ceph nous offre des performances (voir page benchmark) suffisantes pour nos VMs tout en répondant à nos besoins.
Un autre critère important était la simplicité d'exploitation. Charybde et Scylla étaient basés sur OpenIndiana, un OS adapté aux NAS mais que peu de personnes avait l'habitude d'utiliser. Le résultat a donné que peu de personnes osaient toucher aux NAS et donc, nous avions peu de personnes capable de troubleshoot les problèmes. En utilisant un système plus simple à manipuler, et mieux documenté comme Ceph, qui tourne sur un OS qu'on a l'habitude d'utiliser (Debian), on s'assure que tout le monde puisse réparer en cas de problème.
Nous avons aussi une infra un peu plus simple, puisque c'est des block devices qui sont directement exportés sur les serveurs. Sur les anciens NAS, c'était un système de fichier partagé (NFS) sur lesquels on placait des fichiers qui étaient en fait des block devices utilisés par les VMs/CTs. Sans parler du fait que les fichiers des VMs étaient stockés en qcow2 (donc utilisant du copy on write) sur un stockage qui utilisait déjà du copy on write… On avait donc du copy copy on write pour les VMs! :D
La conception des NAS ont été les fruits d'un travail admirable par les bureaux précédent. Un de leur objectif a été la performance. En regardant les benchmarks des différents systèmes nous nous sommes interrogés sur nos besoins en performance. Nous avons conclu que nous devions garder suffisamment de performances mais que nous n'avions pas besoin des meilleurs débits et latences pour quelques VMs (il s'avère que l'infrastucture CEPh après son déploiement a souffert de lourd problèmes de latences, peut-être que c'était plus important que prévu.).
On s'est aussi interrogé sur combien de serveurs on devait mettre. En général, pour faire de la haute disponibilité, il nous faut au moins 3 acteurs. (Voir le Problème des généraux byzantins) Comme ça, si jamais un serveur tombe, on peut garder un quorum, et le service tournera encore sans risque de split-brain.
Cette réflexion est valable pour les noeuds de calcul et les noeuds de stockage, bien entendu.
C'est bête, mais c'est quand même mieux d'avoir nos serveurs répartis dans différentes salles…
Sauf quand le routeur, point central de l'infra, tombe et que plus aucun nœud ne voit les autres…
Un critère limitant lors du choix de la technologie de stockage a été de l'intégrer avec Proxmox. Nous avions donc plusieurs choix possibles tant que ça s'intégrait bien avec Proxmox.
Notre premier choix “principal” que nous avions gardé comme solution pendant un bon moment a été le suivant:
Cette infra utiliserait deux serveurs. Nous utiliserions DRBD ou HAST entre les disques durs des serveurs (c'est du RAID1 mais entre deux disques distants, en utilisant le réseau).
Sur ce RAID, nous metterions du ZFS (utilisé précédemment sur Charybde et Scylla) qui permet de faire plein de trucs. Il aurait permis de faire des volumes (en mode block device), qui auraient pu être exportés. On aurait pu ajouter une redondance supplémentaire sur des données importantes et faire des snapshots.
Pour exporter ces volumes sur les serveurs, nous aurions utilisé du iSCSI, un protocole très rapide et adapté pour exporter des disques sur le réseau.
Cela nous semblait être la solution la plus adaptée car répondant à tous nos besoin, le RAID sur le réseau nous permettant d'avoir un serveur pouvant reprendre le relai de l'autre à tout moment. Les données auraient aussi été bien répliquées.
On était assez motivés pour implémenter cette solution à MiNET. Mais on avait quelques inconvénients.
Premièrement, une de nos préoccupation principale était d'avoir un système de backup fiable. Pour cela nous utiliserions les snapshots, une feature intéressante qui nous permet de prendre des instantanés des VMs en ne stockant que les différences. Cependant, pour faire le snapshot d'un zvol (un volume en mode block device), il faut AU MOINS la taille du disque qu'on veut snapshot en espace sur la pool pour pouvoir faire un snapshot. Ce n'est pas très pratique.
Ensuite, l'intégration avec Proxmox était délicate. L'import d'un disque en iSCSI est possible avec Proxmox, on avait deux solutions: soit on fait un disque par VM, soit un disque redécoupé pour plusieurs VM.
Pour créer une VM si on a a un disque par VM: on crée un zvol, on exporte en iSCSI, on importe sur Proxmox pour enfin créer une VM. Trop compliqué (voir paragraphe sur la simplicité d'exploitation), ça a été abandonné.
Soit on crée “gros” zvol qu'on exporte sur les noeuds de calcul, qui est ensuite redécoupé par LVM pour mettre les différentes VMs/CTs. Avec cette technique on aurait eu une pile de ce genre: HAST | ZFS | iSCSI | LVM | Système de fichier/partition de la VM
C'est assez compliqué et pas très flexible, de plus on ne peut pas faire un snapshot d'une seule VM sans tout faire… On a donc abandonné cette idée.
Une deuxième solution s'offrait à nous avec Proxmox, un truc qui s'appelle “ZFS+iSCSI”. En gros c'est une extension écrite par la communauté qui a été intégré par Proxmox dans leur système qui permet de faire un volume par VM de façon automatisée. Le noeud Proxmox se connecte au serveur de stockage en SSH (en root… pas top pour la sécu) et crée lui même le volume, etc. Le problème c'est que on ne peut pas utiliser de container avec ce système… Abandon encore.
On a étudié les différentes autres solution, en gardant à l'esprit qu'on voulait quelque chose de simple, et on a finalement statué sur Ceph. Je vous passe les discussions qu'on a eu sur les autres bricolages qu'on a pensé faire.
Ceph propose plusieurs façons de faire du stockage, bon évidemment on utilise RBD pour exporter des block device, ce n'est pas trop exotique. Cependant il y a différentes façons de faire la réplication, et différentes façons d'utiliser RBD.
On utilise le nouveau standard de stockage de ceph pour la gestion des OSD qui est bluestore, en utilisant des partitions sur SSD pour stocker les méta-données de bluestore afin d'améliorer la performance.
On avait donc la possibilité d'utiliser une pool en replicated ou en erasure coding, vu la place qu'on a on a choisi replicated pour ne pas s'embêter, et puis ça évite de descendre trop en performance.
On avait également la possibilité d'utiliser du cache tiering qui est censé améliorer les performances, sauf dans les cas d'utilisation avec RBD. Donc on a laissé tombé pour le cache tiering qui permet de copier les données souvent utilisées dans une autre pool qui est plus performante (se place en priorité sur des SSD par exemple)