Mise en œuvre de Ceph

GNU/Linux Magazine n° 180 | mars 2015 | Olivier Delhomme
Creative Commons
  • Actuellement 0 sur 5 étoiles
0
Merci d'avoir participé !
Vous avez déjà noté cette page, vous ne pouvez la noter qu'une fois !
Votre note a été changée, merci de votre participation !
Dans cet article nous allons voir comment Ceph, le système de stockage objet à haute disponibilité et hautes performances, fonctionne et s'il est possible de le soumettre, sans danger, à quelques petites expériences. Nous verrons également qu'une expérimentation à grande échelle est menée au CERN.

Lorsque l'on confie ses données à un système de fichiers ou un système de stockage, réparti ou non, il faut avoir une certaine confiance dans ce système (les sauvegardes aident un peu). Pour avoir un peu confiance, il faut voir comment le système fonctionne en temps normal mais aussi par gros temps (en mode dégradé par exemple). De même je trouve qu'une bonne documentation et des commandes ou outils qui permettent de triturer le système augmentent la confiance que l'on peut avoir dans un système de stockage. Voyons donc quel degré de confiance nous pouvons accorder à Ceph.

1 Architecture

1.1 Haute disponibilité

Ceph est un système de stockage objet à haute disponibilité et hautes performances dont l'installation a déjà été expliquée dans GNU/Linux Magazine n°179 [1]. Pour le moment seuls les serveurs mon et osd (voir encadré) peuvent être plusieurs dans un cluster. Il est même très vivement recommandé d'avoir au moins trois serveurs mon (plus ne peut pas nuire) et le maximum possible de serveurs physiques exécutant un serveur osd par périphérique de stockage (les plus nombreux possibles).

Rappel

osd, mon et mds sont des abréviations pour, respectivement, Object Server Daemon (c'est lui qui va enregistrer les données), monitor server (c'est lui qui va gérer le dispatch) et Meta Data Server (c'est lui qui gère les méta données des fichiers tels dates d'accès, de création, taille...). Pour plus d'informations reportez vous à mon article précédent [1].

Le serveur mds qui est utile à Ceph n'est, à l'heure où j'écris ces lignes, pas encore en version stable pour le support de multiples instances (d'après le site Web officiel du projet). Il n'est donc pas redondant (si le serveur mds est cassé, l'accès au système de fichiers CephFS est rendu impossible). Nous n'utiliserons donc pas ce système de fichiers en production (en tout cas, pas pour le moment).

Pour voir les configurations des différents serveurs on utilisera les commandes ceph osd dump, ceph mon dump et ceph mds dump. Ce qui donnera une sortie similaire à :

$ ceph mon dump

dumped monmap epoch 1

epoch 1

fsid a5bf6b38-02f4-43fb-bffc-9c932e98888e

last_changed 0.000000

created 0.000000

0: 192.168.122.77:6789/0 mon.ceph-mon

Note

En tapant la commande ceph osd dump on se rend compte que les serveurs osd sont numérotés à partir de 0. Dans une configuration de production, on veillera à ce que le premier osd soit nommé 0 afin d'éviter toute confusion possible lors des interventions (ce qui m'est trop souvent arrivé).

Avec Ceph, la haute disponibilité n'est pas un vain mot. Par exemple, pour accéder à un objet, Ceph ne recherche pas sa position dans un index, il la calcule. En effet, si un index était utilisé il serait un point d'accès systématique (pour chaque objet) et donc un goulot d'étranglement et un ensemble de données très critiques (en cas de perte de l'index plus aucun objet ne pourrait être localisé !). La méthode de calcul de la position d'un objet se nomme CRUSH : elle est déterministe et pondérée ce qui permet une définition hiérarchique des serveurs de stockage osd. Cela permet de définir comment les serveurs osd peuvent tomber en panne et donc induit le placement des données pour permettre cela. Par exemple on pourra indiquer host pour que la panne d'un serveur physique n’entraîne aucune perte de données même s'il fait fonctionner plusieurs serveurs logiciels osd. On peut aussi indiquer datacenter par exemple ! Les valeurs possibles sont :

type 0 osd

type 1 host

type 2 chassis

type 3 rack

type 4 row

type 5 pdu

type 6 pod

type 7 room

type 8 datacenter

type 9 region

type 10 root

Avec les commandes ceph osd crush add-bucket pour créer les emplacements (par exemple : des racks, des salles, des datacenters ou des régions...) et ceph osd crush move pour déplacer les éléments dans les bons emplacements. Nos racks étant dotés de 3 PDU (Power Distribution Unit – ensemble de prises électriques, type multiprise) indépendants électriquement, on pourra définir des emplacements et ajouter les serveurs comme suit par exemple :

$ ceph osd crush add-bucket rack1-pdu1 rack

$ ceph osd crush add-bucket rack1-pdu2 rack

$ ceph osd crush add-bucket rack1-pdu3 rack

