Login Logout

Howto Ceph

Attention: cette page est en chantier ! Une image plus ancienne de cette page est disponible ici : /HowtoCeph_2023-09-27.

Ceph est une plateforme libre de stockage. Historiquement développé par Sage Weil à la suite d’une thèse en 2007, Ceph appartient désormais à Red Hat. Ceph peut également s’apparenter à un « disque distribué auto-réparant » ou encore une sorte de « RAID-NG ». Le principe est de s’appuyer sur des disques répartis au sein de plusieurs ordinateurs reliés en réseau, et d’avoir une tolérance de panne avec réparation rapide et de permettre l’ajout de disques de façon simple.

Principes de bases

Ceph permet la répartition d’objets (fichiers, morceaux de fichiers, blocs, etc.) regroupés par pool. Un pool découpé en centaines de morceaux de plusieurs Go appelés placement groups (PG). Chaque morceau (PG) est réparti sur des disques (OSD) situés dans des ordinateurs distincts.

L’algorithme CRUSH décrit ce découpage et rassemble toutes les informations dans une CRUSH map. Cette carte indique comment calculer quel démon OSD interroger pour atteindre un objet.

Un cluster Ceph est constitué de démons osd pour chaque disque, de 3 démons monitor (ou plus, tant que le nombre est pair) et 1 démon manager. Si besoin de faire du CephFS, il faudra avoir un ou plusieurs démons mds, et si besoin d’avoir un accès HTTP REST (compatible Amazon S3) des démons rgw.

Un client peut accéder à un cluster Ceph : en mode bloc (RBD), en mode fichers (CephFS) ou en mode HTTP REST compatible Amazon S3 (RGW). Ces trois modes font appel à RADOS via librados.

Déployer un cluster Ceph

Cette section montre comment déployer un cluster Ceph en suivant la méthode manuelle pour Ceph Pacific sur Debian 12. Dans les grandes lignes, il faut :

  1. ajouter un premier moniteur et un manager ;

  2. ajouter deux OSD ;

  3. ajouter les moniteurs et managers restants ;

  4. ajouter les OSD restants.

On souhaite avoir un cluster de 7 machines :

  • 3 machines cephmon0[012] qui hébergent un démon monitor ;

  • 4 machines cephosd0[1234] qui hébergent des démon OSD.

Ajouter un premier moniteur

On commence par initialiser le cluster : créer le premier monitor sur une machine ceph-mon. C’est la section

  1. Initialiser la configuration du cluster.

    # echo '[global]' > /etc/ceph/ceph.conf
    # chmod 644 /etc/ceph/ceph.conf
    # uuidgen
    # echo 'fsid = <UUID>' >> /etc/ceph/ceph.conf
    # echo 'mon initial members = cephmon00' >> /etc/ceph/ceph.conf
    # echo 'mon host = <IP-cephmon00>' >> /etc/ceph/ceph.conf
  2. Créer l’utilisateur Ceph pour le monitor.

    # ceph-authtool --create-keyring /tmp/ceph.mon.keyring --gen-key -n mon. --cap mon 'allow *'
    # ceph-authtool --create-keyring /etc/ceph/ceph.client.admin.keyring --gen-key -n client.admin --cap mon 'allow *' --cap osd 'allow *' --cap mds 'allow *' --cap mgr 'allow *'
    # ceph-authtool --create-keyring /var/lib/ceph/bootstrap-osd/ceph.keyring --gen-key -n client.bootstrap-osd --cap mon 'profile bootstrap-osd' --cap mgr 'allow r'
    # ceph-authtool /tmp/ceph.mon.keyring --import-keyring /etc/ceph/ceph.client.admin.keyring
    # ceph-authtool /tmp/ceph.mon.keyring --import-keyring /var/lib/ceph/bootstrap-osd/ceph.keyring
    # chown ceph:ceph /tmp/ceph.mon.keyring
  3. Créer le monitor.

    # sudo -u ceph monmaptool --create --add cephmon00 <IP-cephmon00> --fsid <UUID> /tmp/monmap
    # sudo -u ceph mkdir /var/lib/ceph/mon/ceph-cephmon00
    # sudo -u ceph ceph-mon --cluster ceph --mkfs -i cephmon00 --monmap /tmp/monmap --keyring /tmp/ceph.mon.keyring
  4. Démarrer le service.

    # vi /etc/ceph/ceph.conf # TODO completer conf
    # systemctl start ceph-mon@cephmon00

