---
categories: cloud storage
title: Howto Ceph
...

* Documentation : <http://docs.ceph.com>


# Installation

On cherche à créer l'architecture suivante où un client interagit avec un cluster Ceph :

~~~
              +-----[ cluster Ceph ]------+
              |                 +-------+ |
              |             +-> | ceph1 | |
              |             |   +-------+ |
+-------+     | +-------+   |   +-------+ |
| cephc | <-> | | cephm | <-+-> | ceph2 | |
+-------+     | +-------+   |   +-------+ |
              |             |   +-------+ |
              |             +-> | ceph3 | |
              |                 +-------+ |
              +---------------------------+

cephc : client Ceph
cephm : nœud maitre ou nœud admin
ceph[1-3] : nœud cephs
~~~

Les données seront stockées sur les nœuds `ceph[123]`. Ces trois machines doivent donc avoir des disques supplémentaires qui seront utilisés par Ceph.

> Le nœud admin peut aussi être comme un nœud à données comme les nœuds `ceph[123]`.


## Préparation

On suppose ici que :

- chaque machine a été installée sous Debian 9 ;
- `cephm` à un accès SSH à `ceph[123c]`.

Pour la configuration SSH, on aura, pour cephm:

~~~
$ cat ~/.ssh/config
Hostname ceph1
Host ceph1
User cephuser

Hostname ceph2
Host ceph2
User cephuser

Hostname ceph3
Host ceph3
User cephuser
~~~

L'utilisateur `cephuser` doit pouvoir exécuter la commande `sudo` sans mot de passe.

> Il est peut-être nécessaire d'ajouter les machines dans le fichier `/etc/hosts` :
>
> ~~~
> X.X.X.X ceph1
> Y.Y.Y.Y ceph2
> Z.Z.Z.Z ceph3
> ~~~

> En réalité seul le nœud maître à besoin de se connecter aux autres nœud du cluster mais je n'ai pas essayé.

Dans cet exemple, chaque noeud - `ceph1`, `ceph2` et `ceph3` - à un disque supplémentaire à sa disposition. Ce disque contiendra les données à stocker dans le cluster et doit être vide, sans table de partitions et être utilisé comme volume physique :

~~~
wipefs -a /dev/sdX
pvcreate /dev/sdX
~~~

> `/dev/sdX` est le volume supplémentaire.


## Installation

On commence par installer `ceph-deploy`, l'outil qui permet de déployer un cluster Ceph.

~~~
# apt update && apt install apt-transport-https
# wget -q -O- 'https://download.ceph.com/keys/release.asc' | sudo apt-key add -
# echo deb https://download.ceph.com/debian-luminous/ $(lsb_release -sc) main | sudo tee /etc/apt/sources.list.d/ceph.list
# apt update && sudo apt install ceph-deploy
~~~

> Les commandes précédentes ne sont à exécuter que sur le nœud maître.

Puis, on installe NTP sur l'ensemble des nœuds.

~~~
# apt install ntp
# timedatectl set-ntp true
~~~

> Jusqu'à indication du contraire, les commandes qui suivent sont à exécuter sur le nœud maître.

On commence par créer un dossier qui contiendra les fichiers de configuration et les clefs.

~~~
$ mkdir ceph
$ cd ceph
~~~

> On peut aussi se placer dans `/etc/ceph`.

On crée le cluster :

~~~
$ ceph-deploy new ceph1 ceph2 ceph3
~~~

Ajouter le « public_network » à la configuration de Ceph :

~~~
$ cat <<eof >>ceph.conf
public_network = X.X.X.0/24
eof
~~~

Si on souhaite utiliser le cluster pour y installer des VMs, il faut activer le cache RBD :

~~~
cat <<eof >>ceph.conf
[client]
rbd cache = true
eof
~~~

On installe les paquets Ceph sur les nœeuds :

~~~
$ ceph-deploy install --release luminous ceph1 ceph2 ceph3
~~~