$ ceph osd crush add-bucket rack2-pdu1 rack

$ ceph osd crush add-bucket rack2-pdu2 rack

$ ceph osd crush add-bucket rack2-pdu3 rack

$ ceph osd crush move ceph-osd0 rack=rack1-pdu1

$ ceph osd crush move ceph-osd1 rack=rack1-pdu1

$ ceph osd crush move ceph-osd2 rack=rack1-pdu1

$ ceph osd crush move ceph-osd3 rack=rack1-pdu2

...

$ ceph osd crush move ceph-osd10 rack=rack2-pdu1

...

$ ceph osd crush move ceph-osd15 rack=rack2-pdu3

$ ceph osd crush move rack1-pdu1 root=default

$ ceph osd crush move rack1-pdu2 root=default

...

$ ceph osd crush move rack2-pdu2 root=default

Pour voir la totalité de la carte du cluster ceph il faut exécuter les deux commandes qui suivent. La première récupère la carte sous forme binaire, la seconde la transforme en fichier texte (/tmp/crush.txt) lisible par l'informaticien moyen :

$ ceph osd getcrushmap -o /tmp/crush.map

$ crushtool -d /tmp/crush.map -o /tmp/crush.txt

De manière plus rapide et assez lisible, l'arborescence du cluster est directement visible avec la commande ceph osd tree qui pourra produire un résultat similaire à celui-ci (tiré de l'exemple précédent) :

ceph osd tree

# id   weight   type name up/down reweight

-1     8.12     root default

-18    2.26     rack rack1-pdu1

-2     0.45     host ceph-osd0

0      0.45          osd.0                up    1

-3     0.45     host ceph-osd1

1      0.45          osd.1                up    1

-4     0.45     host ceph-osd2

2      0.45          osd.2                up    1

...

-22    1.81     rack rack2-pdu2

-14    0.45     host ceph-osd12

12     0.45          osd.12              up    1

-15    0.45     host ceph-osd13

13     0.45          osd.13              up    1

-16    0.91     host ceph-osd14

14     0.91          osd.14              up    1

Par la suite on pourra créer une règle nommée rack-pdu via la commande ceph osd crush rule create-simple rack-pdu default rack :

$ ceph osd crush rule dump rack-pdu

{ "rule_id": 2,

"rule_name": "rack-pdu",

"ruleset": 2,

"type": 1,

"min_size": 1,

"max_size": 10,

"steps": [

      { "op": "take",

        "item": -1,

        "item_name": "default"},

      { "op": "chooseleaf_firstn",

        "num": 0,

        "type": "rack"},

      { "op": "emit"}

 ]

}

Finalement il est possible d'associer cette règle à un ou plusieurs pool (ici pour le pool periph) : ceph osd pool set periph crush_ruleset 2. Une fois associée, cette règle prendra soin de distribuer les données au niveau « rack » de sorte que la perte inopinée de l'ensemble des serveurs osd se trouvant dans un « rack » ne pose aucun problème d'un point de vue données. Dans notre cas il s'agit d'un tiers de rack physique (un PDU complet).

On prendra soin de bien définir les bonnes règles et de les associer rapidement aux différents pools avant qu'ils ne contiennent beaucoup de données car cela peut conduire à de très grands mouvements de données dans le cluster (cela peut rendre le cluster indisponible pour la production normale !).

1.2 Les commandes

Il y a de nombreuses commandes pour dialoguer avec un cluster Ceph mais en temps normal nous en utiliserons principalement trois. La commande ceph que nous avons déjà vue, la commande rbd qui permet, entre autres, la gestion de périphériques et la commande rados plutôt portée sur la gestion des « pools ». Notons enfin qu'une librairie, la librados, fourni l'API aux différents langages de programmation (C, C++, Python…) pour accéder au cluster (voir la figure 1 pour un schéma complet de l'architecture).

Fig. 1 : Pile de l'architecture (Inspirée d'une image d'Inktank Storage).

Certaines des options de ces commandes sont redondantes mais donnent les résultats sous une forme différente (par exemple ceph osd lspools et rados lspools).

La cerise sur le gâteau est que l'ensemble des commandes peuvent effectuer leur sortie selon plusieurs formats (option --format=). Le format par défaut est plain (celui qui est utilisé dans cet article), mais il est possible d'utiliser json, xml, json-pretty ou xml-pretty. Ces deux dernières sont moins économes en octets mais plus lisibles par le commun des mortels.

1.2.1 Ceph

Il y a trois façons d'utiliser la commande ceph :

- en ligne de commande comme nous l'avons vu jusqu'à maintenant ;

- en mode interactif : invoquer ceph puis entrer vos commandes directement sans répéter la chaîne « ceph » à chaque fois (par exemple osd lspools) ;

- en observation des changements de l'état du cluster (à la manière d'un tail -f) : ceph -w.