À ce stade, exécuter la commande ceph -s doit afficher HEALTH_OK.

Source : Monitor Bootstrapping

Ajouter un manager

Note : il est recommandé d’ajouter un manager sur chaque machine où un moniteur est présent.

La commande suivante affiche la valeur à entrer pour <KEY> juste après.

  1. Créer l’utilisateur.

    # ceph auth get-or-create mgr.cephmon00 mon 'allow profile mgr' osd 'allow *' mds 'allow *'
  2. Créer le fichier contenant les identifiants de l’utilisateur.

    # sudo -u ceph mkdir /var/lib/ceph/mgr/ceph-cephmon00
    # sudo -u ceph tee /var/lib/ceph/mgr/ceph-cephmon00/keyring << .
    [mgr.cephmon00]
        key = <KEY>
    .
  3. Démarrer le service.

    # systemctl start ceph-mgr@cephmon00
    # systemctl status ceph-mgr@cephmon00

La commande ceph -s doit afficher un serveur actif à la ligne mgr:.

Source: ceph-mgr administrator’s guide - Manual setup

Ajouter deux OSD

Il est préférable d’ajouter les premiers OSD depuis une machine différente de celle où le premier monitor a été ajouté. Ça permettra de valider si l’OSD et le monitor arrivent bien à communiquer. Ajouter ensuite un autre OSD, si possible sur une autre machine, en suivant la même procédure.

TODO

Ajouter les moniteurs et managers restants

TODO

Ajouter les OSD restants

TODO

Installer Ceph en mode client

TODO

Gestion des nœuds

Redémarrer un serveur Ceph

Si on souhaite redémarrer un des nœuds du cluster, on commence par désactiver le balancing du cluster temporairement. L’objectif est d’empêcher le cluster de répliquer les objects perdus ailleurs. Sur une des machines (ça peut être la machine à éteindre) :

# ceph osd set noout
# ceph osd set norebalance

Sur la machine à éteindre :

# reboot

Quand la machine est de nouveau disponible, vérifier l’état du cluster. Il faut que les PG soient active+clean. Sur une des machines :

# ceph -s

Note: la commande ceph -s peut afficher le warning MON_CLOCK_SKEW. En général, ce warning ce résoud de lui-même.

Puis réactiver le balancing du cluster.

# ceph osd unset noout
# ceph osd unset norebalance

Empêcher le démarrage des services

Si on veut arrêter certains services et les empêcher de démarrer automatiquement au prochain démarrage de la machine, par exemple avec les services OSD :

Attention : il faut probablement activer les flags noout et norebalance si compte arrêter les OSD.

# systemctl stop ceph-osd@1.service ceph-osd@2.service ...
# systemctl disable ceph.target ceph-osd.target

On peut aussi masquer une unité systemd spécifique si on ne souhaite pas désactiver tous un type de services.

Redémarrer les services Ceph

TODO section à mettre à jour

Pour redémarrer tous les services du cluster faire, sur tous les nœuds du cluster :

# systemctl stop ceph\*.service ceph\*.target
# systemctl start ceph.target

Pour plus de détails : Operating a Cluster.

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'

Liste

$ ceph auth ls

Suppression

$ ceph auth del client.john

Gestion des OSD

mon osd nearfull ratio

Cette variable définie à partir de quel seuil on considère qu’un OSD est bientôt plein. Si un OSD atteint ce ratio, ça déclenchera un warning pour l’état de santé du cluster. La valeur par défaut est 85 %, mais elle est probablement trop élevée. On peut s’aider de ce calculateur en ligne pour choisir le ratio : Ceph: Safely Available Storage Calculator

Par exemple, pour un cluster de 3 serveurs OSD cumulant 24 Tio d’espace disque chacun (72 Tio au total), on mettre le ratio à 67 %. Dans le fichier /etc/ceph/ceph.conf :

[global]
mon osd nearfull ratio = .67

Remplacement

Identifier la machine sur laquelle se trouve l’OSD :

# ceph osd tree

Identifier le disque physique à changer il s’agit, on le notera sdX. Puis, supprimer l’OSD du côté de Ceph :

