Cluster Ceph Raspian
Petit post pour expliquer l’installation de Ceph sous Raspian Stretch. De nombreux tutoriels existent mais je n’en ai trouvé aucun qui marche complètement. Voici donc un petit résumé de ce que j’ai du faire et des difficultés rencontrées.
Matériel utilisé
- 3 Raspberry PI 3
- 3 cartes SD (8 Go)
- 5 clefs USB (il me manquait la sixième 😉 )
- Un chargeur USB
- Un switch
- Des cables réseaux
Voici ce que ca donne en image :
Architecture déployée
Un cluster Ceph nécessite plusieurs composants :
- les monitor : ils supervisent l’état du cluster
- les osd : ils stockent les fichiers
- les mds : utile uniquement si l’on se sert de CephFS
N’utilisant pas CephFS, nous ne déploierons pas de composants mds. Pour plus d’infos, la doc officielle : Doc
Il est conseillé de dissocier les mon et les osd mais pour notre cluster nous ferons l’impasse sur cette recommandation. Nous aurons donc l’architecture suivante:
|Hostname | Function | | +++ | +++ | | Ceph01 | Admin/Monitor/OSD | | Ceph02 | Monitor/OSD | | Ceph03 | Monitor/OSD |
Cette architecture n’est pas optimale mais sera suffisante pour nos tests. A noter que Ceph01 a une fonction Admin en plus car c’est depuis cette machine que nous allons déployer le cluster Ceph à l’aide de ceph-deploy.
Installation système
Concernant l’installation de Raspian, je vous renvoie vers mon article portant la dessus (Installation Raspian ).
Il y a deux points très important à noter:
- les machines doivent être synchronisées au niveau du temps (obligatoire pour le cluster Ceph et l’élection du quorum)
- tous les noms de machine doivent être résolus. Donc soit vous mettez en place un DNS soit vous éditez le fichier hosts de chaque machine
Installation Ceph
Pour déployer notre cluster Ceph, nous allons utiliser l’outil ceph-deploy.
Les packages disponibles sous Stretch sont beaucoup trop vieux ( version 0.94 soit Hammer : Ceph Release ).
Le projet Ceph ne fournit pas (encore ?) de packages pour l’architecture armhf, nous allons donc les chercher en testing.
-
Création d’un fichier /etc/apt/sources.list.d/testing.list :
# echo 'deb http://mirrordirector.raspbian.org/raspbian/ testing main' > /etc/apt/sources.list.d/testing.list
-
Création d’un fichier de pinning afin de ne pas upgrader tout le système en testing:
# cat << EOF > /etc/apt/preferences.d/ceph Package : * Pin : release a=stable Pin-Priority : 900 Package : * Pin : release a=testing Pin-Priority : 300 EOF
-
Les packages Ceph en testing sont ceux de Jewel. ceph-deploy n’étant pas packagé, nous allons prendre la version fournie par le projet Ceph:
# echo 'deb http://download.ceph.com/debian-jewel/ stretch main' > /etc/apt/sources.list.d/ceph.list
-
Récupération de la clef pour le repository Ceph:
# wget -q -O - http://download.ceph.com/keys/release.asc | apt-key add -
-
Installation des packages. Attention il y a une petite subtilité et il faut bien le faire dans l’ordre sinon on va se retrouver avec un cluster non fonctionnel
# apt-get install libleveldb1v5 ceph-deploy btrfs-progs
# apt-get install -t testing ceph rbd-nbd
Voici les différentes subtilités :
* On installe la bonne version de *libleveldb1v5* sinon les outils Ceph ne fonctionneront pas
* On installe *ceph-deploy* **avant** *ceph* pour des histoires de dépendances sur les packages Python
* On installe *btrfs-progs* pour formater les OSD en *btrfs*. Ce n'est pas obligatoire, le format *XFS* étant recommandé.
* On installe *rbd-nbd* car sous Raspbian le module *rbd* n'est pas compilé (cf plus loin)
Déploiement Ceph
Maintenant que Ceph est installé sur nos trois machines, nous allons faire le déploiement grâce à ceph-deploy. Pour cela, il faut remplir les pré-requis suivants:
-
Avoir un compte dédié sur chaque machine. Nous allons reprendre le user ceph créé lors de l’installation du package ceph
-
Ce compte doit avoir un accès sudo complet
-
La machine d’admin doit pouvoir se connecter sur toutes les autres machines en ssh SANS mot de passe avec le compte ceph
-
Création du fichier sudo pour le compte ceph:
# echo 'ceph ALL = (root) NOPASSWD:ALL' > /etc/sudoers.d/ceph
-
Sur la machine ceph01 (celle faisant le role d’admin), nous allons nous logguer en tant qu’utilisateur ceph et générer une clef ssh:
# su -s /bin/bash - ceph $ ssh-keygen
-
Une fois cette clef générée, nous allons devoir changer le shell de l’utilisateur ceph sur toutes les machines:
# chsh -s /bin/bash ceph
Cela va permettre à la machine d’admin de se connecter sur toutes les autres (y compris elle même).
-
On repasse en utilisateur ceph sur la machine d’admin et on copie la clef sur toutes les machines (y compris elle même):
# su -s /bin/bash - ceph $ for h in ceph01 ceph02 ceph03 ; do ssh-copy-id ${h} ; done
-
Toujours en tant qu’utilisateur ceph, nous allons créer un répertoire de travail pour ceph-deploy et commencer le déploiement du cluster:
$ mkdir ceph-deploy && cd ceph-deploy $ ceph-deploy new --public-network 192.168.1.0/25 ceph01 ceph02 ceph03 # Changez bien évidemment le subnet et le nom des machines en fonction de vos paramètres $ ceph-deploy mon create-initial # on déploie les *mon* sur toutes les machines $ ceph admin ceph01 ceph02 ceph03 # on copie la conf sur toutes les machines
A partir de là, vous devriez avoir un cluster opérationnel mais sans OSD (donc état du cluster en HEALTH_ERR):
bash $ ceph -s
Maintenant il faut rajouter des OSD à notre cluster (c’est à dire du stockage). Pour cela nous avons nos clefs usb dans les Raspberry Pi. La répartition est la suivante:
* ceph01 : 2 clefs ( /dev/sda et /dev/sdb )
* ceph02 : 2 clefs ( /dev/sda et /dev/sdb )
* ceph03 : 1 clef ( /dev/sda )
Nous allons initialiser les clefs afin qu’elles puissent être utilisées avec Ceph (nous travaillons toujours avec l’utilisateur ceph):
bash $ ceph-deploy disk zap ceph01:sda ceph01:sdb ceph02:sda ceph02:sdb ceph03:sda
Une fois initialisées, nous allons les formater. J’ai choisi de le faire en BTRFS, ce n’est pas obligatoire. Si vous ne le faîtes pas, ce sera fait en XFS par défaut:
bash $ ceph-deploy osd prepare --fs-type btrfs ceph01:sda ceph01:sdb ceph02:sda ceph02:sdb ceph03:sda
Cette commande va créer deux partitions sur chaque clef. Une pour le journal et une pour les données.
-
Et ensuite on les active:
$ ceph-deploy osd activate ceph01:/dev/sda1:/dev/sda2 ceph01:/dev/sdb1:/dev/sdb2 ceph02:/dev/sda1:/dev/sda2 ceph02:/dev/sdb1:/dev/sdb2 ceph03:/dev/sda1:/dev/sda2
-
Notre cluster doit être up et opérationnel :
$ ceph -s cluster 2a6de943-36d5-40bb-8c16-fb39b71846c0 health HEALTH_OK monmap e2: 3 mons at {ceph01=192.168.1.37:6789/0,ceph02=192.168.1.38:6789/0,ceph03=192.168.1.39:6789/0} election epoch 68, quorum 0,1,2 ceph01,ceph02,ceph03 osdmap e90: 5 osds: 5 up, 5 in flags sortbitwise,require_jewel_osds pgmap v16247: 64 pgs, 1 pools, 0 bytes data, 1 objects 1169 MB used, 45878 MB / 48307 MB avail 64 active+clean client io 13141 B/s rd, 1812 B/s wr, 15 op/s rd, 43 op/s wr
-
Finalisation:
-
Dans le répertoire de travail de ceph-deploy (donc normalement /var/lib/ceph/ceph-deploy) se trouve un fichier ceph.conf. Il faut y ajouter les lignes suivantes:
[client] admin_socket = /var/run/ceph/$cluster-$type.$id.$pid.$cctid.asok ``` Et ensuite faire (en tant qu’utilisateur ceph) :
```bash
$ ceph admin ceph01 ceph02 ceph03 # on redéploie la conf ``` Cela afin d’éviter un conflit de sockets
-
Par défaut le service mon n’est pas activé par systemd. Du coup, lors d’un reboot de machine, le cluster sera en mode dégradé. Il faut donc éxecuter la commande suivante sur toutes les machines:
systemctl enable ceph-mon.target
```
-
-
On remet le shell par défaut pour l’utilisateur ceph sur toutes les machines:
# chsh -s /bin/false ceph
Et maintenant ??
Nous allons vérifier que tout fonctionne correctement. Comme dit précédemment, le module rbd n’est pas compilé sous Raspbian. Nous avons donc installé rbd-nbd pour pouvoir créer des volumes.
-
Visualisation des pools:
bash # ceph osd lspools 0, rbd
Le pool rbd est celui par défaut. -
Création d’un nouveau pool:
```bash # ceph osd pool create containers 256 ```
-
Création d’un “objet”:
# rbd create -p containers --size 3G test
-
On vérifie que la création est ok :
# rbd -p containers ls test # rbd -p containers info test rbd image 'test': size 3072 MB in 768 objects order 22 (4096 kB objects) block_name_prefix: rbd_data.31d6a2ae8944a format: 2 features: layering, exclusive-lock, object-map, fast-diff, deep-flatten flags:
-
On map “l’objet” sur la machine :
# rbd-nbd map containers/test /dev/nbd0
-
Vérifications:
On teste un fdisk dessus:
# fdisk -l /dev/nbd0 Disk /dev/nbd0: 3 GiB, 3221225472 bytes, 6291456 sectors Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes
On formatte:
# mkfs.btrfs /dev/nbd0 btrfs-progs v4.7.3
See http://btrfs.wiki.kernel.org for more information.
Detected a SSD, turning off metadata duplication. Mkfs with -m dup if you want to force metadata duplication.
Performing full device TRIM (1.00GiB) …
Label: (null)
UUID:
Node size: 16384
Sector size: 4096
Filesystem size: 3.00GiB
Block group profiles:
Data: single 8.00MiB
Metadata: single 8.00MiB
System: single 4.00MiB
SSD detected: yes
Incompat features: extref, skinny-metadata
Number of devices: 1
Devices:
ID SIZE PATH
1 3.00GiB /dev/nbd0
```
On monte et on écrit:
```bash
# mount /dev/nbd0 /mnt && cd /mnt && echo test > test
```
-
Voir les devices mappés :
# rbd-nbd list-mapped /dev/nbd0
-
Supprimer un device:
# rbd-nbd unmap /dev/nbd0 && rbd rm test rbd-nbd: the device is not used Removing image: 100% complete...done.