La commande ceph --help donne l'aide complète (et là on se dit « mais pourquoi ai-je pris la pilule bleue ? »). On peut obtenir l'aide d'une commande spécifique en utilisant --help après celle-ci (par exemple ceph mon --help).

1.2.2 Rados et rbd

Pour les commandes rados et rbd il faudra indiquer le pool sur lequel portera la commande avec l'option -p (typiquement : rados -p metadata ls) ou directement comme on le ferait avec un dossier (par exemple : rbd create –size=1024 periph/harddrive).

rados permet de gérer les pools et les objets qu'ils contiennent tandis que rbd permet de gérer les images des machines virtuelles (ou de CD, DVD...) et les périphériques blocs pour une machine hôte.

1.3 Partitionnement logique (les pools)

Les pools permettent le partitionnement logique de l'espace de stockage du cluster. Il est possible d'indiquer quelques paramètres qui seront spécifiques à chaque pool :

- le nombre de réplicats pour les objets et le nombre minimal de réplicats acceptables pour continuer de fonctionner en mode dégradé (par défaut c'est respectivement 2 et 1) ;

- les propriétaires et les droits d'accès ;

- le nombre de groupes de placement (par défaut c'est 8) ;

- la règle CRUSH à utiliser (par défaut la règle 0) ;

Il est fortement recommandé de changer ces valeurs par défaut qui ne sont pas faites pour une utilisation normale. La formule pour calculer le nombre de groupes de placement idéal est la puissance de 2 immédiatement supérieure à (100 * nombre d'osd) / nb de réplicats (ce qui donne 128 pour notre cas particulier avec 2 réplicats et 2 osd). Voyons maintenant quelques commandes sur les pools.

Note

La valeur par défaut pour la taille (le nombre de réplicats) a changé depuis la version firefly 0.80.x elle est maintenant de 3 car c'est la valeur constatée le plus couramment chez les utilisateurs de Ceph.

1.3.1 Lister les pools

Pour voir les pools déjà existants utilisez la commande ceph osd lspools ou rados lspools qui vous donnera un résultat similaire (au moins au début) :

$ ceph osd lspools

0 data,1 metadata

 

$ rados lspools

data

metadata

1.3.2 Créer un pool

Pour ajouter des pools à ceux qui sont créés par défaut il convient d'utiliser la sous-commande mkpool comme suit :

$ rados mkpool test1

successfully created pool test1

Si on veut spécifier le nombre de groupes de placement souhaités on peut utiliser une autre commande qui permet également la création d'un pool :

$ ceph osd pool create test2 100

pool 'test2' created

1.3.3 Détruire un pool

Pour détruire un pool il faut lui donner deux fois le nom à la commande et indiquer l'option --yes-i-really-really-mean-it. Ce sont des garde-fous pour éviter de détruire accidentellement un pool (il n'existe pas de commande ou d'option pour reconstruire ou récupérer un pool détruit) :

$ ceph osd pool delete test3 test3 --yes-i-really-really-mean-it

pool 'test3' deleted

1.3.4 Lister les objets d'un pool

Chacun des pools est destiné à stocker des objets. Pour voir quels objets sont contenus dans un pool il est possible d'utiliser la sous-commande ls (raccourci pour « list ») :

$ rados -p metadata ls

1.00000000.inode

100.00000000

100.00000000.inode

1.00000000

2.00000000

200.00000000

...

1.3.5 Instantanés d'un pool

Les instantanés d'un pool permettent de garder l'état de ce pool au moment précis où l’instantané a été pris, un peu comme une photographie. Pour créer un instantané (ou snapshot en anglais) nommé instantane1 du pool test1, on utilisera la commande mksnap :

$ ceph osd pool mksnap test1 instantane1

created pool test1 snap instantane1

Nous pouvons maintenant lister les instantanés disponibles grâce à la sous-commande lssnap de rados (cette sous-commande ne semble pas disponible avec la commande ceph osd pool) :

$ rados -p test1 lssnap

1 instantane1 2014.01.20 22:02:02

1 snaps

La destruction d'un instantané est similaire à sa création (d'ailleurs il est possible d'utiliser la sous-commande rmsnap avec la commande ceph osd pool) :

$ rados -p test1 rmsnap instantane1

removed pool test1 snap instantane1

Note

La commande rbd propose également des sous-commandes pour créer, détruire et gérer des instantanés. Il s'agit ici d'instantanés réalisés sur les images des machines virtuelles (c'est à dire sur des objets d'un pool).

2 Dans les faits, ça se comporte comment ?

Tout d'abord, je dois dire que je n'ai pas porté une attention particulière à l'ordre dans lequel j'éteignais mes machines virtuelles lors de mes tests. Je n'ai jamais eu de problème lorsque je ré-allumais mes machines : le cluster était le plus souvent dans un état active+clean. Lorsque ce n'était pas le cas, le système a retrouvé un état active+clean assez rapidement.

Les tests de performance n'auraient aucun sens s'agissant de machines virtuelles stockées dans un PC de bureau sur lequel il n'y a qu'un seul disque dur. Cela d'autant plus que les volumes sont assez faibles et sont certainement très rapidement en cache (cette machine de bureau est plutôt bien fournie en mémoire). Je vous propose donc quelques essais sur les aspects comportement et fiabilité.

2.1 Ajouter des serveurs « monitor » au cluster Ceph

Pour faire de la haute disponibilité il faut au moins 3 serveurs monitor dans le cluster Ceph. En effet, il faut que puisse se dégager une majorité entre eux et cela est impossible avec 2 moniteurs seulement. Ici nous n'en n'avons qu'un seul et il faut donc en ajouter deux. Il faut préparer deux autres machines virtuelles (comme nous l'avons déjà fait dans les paragraphes précédents). Mes machines seront :

192.168.122.240 ceph-mon1

192.168.122.66 ceph-mon2

2.1.1 Méthode automatique

Pour le moment, utiliser ceph-deploy est une mauvaise idée : le cluster devient injoignable car le quorum ne peut-être atteint avec deux moniteurs et il semble que ceph-deploy n'arrive pas à terminer son ajout !

Si comme moi vous avez fait cette erreur et que plus rien ne répond vous pouvez vous en sortir en réinjectant la bonne carte (le monmap) directement dans votre premier moniteur (ici sur ceph-mon) :

# /etc/init.d/ceph stop

# ceph-mon -i ceph-mon --extract-monmap /tmp/monmap

# monmaptool --generate --set-initial-members --rm ceph-mon1 \\

--fsid a5bf6b38-02f4-43fb-bffc-9c932e98888e /tmp/monmap

# ceph-mon --inject-monmap /tmp/monmap

# /etc/init.d/ceph start

Dans mon cas, avant de récupérer l'accès à mon cluster ceph il faudra que je redémarre les serveurs ceph-osd1, ceph-osd2 et ceph-mds.

2.1.2 Méthode manuelle

Il faut donc ajouter les deux moniteurs à la main. J'exécute sur ceph-mon1 (faire de même avec ceph-mon2) les commandes suivantes :

# mkdir -p /var/lib/ceph/mon/ceph-ceph-mon1/tmp

# cd /var/lib/ceph/mon/ceph-ceph-mon1/tmp

# ceph auth get mon. -o mon.keyring

# ceph mon getmap -o monmap

# ceph-mon -i ceph-mon1 --mkfs --monmap monmap --keyring mon.keyring

# ceph mon add ceph-mon1 192.168.122.240:6789

Lorsque l'on tape cette dernière commande la sortie nous indique qu'il est parti chasser le moniteur... et plus rien ne fonctionne. Sur le premier moniteur ceph-mon j'ai récupéré la carte du cluster et je lui ai ajouté le troisième moniteur. J'ai ensuite indiqué aux deux nouveaux moniteurs leurs adresses publiques respectives :

# /etc/init.d/ceph stop

# ceph-mon -i ceph-mon --extract /tmp/monmap

# monmaptool --generate --set-initial-members --add ceph-mon2 192.168.122.66:6789 \\

--fsid a5bf6b38-02f4-43fb-bffc-9c932e98888e /tmp/monmap

# /etc/init.d/ceph start

# ssh ceph-mon1 ceph-mon -i ceph-mon1 --public-addr 192.168.122.240:6789

# ssh ceph-mon2 ceph-mon -i ceph-mon2 --public-addr 192.168.122.66:6789

Et voilà... la commande ceph mon dump exécutée sur chacun des moniteurs achèvera de vous convaincre que tous les moniteurs se connaissent.

Maintenant, pour les clients nous pouvons indiquer les différents moniteurs dans le fichier de configuration /etc/ceph/ceph.conf (les moniteurs, eux, utilisent en interne la carte monmap) :

[global]

fsid = a5bf6b38-02f4-43fb-bffc-9c932e98888e

mon_initial_members = ceph-mon

mon host = ceph-mon,ceph-mon1,ceph-mon2

mon addr = 192.168.122.77:6789,192.168.122.240:6789,192.168.122.66:6789

auth_supported = cephx

osd_journal_size = 1024

filestore_xattr_use_omap = true

Note

N'oubliez pas de mettre à jour le fichier ceph.conf du dossier /home/dup/demo-ceph de la machine d'administration.

2.1.3 Finalement

Au vu de la difficulté que j'ai eue pour ajouter un moniteur, je recommande très chaudement d'installer directement trois moniteurs à la création du cluster. Au passage, il faut noter d'une part l'existence de nombreux outils pour éditer et triturer le cluster et d'autre part l'excellente documentation qui contient des paragraphes entiers pour la résolution de problèmes. Cela est rassurant lorsqu'on envisage un éventuel passage en production.

2.2 Arrêter brutalement l'un des deux osd

Pour les besoins du test, j’exécute le script suivant dans le répertoire exporté par le zfs (/testpool) : watch --interval=1 "ls -ls; date >>date.txt" puis je force l'extinction de la machine virtuelle ceph-osd2. Après environ 40 secondes le statut du cluster devient :

# ceph status

cluster a5bf6b38-02f4-43fb-bffc-9c932e98888e

health HEALTH_WARN 252 pgs degraded; 247 pgs stuck unclean;

recovery 329/658 objects degraded (50.000%); 1/2 in osds are down

monmap e6: 3 mons at {ceph-mon=192.168.122.77:6789/0,

ceph-mon1=192.168.122.240:6789/0,

ceph-mon2=192.168.122.66:6789/0}, election epoch 4,

quorum 0,1,2 ceph-mon,ceph-mon1,ceph-mon2

mdsmap e156: 1/1/1 up {0=ceph-mds=up:active}

osdmap e102: 2 osds: 1 up, 2 in

pgmap v23634: 252 pgs, 6 pools, 1145 MB data, 329 objects

2293 MB used, 27636 MB / 29929 MB avail

329/658 objects degraded (50.000%)

252 active+degraded

client io 21190 B/s wr, 14 op/s

Puis je redémarre la machine virtuelle. Lorsque celle-ci est démarrée, je regarde le contenu de mon fichier date.txt et il contient bien toutes les secondes. Le processus en cours n'a pas été affecté et le fichier est cohérent. Une phase de reconstruction a eue lieu (elle n'a pas affecté le processus non plus) et l'état du cluster est revenu à la normale :

# ceph status

cluster a5bf6b38-02f4-43fb-bffc-9c932e98888e

health HEALTH_OK

monmap e6: 3 mons at {ceph-mon=192.168.122.77:6789/0,

ceph-mon1=192.168.122.240:6789/0,

ceph-mon2=192.168.122.66:6789/0}, election epoch 4,

quorum 0,1,2 ceph-mon,ceph-mon1,ceph-mon2

mdsmap e156: 1/1/1 up {0=ceph-mds=up:active}

osdmap e104: 2 osds: 2 up, 2 in

pgmap v23646: 252 pgs, 6 pools, 1145 MB data, 329 objects

2308 MB used, 27621 MB / 29929 MB avail

252 active+clean

client io 3386 B/s wr, 2 op/s

S'agit-il d'un coup de chance ? Le fichier est si petit qu'il est, tout entier, dans la mémoire cache ? Pour éviter cela, je vais copier une image iso de la distribution 2013 de texlive (2,3 Gi) pendant la copie, je coupe la machine virtuelle ceph-osd2 : la copie se déroule sans accroche, même si les performances sont visiblement dégradées (en comparaison des performances lorsque les deux osd sont en fonctionnement). Redémarrons la machine ceph-osd2. La récupération se lance automatiquement et se déroule sans accroche jusqu'à son terme (alors même que la copie est toujours en cours). En revanche, les accès sont très lents et la copie indique parfois -stalled- ce qui n'est pas forcément bon signe. Toutefois, cette procédure s'effectue sur des machines virtuelles qui sont toutes stockées sur un même et unique disque dur dans une même machine physique et, vu que les auteurs de ceph indiquent que la procédure de récupération est gourmande en ressource, on pouvait s'attendre à ce résultat. En tous les cas les sommes de contrôle sha1 du fichier source et du fichier copié sont identiques !

2.3 Un osd tombe, vite montons un nouvel osd

Dans la vraie vie, les serveurs qui s'arrêtent ont souvent des problèmes qu'il est parfois difficile de résoudre en trois minutes. Une fois le serveur ceph-osd2 arrêté et que l'on est en mode dégradé, est-il facile de configurer et faire rentrer un nouveau serveur osd dans le cluster ?

Il faut préparer une nouvelle machine virtuelle et suivre la procédure du paragraphe « 2.6.5 Les serveurs de données (osd) » du précédent article [1]. Le cluster intègre le nouvel osd et commence la récupération de données. Lorsque celle-ci est terminée, ceph indique qu'il contient 3 osd et que 2 sont up et 2 sont in.

Ce n'est pas plus difficile d'ajouter un serveur osd quand le cluster est en mode dégradé qu'en temps normal !

2.4 Changement du disque dur dans l'osd en panne

Finalement, c'était le disque dur où sont stockées les données qui était cassé... On le remplace avec un nouveau disque dur tout neuf... (on simule cela en détachant, dans la machine virtuelle, l'image disque et en en ajoutant une nouvelle).