# N=1 # On suppose que l'OSD 1 est down
# ceph osd out osd.$N
# systemctl stop ceph-osd@$N.service
# ceph osd crush remove osd.$N
# ceph auth del osd.$N
# ceph osd rm osd.$N
# umount /var/lib/ceph/osd/ceph-$N

Une fois que le disque a été remplacé, on ajoute le nouvel OSD :

# ceph-volume lvm zap /dev/sdX
# ceph-volume lvm  prepare --osd-id <id> --data /dev/sdX
# ceph osd find <id> | grep fsid
    "osd_fsid": "<fsid>",
# ceph-volume lvm activate <id> <fsid>

Remplacement avec ceph-deploy (déprécié)

On change de disque sdX sur la machine puis :

# pvcreate /dev/sdX

Sur un nœud admin :


# sudo -i -u cephuser
$ cd ~/cephdir
$ ceph-deploy osd create --data /dev/sdX <hostname>

Suppression

Attention: section à revoir

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

Taille

Taille provisionnée :

# rbd ls -l

Espace alloué par pool :

ceph df

Sortie :

RAW STORAGE:
    CLASS     SIZE       AVAIL      USED       RAW USED     %RAW USED 
    hdd       65 TiB     39 TiB     27 TiB       27 TiB         40.91 
    TOTAL     65 TiB     39 TiB     27 TiB       27 TiB         40.91 
 
POOLS:
    POOL     ID     PGS     STORED      OBJECTS     USED       %USED     MAX AVAIL 
    nfs       1     256     7.7 GiB       2.05k     24 GiB      0.08        10 TiB 
    libvirt   2     256     8.9 TiB       2.33M     27 TiB     46.80        10 TiB 

Dans la section POOLS, la colonne USED devrait correspondre à la colonne STORED multiplié par le nombre de réplication des objets. Ici, les objets sont répliqués trois fois (un objet et deux copies). Pour le pool libvirt, on a : 8.9 × 3 = 26.7 Tio, qu’on peut arrondir à 27 Tio.

La colonne MAX AVAIL donne une estimation de la quantité de données qu’on peut ajouter dans un pool. Cette valeur prend notamment en compte le nombre de réplication et la valeur mon_osd_full_ratio.

Attention : pour un pool RBD, l’espace utilisé affiché correspond à l’espace réclamé pour un volume donné. Si on crée un volume de 1 Tio, mais qu’on y écrit 100 Gio de zéros, le volume fera 100 Gio du point de vue de ceph df. La boucle suivante permet d’avoir une approximation en Gio de l’espace effectivement occupé par les volumes RBD d’un pool sous Ceph 12 :

# rbd -p <my_pool> ls -l | awk 'NR > 2 { sub("GiB$", "", $2); if ($2 ~ "TiB$") { sub("TiB$", "", $2); $2 = $2 * 1024 }; s += $2 } END { print s }'

Pour avoir les volumes RBD triés par ordre décroissant de taille sous Ceph 14 :

# rbd -p vm ls -l | sed -E 's/([0-9]) ([GT])/\1\2/' | awk 'NR == 1 { print } NR > 1 { print | "sort -hr -k2" }'

La colonne SIZE de la commande rbd ls -l change de format entre Ceph 12 et Ceph 14. Avec Ceph 14, il y a une espace entre la taille et son unité. ## RBD et Libvirt

Pour permettre à QEMU/Libvirt de parler à Ceph :

# apt install qemu-block-extra

Il est possible de faire en sorte que Libvirt parle à Ceph directement. Cela facilite l’allocation de RBD a une machine virtuelle. On peut déjà créer un RBD depuis le client :

# qemu-img create -f rbd rbd:rbd/vm0-data 8

Une autre forme permet de préciser l’utilisateur que par lequel QEMU doit passer. Il est préférable d’utiliser cette forme :

# qemu-img create -f rbd rbd:rbd/kvmdev-test:id=libvirt:conf=/etc/ceph/ceph.conf 8G

Cela créer une image vm0-data de 8 Gio dans le pool rbd.

Sur la machine cliente, on ajoute la clef de l’utilisateur libvirt dans un secret :

# cat > secret.xml << EOF
<secret ephemeral='no' private='no'>
        <usage type='ceph'>
                <name>client.libvirt secret</name>
        </usage>
</secret>
EOF
# virsh secret-define --file secret.xml # Donne la valeur de UUID
# virsh secret-set-value --secret $UUID --base64 $KEY # KEY est dans le fichier /etc/ceph/ceph.client.libvirt.keyring