On initialise le moniteur. Cela va créer des fichiers `*.keyring`. On copie ensuite ces fichiers sur tous les nœeuds dans `/etc/ceph` avec la commande `ceph-deploy admin. Un monitor sert à maintenir une carte de l'état du cluster.

~~~
$ ceph-deploy mon create-initial
$ ceph-deploy admin ceph0 ceph1 ceph2 ceph3
~~~

On déploie un manager. Celui-ci permet de regrouper l'état du cluster à un seul endroit.

~~~
$ ceph-deploy mgr create deb1
~~~

On crée les OSD :

~~~
$ ceph-deploy osd create --data /dev/sdX deb1
$ ceph-deploy osd create --data /dev/sdX deb2
$ ceph-deploy osd create --data /dev/sdX deb3
~~~

> On peut lancer la commande suivante pour s'assurer que le cluster fonctionne bien :
>
> ~~~
> $ ssh ceph1 sudo ceph -s | grep HEALTH_OK && echo yes || echo fail
> ~~~

On ajoute des moniteurs afin d'assurer la bonne disponibilité du cluster. Il vaut mieux avoir un nombre impair de moniteurs.

~~~
$ ceph-deploy mon add deb2
$ ceph-deploy mon add deb3
~~~

De la même manière, on ajoute des managers. Dans le cas où un manager décide de ne plus fonctionner.

~~~
$ ceph-deploy mgr create deb2
$ ceph-deploy mgr create deb3
~~~

Il ne reste qu'à créer un pool et à l'initialiser pour RBD :

~~~
# ceph osd pool create rbd 128
# ceph osd pool set rbd nodelete true
# ceph osd pool application enable rbd rbd
# rbd pool init rbd
~~~

> La seconde commande empêche la suppression du pool. Il sera impossible de le supprimer par accident (ou de le supprimer tout court).

Le cluster est prêt. On peut maintenant s'occuper du client.


## Client

L'installation du client est analogue à celle des nœuds. Depuis le nœud admin :

~~~
$ ceph-deploy install --release luminous debc
$ ceph-deploy admin debc
~~~

> Si cette étape échoue à cause d'un problème de clefs, il faut copier les clefs dans /etc/ceph :
>
> ~~~
> # cp ceph.client.admin.keyring /etc/ceph
> ~~~

Sur le client, on peut désormais récupérer le block device :

~~~
# rbd create foo --size 4096 --image-feature layering
# map foo --name client.admin
~~~

> On peut connaître l'espace maximal réservé à un pool :
>
> ~~~
> $ ceph df
> ~~~

Si on compte utiliser le block device pour y installer une machine virtuelle, on peut s'arrêter là. Sinon, il ne reste qu'à le formater puis à le monter :

~~~
# mkfs.ext4 -m0 /dev/rbd/rbd/foo
# mkdir /mnt/ceph-block-device
# mount /dev/rbd/rbd/foo /mnt/ceph-block-device
# cat <<EOF >>/mnt/ceph-block-device
plain text is life
EOF
~~~


# Gestion des comptes utilisateurs

Ceph a un système interne de gestion des utilisateurs. Un utilisateur est représenté par :

- un nom (et un ID) ;
- des permissions ;
- une clef.

Par exemple pour l'utilisateur `client.admin` - l'utilisateur par défaut - l'ID est `admin`, le nom est `client.admin` et la clef et ses permissions sont :

~~~
$ ceph auth get client.admin
exported keyring for client.admin
[client.admin]
        key = ****************************************
        caps mds = "allow *"
        caps mgr = "allow *"
        caps mon = "allow *"
        caps osd = "allow *"
~~~

> On constate naturellement que l'utilisateur `client.admin` a tous les droits sur chacun des éléments du cluster.

Après avoir installé le cluster, `client.admin` est le seul utilisateur et celui par défaut. Si vous vous êtes placé dans `/home/$USER/ceph` pour la mise en place du cluster, les fichiers de configuration et la clef de l'utilisateur `client.admin` s'y trouvent. Cependant, par défaut, les commandes comme `ceph` ou `rbd` cherchent les clefs dans `/etc/ceph`. De ce fait, si on est pas `root` ou que la clef n'est pas dans `/etc/ceph`, Ceph renverra une erreur disant qu'il ne peut pas accéder au cluster. Pour corriger ça, il faut spécifier manuellement l'emplacement de la clef en option :

~~~
$ ceph -n client.admin -k ~/ceph/ceph.client.admin.keyring health
~~~

Il est possible de définir des arguments par défaut pour ne pas avoir à tout taper à chaque fois à l'aide de la variable d'environnement `CEPH_ARGS` :

~~~
$ CEPH_USER_NAME=client.admin
$ export CEPH_ARGS="-n $CEPH_USER_NAME -k $HOME/ceph/ceph.$CEPH_USER_NAME.keyring"
$ ceph health
~~~

> Depuis peu, il est facultatif de donner l'option `-k` quand l'option `-n` est déjà présente si le fichier de clef de l'utilisateur est présent dans sous cette forme : `/etc/ceph/ceph.$CEPH_USER_NAME.keyring`.

> Il est suffisant de donner la clef avec l'option `-k`, le nom est facultatif.


## Création

Il y a deux façons de procéder. La première avec `add` et la seconde avec `get-or-create` :

~~~
$ ceph auth add client.john mon 'allow r'
added key for client.john
$ ceph auth get-or-create client.paul mon 'allow r'
[client.paul]
        key = ****************************************
~~~

La seconde méthode va, en plus de la création de l'utilisateur, afficher sa clef. On peut la récupérer sur la sortie standard ou via l'option `-o` pour l'écrire dans un fichier. De plus, si l'utilisateur existe déjà, c'est la clé déjà existante qui sera imprimée. Si on a utilisé `ceph auth add` pour ajouter l'utilisateur, on pourra récupérer sa clef avec `ceph auth get`.


## Modification

La commande suivante permet de modifier les droits d'un utilisateur. Cela va *écraser* ses droits actuels.

~~~
$ ceph auth caps client.john mon 'profile rbd' osd 'profile rbd pool=rbd'
~~~


## Suppression

~~~
$ ceph auth del client.john
~~~


# Gestion des OSD


## Suppression

~~~
OSD=0
ceph osd out $OSD
sudo systemctl stop ceph-osd@$OSD
ceph osd purge $OSD --yes-i-really-mean-it
~~~


# Gestion des pools


## Suppression

Par défaut, il est impossible de supprimer un pool. Il y a deux gardes-fous à passer pour permettre la suppression. On s'assure d'abord que le flag « nodelete » est bien à « false » :

~~~
# ceph osd pool get $POOL_NAME nodelete | grep -q true && ceph osd pool set $POOL_NAME nodelete false
~~~

Une fois ce flag désactivé, il faut configurer le cluster pour autoriser la suppression d'un pool :

~~~
# ceph tell mon.* injectargs --mon-allow-pool-delete=true
~~~

Pour finir, on supprime le pool puis on active à nouveau la sécurité :

~~~
# ceph osd pool delete $POOL_NAME $POOL_NAME --yes-i-really-really-mean-it
# ceph tell mon.* injectargs --mon-allow-pool-delete=false
~~~


# RBD


## VM

On peut utiliser un block device pour y installer une machine virtuelle avec `virt-install`. Le chemin du disque doit mener au block device :

~~~
# virt-install --connect=qemu:///system \
  --name=$VMNAME \
  --cpu mode=host-passthrough --vcpus=$VCPU \
  --ram=$RAM \
  --disk path=/dev/rbd/rbd/foo,bus=virtio,io=threads,cache=none,format=raw \
  --network=bridge:br0,model=virtio \
  --noautoconsole --graphics vnc,listen=127.0.0.1,keymap=fr \
  --rng /dev/random \
  --cdrom=/home/images/slackware64-14.2-install-dvd.iso
~~~


## Redimensionnement

Il est possible d'étendre ou de réduire un block device au sein d'un pool. Si des machines virtuelles ont été installées sur le block device en question, il n'est pas nécessaire de les éteindre. On suppose ici que l'on souhaite étendre le block device foo de 8 Gio à 16 Gio. Depuis le nœud admin ou client, il suffit de faire :

~~~
# rbd resize foo --size 16G
~~~

Il reste à avertir la machine que le device a changé de taille :

~~~
# virsh blockresize testrbd /dev/rbd/rbd/foo 10G
~~~

> Si on souhaite réduire la taille du block device :
>
> ~~~
> # rbd resize foo --size 8G --allow-shrink
> ~~~

Le reste de la procédure dépend du système de fichier utilisé et est à faire sur la VM. Si on souhaite étendre une partition `ext4` :

~~~
# fdisk /dev/sdXY # suppression puis recréation de la partition
# partprobe
# e2fsck -yf /dev/sdXY
# resize2fs /dev/sdXY
~~~


## Réplication

Un block device est répliqué fois 2 par défaut. La commande suivante permet de changer cette valeur :

~~~
# ceph osd pool set rbd size 2
~~~

Le block device `rbd` sera ainsi répliqué 1 fois. Dans le cluster, on trouvera le block device original plus une réplication, d'où le « 2 ».

Pour accéder au nombre de réplicats :

~~~
# ceph osd pool get rbd size
~~~

> **NB** Si on augmente le nombre de réplications, la commande `ceph -s` affichera certainement « HEALTH WARN ». Ce warning est normal et signale qu'une des réplications n'est pas complète. Il s'agit de celle qui vient d'être ajoutée. Le warning disparaitra quand la nouvelle réplication sera complète.


## Snapshots

Il est possible de créer des snapshots de block device, de les restaurer, les cloner…

Créer une snapshot :

~~~
$ rbd snap create rbd/foo@foo_$(date +%F)
~~~

Lister les snapshots :

~~~
$ rbd snap ls rbd/foo
~~~

Revenir à une snapshot :

~~~
$ rbd snap rollback rbd/foo@$SNAPNAME
~~~

Supprimer une snapshot :

~~~
$ rbd snap rm rbd/foo@$SNAPNAME
~~~

**TODO** ajouter la partie protection et clonage des snapshots

## Es


# CephFS


## Mise en place

Il est nécéssaire d'avoir un serveur de méta-données pour utiliser CephFS :

~~~
$ ceph-deploy mds create $CEPH_NODE
~~~

On créer le pool de données et de méta-données :

~~~
$ ceph osd pool create cephfs_data $PG_NUM
$ ceph osd pool create cephfs_metadata $PG_NUM
$ ceph fs new $FS_NAME cephfs_metadata cephfs_data
~~~


## Utilisation

Il suffit de monter le CephFS, il sera utilisable :

~~~
# KEY=$(awk '/key = / { print $NF }' </etc/ceph/ceph.client.admin.keyring)
# CEPH_USER_ID=admin
# mkdir /mnt/mycephfs
# mount.ceph $MON_IP_ADDR:/ /mnt/mycephfs -o "name=$CEPH_USER_ID,secret=$KEY"
# cat <<EOF >/mnt/mycephfs/truth
slackware is the best
e ≃ 2.7181828
EOF
~~~

> La commande `mount.ceph` est équivalente à `mount -t ceph`.

Il est possible de donner un fichier contenant la clef au lieu donner la clef directement lors du `mount.ceph` :

~~~
# SECRETFILE=/etc/ceph/admin.secret
# awk '/key = / { print $NF }' </etc/ceph/ceph.client.admin.keyring >$SECRETFILE
# CEPH_USER_ID=admin
# mount.ceph $MON_IP_ADDR:/ /mnt/mycephfs -o "name=$CEPH_USER_ID,secretfile=$SECRETFILE"
~~~

On peut aussi utiliser FUSE :

~~~
# ceph-fuse -m $MONITOR_IP_ADDRESS:6789 /mnt/mycephfs
~~~

Il est également possible de limiter l'utilisation du FS à un répertoire pour un utilisateur Ceph :

~~~
$ CEPH_USERNAME=client.cephuser
$ ceph fs authorize cephfs $CEPH_USERNAME /dir0 rw /dir1 r
~~~

Cette commande va créer un utilisateur `client.cephuser`. Il aura accès au répertoire `/dir0` en lecture et en écriture et `/dir1` en lecture seule. On pourra monter le FS de cette manière :

~~~
$ ceph-fuse -n $CEPH_USERNAME -m $MONITOR_IP_ADDRESS:6789 /mnt/mycephfs -r /dir0
~~~

> Le mécanisme de restriction d'accès fonctionne aussi bien avec `ceph-fuse` qu'avec `mount.ceph`.


# Troubleshooting


## Crash

Si une ou plusieurs machines du cluster s'éteigent brutalement, il suffit de les redémarrer et de s'assurer que le service NTP soit lancé sur la machine :

~~~
# timedatectl status | grep -q '^NTP synchronized: yes$' || timedatectl set-ntp true
~~~

Ceph devrait se réparer tout seul. La commande `watch ceph -s` permet de s'en assurer.


## Installation client impossible

Si l'installation  d'un client n'est pas possible à cause d'une erreur de configuration des paquets avec dpkg :

~~~
# dpkg --configure ceph-common
~~~

Puis recommencez l'installation depuis le nœud admin.


## « Reduced data availability »

Après avoir éteint le cluster pendant un week-end, la commande `sudo ceph -s` peut retourner le warning suivant :

~~~
$ ceph -s
  cluster:
    id:     beaa2317-eecb-4e2b-b5d2-358b072fe05d
    health: HEALTH_WARN
            Reduced data availability: 154 pgs inactive, 152 pgs peering
            Degraded data redundancy: 888/5094 objects degraded (17.432%), 66 pgs degraded
~~~

Dans la plupart des cas il suffira d'attendre que le cluster se soigne seul. On peut surveiller l'état du cluster avec `watch sudo ceph -s`. En dernier recours, si le cluster est bloqué, la commande suivante *peut* corriger ce warning :

~~~
$ ceph sync force --yes-i-really-mean-it --i-know-what-i-am-doing
~~~

## Manque de placement groups

Si on ajoute un grand nombres d'OSD sur un cluster de petite taille (c.à.d ayant moins de 10 OSD) le rapport de santé de Ceph peut nous avertir d'un manque de placement groups (noté « pgs »). Il suffit d'en ajouter avec la commande suivante :

~~~
$ ceph osd pool set $POOL_NAME pg_num $PG_NUM
$ ceph osd pool set $POOL_NAME pgp_num $PG_NUM
~~~

> $PG_NUM devrait être une puissance de 2 pour permettre une répartition des données plus homogène sur le cluster.

# buf[]

> /\* Cette section contient des éléments à compléter, mettre en forme, supprimer|… \*/

## taille rbd

provisionnée :

~~~
rbd ls -l
~~~

allouée *par pool* :

~~~
ceph df
~~~

## création vm proprement

~~~
# apt install qemu-block-extra
# qemu-img create -f raw rbd:rdb/bar 8
~~~

## migration à chaud

~~~
virsh migrate --live --unsafe --verbose first qemu+ssh://$IP_DST/system
~~~

Le cache RBD doit être activé.