Redémarrons la machine. Rien ne se passe car il n'y a ni donnée, ni journal. Au point où nous en sommes il reste à réinstaller complètement le serveur. Avant cela prenons la précaution de supprimer l'ancien moniteur (ceph-osd2 qui était nommé osd.1 en interne) :

$ ceph osd crush remove osd.1

$ ceph auth del osd.1

$ ceph osd rm 1

On peut maintenant réinstaller le serveur osd. J'utilise l'option --overwrite-conf car le fichier /etc/ceph/ceph.conf est toujours là et sans cette option ceph-deploy refuse de l'écraser :

$ ceph-deploy disk zap ceph-osd2:sdb

$ ceph-deploy --overwrite-conf osd prepare ceph-osd2:sdb

$ ceph-deploy osd activate ceph-osd2:sdb

Nous voilà avec 3 serveurs osd et 3 serveurs mon (notez que j'ai arrêté le serveur mds pour libérer un peu de mémoire sur ma machine) :

$ ceph status

cluster a5bf6b38-02f4-43fb-bffc-9c932e98888e

health HEALTH_WARN mds ceph-mds is laggy

monmap e6: 3 mons at {ceph-mon=192.168.122.77:6789/0,

ceph-mon1=192.168.122.240:6789/0,

ceph-mon2=192.168.122.66:6789/0}, election epoch 4,

quorum 0,1,2 ceph-mon,ceph-mon1,ceph-mon2

mdsmap e8397: 1/1/1 up {0=ceph-mds=up:active(laggy or crashed)}

osdmap e392: 3 osds: 3 up, 3 in

pgmap v26450: 436 pgs, 6 pools, 8196 MB data, 2122 objects

7319 MB used, 37575 MB / 44894 MB avail

436 active+clean

Le serveur ceph-osd2 est maintenant nommé osd.3 en interne :

$ ceph osd tree

# id weight type name     up/down reweight

-1 0.02998 root default

-2 0.009995               host ceph-osd1

0 0.009995                        osd.0 up 1

-3 0.009995               host ceph-osd2

3 0.009995                        osd.3 up 1

-4 0.009995               host ceph-osd3

2 0.009995                        osd.2 up 1

Note

La perte du disque où sont stockés les journaux (qui est généralement un SSD pour des questions de performances) n'entraîne pas nécessairement la perte complète des osd correspondants. En effet, grâce à une procédure [2] de reconstruction des partitions du disque, (à partir de l'UUID des journaux de chacun des osd) il est possible de repartir comme si de rien était !