Il est maintenant possible d’ajouter un RBD à une machine virtuelle. Par exemple pour ajouter le disque vm0-data du pool rbd à la VM vm0 (ne pas oublier de renseigner l’UUID) :

# cat << EOF > vm0-data.xml
    <disk type='network' device='disk'>
      <driver name='qemu'/>
      <auth username='libvirt'>
        <secret type='ceph' uuid='$UUID'/>
      </auth>
      <source protocol='rbd' name='rbd/vm0-data'>
        <host name='192.168.0.1' port='6789'/>
        <host name='192.168.0.2' port='6789'/>
        <host name='192.168.0.3' port='6789'/>
      </source>
      <target dev='vda' bus='virtio'/>
    </disk>
EOF
# virsh attach-device vm0 vm0-data.xml --persistent

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

migration à chaud

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

Le cache RBD doit être activé.

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 foo de 8 Gio à 16 Gio. On peut exécuter la commande suivante depuis n’importe quel nœud, y compris depuis un client.

# rbd resize foo --size 16G

N.B. : Il faut préciser la taille finale du volume et non la quantité que l’on souhaite ajouter.

Pour une machine virtuelle

Depuis un hyperviseur, on pourra utiliser virsh blockresize directement, pas de commande rbd nécessaire

virsh blockresize "${domain}" "${block}" "${newsize}"

N.B. : Il faut préciser la taille finale du volume et non la quantité que l’on souhaite ajouter.

La variable block peut être déterminée avec colonne Target dans la sortie de la commande virsh domblklist $domain

Réduction

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é sur la machine virtuelle.

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.

Attention : il faudra aussi adapter la variable min_size. Cette variable définie le nombre de réplicats requis pour un objet pour que le cluster accepte des IO dessus.

Par exemple, un client souhaite lire les données d’un objet. Si les variables size et min_size sont à 2, mais qu’il n’y a qu’un objet disponibles sur les deux à cause d’un incident, l’objet sera inaccessible en écriture et en lecture, puisque le nombre d’objet disponible est inférieur à min_size.

Si on met size à 2, il faudrait mettre min_size à 1.

Supprimer

Par sécurité, on peut placer les images RBD dans une corbeille avant de les supprimer. Pour mettre une image dans la corbeille :

# rbd trash mv rbd/mon-image

Si le pool d’images RBD est rbd, on peut entrer : # rbd trash mv mon-image. On précisera quand-même le nom du pool dans la suite.

Les images dans la corbeille sont désignées par un ID lisible avec :

# rbd trash ls -l
# rbd trash ls -l <mon-pool>

Si on a besoin de restaurer une image :

# rbd trash restore rbd/<id>

Pour supprimer définitivement une image :

# rbd trash rm rbd/<id>

Pour supprimer directement un volume RBD sans passer par la corbeille :

# rbd rm rbd/mon-image

Supprimer une image, depuis la corbeille ou non, peut prendre du temps (plus d’une minute).

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

Renommer un volume RBD

# rbd mv mon_image nouveau_nom

Si le volume est attaché à une machine virtuelle, il est fortement recommandé de mettre à jour sa définition avec virsh edit, de l’arrêter complètement et de la redémarrer (pas un reboot).

RadosGW

Installer un démon RadosGW

On souhaite installer un démon RadosGW (RGW) sur <HOSTNAME>. On suppose que <HOSTNAME> est un nœud du cluster Ceph.

# apt install radosgw # certainement déjà installé
# mkdir /var/lib/ceph/radosgw/ceph-rgw."${HOSTNAME}"
# ceph auth get client.bootstrap-rgw | grep -e '^\[' -e '^[[:space:]]*key' > /var/lib/ceph/bootstrap-rgw/ceph.keyring
# ceph --cluster ceph --name client.bootstrap-rgw --keyring /var/lib/ceph/bootstrap-rgw/ceph.keyring auth get-or-create client.rgw."${HOSTNAME}" osd 'allow rwx' mon 'allow rw' -o /var/lib/ceph/radosgw/ceph-rgw."${HOSTNAME}"/keyring
# rm /var/lib/ceph/bootstrap-rgw/ceph.keyring
# systemctl enable ceph-radosgw@rgw."${HOSTNAME}"
# systemctl start ceph-radosgw@rgw."${HOSTNAME}"
# systemctl enable ceph.target

Cette procédure va provoquer la création de plusieurs pools pour le stockage object.

Le démon RGW devrait être joignable sur le port 7480. Une simple requête GET sur http://127.0.0.1:7480/ devrait retourner :

<?xml version="1.0" encoding="UTF-8"?>
<ListAllMyBucketsResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
  <Owner>
    <ID>anonymous</ID>
    <DisplayName></DisplayName>
  </Owner>
  <Buckets>
  </Buckets>
</ListAllMyBucketsResult>

Utilisateurs

Créer un utilisateur

# radosgw-admin user create --uid='USERNAME' --display-name='Some Fancy Name'

La commande précédente : affiche les informations de l’utilisateur dont sa clé d’accès et sa clé secrète. Les deux seront utilisés pour s’identifier en tant que client.

Retrouver les accès API d’un utilisateur

# radosgw-admin user info --uid='USERNAME' | grep -e 'access_key' -e 'secret_key'

Lister les utilisateurs

# radosgw-admin user list

Pour avoir l’espace occupé par un utilisateur :

# radosgw-admin user stats --uid='USERNAME' --sync-stats
[…]
        "total_bytes": 46272,
[…]

Définir un quota

Limiter USERNAME à 100 Gio au total :

# radosgw-admin quota set --quota-scope=user --uid='USERNAME' --max-size=100G
# radosgw-admin quota enable --quota-scope=user --uid='USERNAME'

Pour vérifier si le quota est bien défini :

# radosgw-admin user info --uid='USERNAME'
[…]
    "user_quota": {
        "enabled": true,
        "check_on_raw": false,
        "max_size": 107374182400,
        "max_size_kb": 104857600,
        "max_objects": -1
    },
[…]

Supprimer un utilisateur

# radosgw-admin user rm --uid='USERNAME'

Lister les buckets

# radosgw-admin bucket list

Si on souhaite savoir à quel utilisateur appartient un bucket :

# radosgw-admin bucket stats --bucket='BUCKET'

La longue commande ci-dessous permet de lister tous les buckets et leur propriétaire :

# radosgw-admin bucket stats | tr -d ' ",' | awk -F: '$1 == "bucket" { b = $2 } $1 == "owner" { printf "%s\t%s\n", $2, b }'
user1	bucket1
user2	bucket2
user2	bucket3
user3	bucket4

La même chose avec jq :

# radosgw-admin bucket stats | jq -r '.[] | "\(.owner)\t\(.bucket)"'

Clients

On peut utiliser MinIO client ou Rclone par exemple.

Monitoring

Un ensemble de plugins Nagios pour Ceph sont fournis par Ceph sur Github.

Tous les checks sont utilisables out of the box dès qu’on a créé un utilisateur dédié au monitoring.

# ceph auth get-or-create client.nagios mon 'allow r' | tee /etc/ceph/ceph.client.nagios.keyring
# chgrp nagios /etc/ceph/ceph.client.nagios.keyring
# chmod g+r /etc/ceph/ceph.client.nagios.keyring

Deux checks ont besoin d’ajustements pour fonctionner correctement : check_ceph_rgw et check_ceph_rgw_api.

check_ceph_rgw

Le dépôt Github des plugins Nagios pour Ceph indique de créer un utilisateur Ceph avec seulement les droits d’écriture pour les moniteurs. Le check ne fonctionnera pas avec ces permissions. Le check retournera une erreur de ce genre :

RGW ERROR:  :: 2022-01-31 12:34:56.789012 1234567890ab  0 failed reading realm info: ret -1 (1) Operation not permitted
couldn't init storage provider

Pour contourner le problème, il faut ajouter rx pour les OSD :

# ceph auth caps client.nagios mon 'allow r' osd 'allow rx'

Aussi, ce check, contrairement aux autres, ne permet pas de spécifier le chemin du fichier .keyring, il faut placer fichier ici : /etc/ceph/ceph.client.nagios.keyring.

check_ceph_rgw_api

# apt install python-awsauth
# radosgw-admin user create --uid=nagios --display-name='Monitoring user'
# radosgw-admin caps add --uid=nagios --caps="buckets=read"
# sudo -u nagios /usr/local/lib/nagios/plugins/check_ceph_rgw_api -H <url> -a <access_key> -s <secret_key>

Troubleshooting

Impossible d’ajouter un RBD à une VM avec AppArmor