2.5 Arrêter deux osd

Normalement l'arrêt de deux serveurs osd sur trois devrait me rendre un certain nombre d'objets inutilisables étant donné que mes pools sont configurés avec une taille de 2 et une taille minimale de 1 :

$ ceph osd pool get images size

size: 2

$ ceph osd pool get images min_size

min_size: 1

L'arrêt brutal non prévu de deux des trois serveurs osd laisse le cluster Ceph dans un état dégradé :

$ ceph health

HEALTH_WARN 291 pgs degraded;

145 pgs stale; 145 pgs stuck stale; 291 pgs stuck unclean;

2 requests are blocked > 32 sec;

recovery 3081/6686 objects degraded (46.081%); mds ceph-mds is laggy

On voit que 46% des objets ne sont plus accessibles. Comme mes objets sont probablement en cache dans mes machines virtuelles cette coupure ne semble pas avoir d'incidence sur les périphériques et notamment le système de fichiers ZFS : /testpool est toujours accessible ! Mais si on exécute la commande dd if=texlive2013.iso of=morceau bs=1M count=200 qui produira un fichier morceau avec les 200 premiers méga octets du fichier texlive2013.iso rien ne se passe (même au bout d'une minute la commande est toujours en suspend et aucune erreur n'est apparue...).

Démarrons les machines virtuelles qui étaient arrêtées. Dès que les deux serveurs osd sont démarrés et accessibles, Ceph entame une procédure de récupération des données et arrive rapidement à un état stable. La commande qui était « stoppée » a démarré toute seule et s'est correctement terminée :