Il est possible que le problème vienne du client. Dans ce cas, l’élément bloquant est certainement apparmor. On suppose ici qu’on souhaite supprimer apparmor.

Alors que apparmor est encore installé et actif, on identifie les processus pris en charge par apparmor :

# aa-status

Pour ne pas s’embêter, on dit a apparmor d’arrêter de sécuriser tous les processus :

# aa-complain /etc/apparmor.d/usr.*
# aa-complain /etc/apparmor.d/local/usr.*
# ls /etc/apparmor.d/libvirt/libvirt-* | grep -v '\.files$' | xargs -n1 aa-complain

Normalement, à ce stade tous les processus sont dans la catégorie « complain » et non « enforce ». Puis, on peut supprimer apparmor :

# systemctl stop apparmor.service
# apt remove apparmor apparmor-utils

Après ça, l’ajout à froid de disque via virsh attach-device fonctionnera :

# virsh shutdown $vm
# virsh attach-device $vm $xml --config
# virsh start $vm

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 pour plus d’une journée par exemple, la commande 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 ceph -s.

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.

host down

Le message d’erreur est :

  cluster:
    id:     c957bfaa-ec62-443a-8df1-6e21852e7740
    health: HEALTH_WARN
            4 osds down
            1 host (4 osds) down

  services:
    mon: 3 daemons, quorum ceph01,ceph02,ceph03
    mgr: ceph01(active), standbys: ceph03, ceph02
    osd: 12 osds: 8 up, 12 in

  data:
    pools:   0 pools, 0 pgs
    objects: 0 objects, 0B
    usage:   12.8GiB used, 65.3TiB / 65.3TiB avail
    pgs:

La machine en question est inaccessible.

Fichier keyring dans /etc/ceph absents

Si un fichiers *.keyring dans /etc/ceph est absent ou a été supprimé, tout va bien, on peut le générer. Si l’utilisateur est client.libvirt, on peut exécuter ces commandes sur un des nœuds du cluster.

id=client.libvirt
ceph auth get "$id" | grep -e "$id" -e key > /etc/ceph/ceph."$id".keyring

Les infos seront dans /etc/ceph/ceph.client.libvirt.keyring.

Quel client utilise ce RBD ?

Depuis un nœud du cluster, on peut savoir quel client utilise un RBD avec la commande rbd status.

root@ceph-admin-node:~# rbdname=mypool/myrbd
root@ceph-admin-node:~# rbd status vm-root "${rbdname}"
Watchers:
        watcher=x.y.z.t:0/2718281828 client.2718281 cookie=271828182845904

L’IP du client est x.y.z.t.

Pour lister les clients qui utilisent une des images RBD :

for image in $(rbd ls)
do
    rbd status "${image}"
done | awk 'BEGIN { FS = "[=:]" } /watcher=/ { count[$2]++ } END { for (ip in count) print ip }'

daemons [osd.N,mon.hostname] have slow ops

Si la commande ceph -s retourne l’erreur suivante :

  cluster:
    id:     01234567-89ab-cdef-0123-456789abcdef
    health: HEALTH_WARN
            NN slow ops, oldest one blocked for 1000000 sec, daemons [osd.N,mon.hostname] have slow ops.

On peut essayer de redémarrer le service ceph-mon sur le serveur hostname :

systemctl stop ceph-mon@hostname.service
systemctl start ceph-mon@hostname.service

mon is allowing insecure global_id reclaim

Si on a le warning suivant :

  cluster:
    id:     01234567-89ab-cdef-0123-456789abcdef
    health: HEALTH_WARN
            mon is allowing insecure global_id reclaim

On peut désactiver la fonctionnalité.

Attention : si le warning client is using insecure global_id reclaim est aussi présent, il faut d’abord mettre à jour Ceph sur les nœuds clients ou désactiver le warning pour un moment. Pour désactiver le warning :

# ceph health mute AUTH_INSECURE_GLOBAL_ID_RECLAIM_ALLOWED 1w   # 1 week

Pour désactiver le warning pour une durée indéterminée :

# vi /etc/ceph/ceph.conf
[mon]
mon_warn_on_insecure_global_id_reclaim = false
mon_warn_on_insecure_global_id_reclaim_allowed = false
# systemctl restart ceph-mon@<hostname>.service

Pour désactiver la fonctionnalité, si les clients sont à jour :

# ceph config set mon auth_allow_insecure_global_id_reclaim false

Pour avoir l’état de la variable :

# ceph config get mon_auth_allow_insecure_global_id_reclaim

Source : Ceph Documention - Health checks

Connexion impossible avec une mise à niveau d’un client vers Debian 11

Pour un cluster en Ceph 14 (Nautilus), si on fait une mise à niveau vers Debian 11 (ou Ceph 14) d’un client, il faut penser à autoriser la machine cliente à communiquer avec les moniteurs sur le port 3300 en plus du port 6789.

ceph-osd - auth: unable to find a keyring

Lorsqu’on démarre le service ceph-osd@N.service et qu’on a cette erreur dans les logs du système (journalctl ou /var/log/syslog), il faut essayer de démarrer le service ceph-volume correspondant.

# less /var/log/syslog
Jan  1 12:34:56 hostname systemd[1]: Started Ceph object storage daemon osd.N.
Jan  1 12:34:56 hostmane ceph-osd[1234567]: 2022-01-01 12:34:56.789 01234567890a -1 auth: unable to find a keyring on /var/lib/ceph/osd/ceph-N/keyring: (2) No such file or directory
# systemctl start ceph-volume@lvm-N-01234567-890a-bcde-f012-34567890abcd.service

Pour savoir à quel unité correspond quel volume, on peut s’appuyer sur le nom des unités systemd ceph-volume.

# systemctl list-units --all ceph-volume@*.service
UNIT                                                           LOAD   ACTIVE   SUB  DESCRIPTION
ceph-volume@lvm-N-01234567-890a-bcde-f012-34567890abcd.service […]
                │ ╰──────────────────────────────────┴╴UUID présent dans le nom du LV
                ╰╴numéro de l'OSD

HEALTH_ERR - Possible data damage

La commande ceph -s nous retourne une erreur de cette forme :

  cluster:
    health: HEALTH_ERR
            24 scrub errors
            Possible data damage: 3 pgs inconsistent

Pour avoir les PG concernés :

# ceph health detail
HEALTH_ERR 24 scrub errors; Possible data damage: 3 pgs inconsistent
OSD_SCRUB_ERRORS 24 scrub errors
PG_DAMAGED Possible data damage: 3 pgs inconsistent
    pg 5.13 is active+clean+inconsistent, acting [8,0]
    pg 5.99 is active+clean+inconsistent, acting [9,4]
    pg 5.b8 is active+clean+inconsistent, acting [9,1]

On voit qu’il s’agit des PG 5.13, 5.99 et 5.b8 hébergés respectivement sur les couples d’OSD [8,0], [9,4] et [9,1]. On peut avoir plus d’informations sur ces PG avec cette commande :

# rados list-inconsistent-obj 5.99 --format=json-pretty

Ici, la commande indique :

            "shards": [
                {
                    "osd": 4,
                    "primary": false,
                    "errors": [],
                    "size": 4194304,
                    "omap_digest": "0xffffffff",
                    "data_digest": "0x242f0b48"
                },
                {
                    "osd": 9,
                    "primary": true,
                    "errors": [
                        "read_error"
                    ],
                    "size": 4194304
                }
            ]

L’OSD 9 retourne l’erreur read_error. Si on regarde la sortie de la commande ceph osd tree, on constate, dans ce cas, que :

  • tous les OSD sont actifs et accessibles ;
  • tous les PG ont une machine en commun.

À ce stade, il faut vérifier sur la machine en question si les disques fonctionnent correctement. En l’occurrence, le fichier /var/log/syslog est rempli d’erreurs blk_update_request: I/O error pour deux disques, donc il faut les changer disques. En attendant, on peut essayer de faire réparer les PG :

# ceph pg repair 5.99

En fonction de l’état du disque physique, l’opération se déroulera correctement et le PG sera bon. Ça peut être une bonne de sortir l’OSD du cluster, car dans le cas d’une panne de disque, le problème va certainement se produire de nouveau.

Vérifier la configuration d’un démon

# ceph daemon mon.<hostname> config show
# ceph daemon osd.<num_osd> config show

L’ensemble des options (ici config show) est visible avec la commande suivante.

# ceph daemon <daemon>.<id> help

error: internal error: missing backend for pool type 9 (rbd)

Installer le paquet : libvirt-daemon-driver-storage-rbd.