# ls -lsh /testpool

total 2,6G

190M -rw-r--r-- 1 root root 200M juin 17 11:50 morceau

2,4G -rw-r--r-- 1 root root 2,4G juin 12 14:39 texlive2013.iso

2.6 Arrêt subit d'un serveur moniteur

Maintenant que trois serveurs moniteur existent, que se passe-t-il si l'un de ces serveurs s'arrête subitement ? L'existence du fait que l'un des serveurs moniteur est HS se note sur la deuxième ligne : 1 mons down et au niveau du quorum qui n'est plus constitué que de deux serveurs moniteur (ceph-mon1 et ceph-mon2) :

$ ceph status

cluster a5bf6b38-02f4-43fb-bffc-9c932e98888e

health HEALTH_WARN mds ceph-mds is laggy; 1 mons down,

quorum 0,2 ceph-mon1,ceph-mon2

monmap e6: 3 mons at {ceph-mon=192.168.122.77:6789/0,

ceph-mon1=192.168.122.240:6789/0,

ceph-mon2=192.168.122.66:6789/0},

election epoch 6,

quorum 0,2 ceph-mon1,ceph-mon2

mdsmap e16666: 1/1/1 up {0=ceph-mds=up:active(laggy or crashed)}

osdmap e415: 3 osds: 3 up, 3 in

pgmap v27896: 436 pgs, 6 pools, 4599 MB data, 1198 objects

7727 MB used, 37167 MB / 44894 MB avail

436 active+clean

client io 11480 B/s rd, 34736 B/s wr, 21 op/s

Sinon, toutes les opérations sont faisables sans aucun problème particulier :

# rbd -p periph --size 1024 create dd4

# rbd map periph/dd4

# zpool add testpool spare /dev/rbd/periph/dd4

# zpool status -v

pool: testpool

state: ONLINE

scrub: none requested

config:

        NAME              STATE      READ   WRITE   CKSUM

        testpool          ONLINE        0       0       0

          rbd/periph/dd1  ONLINE        0       0       0

          rbd/periph/dd2  ONLINE        0       0       0

          rbd/periph/dd3  ONLINE        0       0       0

        spares

          rbd/periph/dd4 AVAIL

 

errors: No known data errors

La copie d'un fichier ou l'installation d'une machine virtuelle se terminent sans aucun souci. Le retour du serveur moniteur est immédiat et, là encore, cela ne pose aucun problème.

2.7 Maintenance programmée

Lorsque l'on doit intervenir sur un serveur osd pour réaliser une maintenance, comme par exemple l'ajout de barrette mémoire, il est possible de prévenir le cluster afin d'éviter que les données ne soient automatiquement redistribuées :

$ ceph osd set noout

set noout

Dans le même ordre d'idée on peut demander à mettre en pause le scrub et le deep-scrub :

$ceph osd set noscrub

set noscrub

$ ceph osd set nodeep-scrub

set nodeep-scrub

On peut éteindre l'osd pour effectuer la maintenance programmée. À l'issue de la maintenance, lors de la mise sous tension du serveur, les scripts d'initialisation redémarrent automatiquement le service ceph :

$ ssh ceph-osd2 sudo /etc/init.d/ceph stop

=== osd.3 ===

Stopping Ceph osd.3 on ceph-osd2...kill 3148...kill 3148...done

 

$ ceph status

cluster a5bf6b38-02f4-43fb-bffc-9c932e98888e

health HEALTH_WARN 276 pgs degraded; 276 pgs stuck unclean;

recovery 3741/8218 objects degraded (45.522%); mds ceph-mds is laggy;

1/3 in osds are down; noout flag(s) set

monmap e6: 3 mons at {ceph-mon=192.168.122.77:6789/0,

ceph-mon1=192.168.122.240:6789/0,

ceph-mon2=192.168.122.66:6789/0},

election epoch 4,

quorum 0,1,2 ceph-mon,ceph-mon1,ceph-mon2

mdsmap e16511: 1/1/1 up {0=ceph-mds=up:active(laggy or crashed)}

osdmap e396: 3 osds: 2 up, 3 in

flags noout

pgmap v27615: 436 pgs, 6 pools, 15962 MB data, 4109 objects

7310 MB used, 37584 MB / 44894 MB avail

3741/8218 objects degraded (45.522%)

160 active+clean

276 active+degraded

Une fois la maintenance terminée, le serveur redémarré et le service ceph en fonctionnement il ne faut pas oublier d'enlever les drapeaux noout, noscrub et nodeep-scrub :

$ ceph osd unset noout

unset noout

$ ceph osd unset noscrub

unset noscrub

$ ceph osd unset nodeep-scrub

unset nodeep-scrub

Et voilà, c'est tout ! Évidemment, il faut veiller à ce que ce mode de maintenance soit le plus court possible et si possible ne pas éteindre le mauvais serveur osd !

2.8 Mise à jour du cluster (passage à firefly)

D'après la note de version il convient de migrer en premier les serveurs moniteurs puis les serveurs osd et enfin seulement le serveur mds. Sur chacun des serveurs moniteurs on change la version de ceph de « emperor » à « firefly » :

$ ssh ceph-mon sudo sed -i s/emperor/firefly/ /etc/apt/sources.list.d/ceph.list

Sur chacune des machines on réalise alors la mise à jour :

$ ssh ceph-mon sudo aptitude update

$ ssh ceph-mon sudo aptitude safe-upgrade

On réalise la même chose sur chacun des serveurs osd, sur le serveur mds puis sur les clients (ici ceph-admin et debian-virt2). Ensuite la documentation indique que si l'on utilise Ceph avec une version plus ancienne du noyaux Linux que 3.9, il convient de réaliser la commande suivante (debian wheezy est en version 3.2) :

$ ceph osd crush tunables legacy

Par acquit de conscience sur la machine debian-virt2 j'ai arrêté le service zfs-fuse, redémarré rbdmap et relancé zfs-fuse.

Note

La mise à jour de la version « firefly » vers la version « giant » s'effectue exactement de la même façon et selon le même protocole.

3 Une expérimentation à grande échelle au CERN

Le CERN, l'organisation européenne pour la recherche nucléaire, possède les équipements scientifiques les plus imposants de la planète. De par leur gigantisme (aussi gros que des cathédrales) mais aussi de par les masses de données qu'ils produisent. En effet, quelques chiffres [3] en disent long : le LHC produit 1 péta octet de données par seconde d'expérience (40 millions d'images à 100 Méga pixels) qui une fois filtré génère 30 pétaoctets de données par an. Les données sont traitées au rythme d'un pétaoctet par jour.... Songez que les détecteurs du LHC ne sont pas les seules expériences du CERN !

Les systèmes de fichiers CASTOR et EOS recueillent les données des expériences et ils supportent un flot de données d'environ 10 gigaoctets par secondes. CASTOR fait environ 89 pétaoctets et EOS environ 20 pétaoctets. Un « petit » système de fichiers AFS stocke l'ensemble des répertoires personnels des 30 000 personnes liées au CERN. Il fait environ 300 téraoctets et contient plus de 2 milliards de fichiers.

Un « petit » cluster de test [4] a permis de réaliser la validation de Ceph comme solution de stockage pour le CERN. Il s'agit de 47 serveurs physiques de stockage comportant chacun 2 processeurs Xeon E2650 (8 cœurs à 2 Ghz soit 16 cœurs et 32 threads par serveurs), 64 Go de mémoire vive, une interface Ethernet à 10 Gbits connectée (sur deux utilisables), 24 disques de 3 téraoctets pour les données et 3 disques de 2 téraoctets en miroirs pour le système. Chacun de ces serveurs physiques fait fonctionner 24 serveurs logiciels osd (un par disque). Le cluster comporte également 5 serveurs physiques moniteurs dont la particularité est d'utiliser des disques dur SSD pour les serveurs mon. Un petit calcul rapide (24 disques de 3 téraoctets sur 47 serveurs) donne un volume utilisable de 3 384 téraoctets soit 3,3 pétaoctets !!

En effet, Le CERN est en train d'opérer un changement majeur dans son architecture informatique en passant à un système d'information virtualisé et redondant. Pour la redondance, un nouveau datacenter a été construit à Budapest. La plateforme choisie pour la virtualisation est OpenStack (elle est déjà en production). Ceph (le cluster de test est maintenant passé en production) réalise une partie du stockage pour cette plate-forme et comporte déjà plus de 500 volumes OpenStack Cinder, 15 millions d'objets, et environ 1000 images OpenStack Glance. Le tout occupe un espace de 60 téraoctets (180 sur les disques puisque la configuration du cluster stocke 3 fois les données) et supporte en temps normal entre 3000 et 5000 opérations par seconde.

Ce cluster est déployé via Puppet et les scripts d'Enovance [5] légèrement modifiés [6]. L'ajout d'un serveur est automatique (mon ou osd). Les disques des serveurs osd sont détectés, préparés, initialisés et insérés dans le cluster. Le fichier ceph.conf est auto-généré, seule l'opération de démarrage du cluster (service ceph start) reste manuelle afin de laisser la possibilité de tout vérifier avant.

Conclusion

Ceph réalise l'unification, la convergence et la virtualisation du stockage (et aussi le stockage de la virtualisation ;-)). C'est un changement de paradigme. Cet article et le précédent [1] ne sont qu'une toute petite introduction à Ceph et ce que nous avons vu est déjà impressionnant. Les quelques tests basiques qui ont été réalisés montrent sa robustesse et sa fiabilité. Le degré de confiance dans ce système de stockage me semble tout à fait compatible avec un usage en production (ce qu'est en train de faire le CERN). Maintenant c'est à vous d'aller plus loin dans la découverte du système et peut-être d'écrire un programme utilisant la librados ou l'API REST pour accéder directement au cluster Ceph fraîchement mis en œuvre via les interfaces S3 ou Swift  ?

Note

Je remercie ma femme et mes enfants pour leur patience infinie, Fanny pour sa relecture de la version alpha de l'article, Dan Van Der Ster et Mélissa Gaillard pour leur autorisation de publier un paragraphe sur le CERN (et leur relecture bienveillante de ce paragraphe).

Références et liens intéressants

[1] O. Delhomme, « Présentation et installation du système de stockage réparti Ceph », GNU/Linux Magazine n°179, février 2015, p. 32 à 38

[2] Récupération des données après la perte du journal : http://www.sebastien-han.fr/blog/2014/11/27/ceph-recover-osds-after-ssd-journal-failure/

[3] l'informatique au CERN : http://home.web.cern.ch/about/computing

[4] Une présentation de Ceph au CERN : http://fr.slideshare.net/Inktank_Ceph/scaling-ceph-at-cern

[5] Les scripts d'Enovance : https://github.com/enovance/puppet-ceph/

[6] Les modifications du CERN : https://github.com/cernceph/puppet-ceph/