Howto Ceph
- Principes de bases
- Cluster Ceph
- Pools
- RADOS Block Device (RBD)
- RADOS Gateway (RGW)
- Monitoring
- Troubleshooting
- Impossible d’ajouter un RBD à une VM avec AppArmor
- Crash
- Reduced data availability
- Manque de placement groups
- host down
- Fichier keyring dans /etc/ceph absents
- Quel client utilise ce RBD ?
daemons [osd.N,mon.hostname] have slow ops
mon is allowing insecure global_id reclaim
- Connexion impossible après une mise à niveau d’un client vers Debian 11
ceph-osd
-auth: unable to find a keyring
HEALTH_ERR
-Possible data damage
- Vérifier la configuration d’un démon
error: internal error: missing backend for pool type 9 (rbd)
Attention: cette page est en chantier ! Une image plus ancienne de cette page est disponible ici : /HowtoCeph_2023-09-27.
- Documentation : https://docs.ceph.com
- Notre présentation de Ceph en vidéo (1h10) : https://www.youtube.com/watch?v=9VzZKGFfjGw
- Thèse de Sage Weil : https://ceph.com/wp-content/uploads/2016/08/weil-thesis.pdf
- Publications sur Ceph : https://ceph.io/publications/
- Vidéo “Intro to Ceph” par Sage Weil : https://youtu.be/PmLPbrf-x9g
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
.
Cluster Ceph
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 :
ajouter un premier moniteur et un manager ;
ajouter deux OSD ;
ajouter les moniteurs et managers restants ;
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
- Initialiser la configuration du cluster.
ceph-mon# echo '[global]' > /etc/ceph/ceph.conf
ceph-mon# chmod 644 /etc/ceph/ceph.conf
ceph-mon# uuidgen
ceph-mon# echo 'fsid = <UUID>' >> /etc/ceph/ceph.conf
ceph-mon# echo 'mon initial members = cephmon00' >> /etc/ceph/ceph.conf
ceph-mon# echo 'mon host = <IP-cephmon00>' >> /etc/ceph/ceph.conf
- Créer l’utilisateur Ceph pour le monitor.
ceph-mon# ceph-authtool --create-keyring /tmp/ceph.mon.keyring --gen-key -n mon. --cap mon 'allow *'
ceph-mon# 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-mon# 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-mon# ceph-authtool /tmp/ceph.mon.keyring --import-keyring /etc/ceph/ceph.client.admin.keyring
ceph-mon# ceph-authtool /tmp/ceph.mon.keyring --import-keyring /var/lib/ceph/bootstrap-osd/ceph.keyring
ceph-mon# chown ceph:ceph /tmp/ceph.mon.keyring
- Créer le monitor.
ceph-mon# sudo -u ceph monmaptool --create --add cephmon00 <IP-cephmon00> --fsid <UUID> /tmp/monmap
ceph-mon# sudo -u ceph mkdir /var/lib/ceph/mon/ceph-cephmon00
ceph-mon# sudo -u ceph ceph-mon --cluster ceph --mkfs -i cephmon00 --monmap /tmp/monmap --keyring /tmp/ceph.mon.keyring
- Démarrer le service.
ceph-mon# vi /etc/ceph/ceph.conf # exemple de fichier ceph.conf
[global]
fsid = 12345678-90ab-cdef-1234-567890abcdef
mon initial members = ceph-mon00
mon host = <ip-ceph-mon00>
# complements (point 16 de la doc)
public network = <reseau-ceph-public>
cluster network = <ip-ceph-osd00>, <ip-ceph-osd01>, … <ip-ceph-osdN>
auth cluster required = cephx
auth service required = cephx
auth client required = cephx
osd pool default size = 3 # Write an object n times.
osd pool default min size = 2 # Allow writing n copies in a degraded state.
osd pool default pg num = 512
osd pool default pgp num = 512
osd crush chooseleaf type = 1
ceph-mon# 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.
- Créer l’utilisateur.
ceph-mon# ceph auth get-or-create mgr.cephmon00 mon 'allow profile mgr' osd 'allow *' mds 'allow *'
- Créer le fichier contenant les identifiants de l’utilisateur.
ceph-mon# sudo -u ceph mkdir /var/lib/ceph/mgr/ceph-cephmon00
ceph-mon# sudo -u ceph tee /var/lib/ceph/mgr/ceph-cephmon00/keyring << .
[mgr.cephmon00]
key = <KEY>
.
- Démarrer le service.
ceph-mon# systemctl start ceph-mgr@cephmon00
ceph-mon# 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 deux machines différentes de celle où le premier monitor a été ajouté. Ça permettra de valider si les OSD et le monitor arrivent bien à communiquer.
ceph-osd# ceph-volume lvm create --data /dev/<DEVICE>
Ajouter les moniteurs et managers restants
Pour ajouter un monitor :
# mkdir -v /var/lib/ceph/mon/ceph-<HOSTNAME>
# mkdir tmp-mon-add
# ceph auth get mon. -o tmp-mon-add/mon.keyring
# ceph mon getmap -o tmp-mon-add/map
# ceph-mon -i <HOSTNAME> --mkfs --monmap tmp-mon-add/map --keyring tmp-mon-add/mon.keyring
# ceph-mon -i <HOSTNAME> --public-addr <IP>
# rm -r tmp-mon-add
Pour ajouter un manager :
# ceph auth get-or-create mgr.<HOSTNAME> mon 'allow profile mgr' osd 'allow *' mds 'allow *'
# systemctl start ceph-mgr@<HOSTNAME>
Ajouter les OSD restants
Pour chaque disque sur chaque machine :
ceph-osd# ceph-volume lvm create --data /dev/<DEVICE>
Gérer les démons
Les différents démons/services du cluster Ceph sont gérés avec systemd. Sur une machine qui hébergent des OSD et des moniteurs, il y aura :
ceph.target
ceph-mgr.target
ceph-mgr@*.service
ceph-mon.target
ceph-mon@*.service
ceph-osd.target
ceph-osd@*.service
Voir notre /HowtoSystemd pour en savoir plus sur la
gestion des unités systemd. Attention : une commande stop
,
start
ou restart
sur une unité
target
sera exécutée pour toutes les unités
service
en dessous.
Source : Operating a Cluster - Running Ceph with systemd.
Redémarrer un nœud du cluster
Si la machine héberge un démon OSD, 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 si on l’a désactivé au début.
# ceph osd unset noout
# ceph osd unset norebalance
Gestion des comptes utilisateurs
Ceph a un système interne de gestion des utilisateurs. Pour chaque utilisateur, il y a :
- un nom
type.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 clé et ses permissions sont :
Afficher un utilisateur
Afficher la clé et les permissions d’un utilisateur.
$ ceph auth get client.admin
exported keyring for client.admin
[client.admin]
key = REDACTED
caps mds = "allow *"
caps mgr = "allow *"
caps mon = "allow *"
caps osd = "allow *"
On constate que l’utilisateur
client.admin
a tous les droits sur chacun des éléments du cluster.
Autre exemple avec un utilisateur prévu pour interagir avec Libvirt.
[client.libvirt]
key = REDACTED
caps mon = "profile rbd"
caps osd = "profile rbd pool=nom_pool_ceph_rbd"
Créer un utilisateur
$ ceph auth get-or-create client.<id> mon 'allow r'
[client.<id>]
key = REDACTED
Par exemple, pour créer un utilisateur client.libvirt
prévu pour connecter Libvirt à Ceph :
$ ceph auth get-or-create client.libvirt mon 'profile rbd' osd 'profile rbd pool=nom_pool_ceph_rbd'
Dans cet exemple, on utilise un profil au lieu de préciser les différentes permissions à la main.
On peut aussi utiliser ceph auth add
, mais
ceph auth get-or-create
est plus pratique. La seconde
méthode va créer l’utilisateur puis afficher sa clef. On peut la
récupérer sur la sortie standard pour créer le fichier
/etc/ceph/ceph.client.<id>.keyring
. 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
.
Modifier un utilisateur
La commande suivante permet de modifier les droits d’un utilisateur. Cela va écraser ses droits actuels.
$ ceph auth caps client.<id> mon 'profile rbd' osd 'profile rbd pool=rbd'
Lister les utilisateurs
$ ceph auth ls
Supprimer un utilisateur
$ ceph auth del client.<id>
Note : penser à supprimer le fichier
/etc/ceph/ceph.client.<id>.keyring
s’il existe.
Sélectionner un utilisateur
Les commandes ceph
et rbd
supposent qu’on
est l’utilisateur client.admin
par défaut. Si on est censé
employer un autre utilisateur Ceph, on aura une erreur de cette forme
:
# ceph health
[errno 2] error connecting to the cluster
# rbd ls
YYYY-MM-DD HH:MM:SS.mmm 0123456789ab -1 auth: unable to find a keyring on /etc/ceph/ceph.client.admin.keyring,/etc/ceph/ceph.keyring,/etc/ceph/keyring,/etc/ceph/keyring.bin,: (2) No such file or directory
rbd: couldn't connect to the cluster!
Pour spécifier un utilisateur différent, il faut ajouter l’option
--id <id>
ou --name <type.id>
:
$ ceph --id <id> health
$ rbd --id <id> ls
Note : la clé de l’utilisateur doit être dans le fichier
/etc/ceph/ceph.client.<id>.keyring
.
Il est possible de définir des arguments par défaut pour ne pas avoir
à tout taper à chaque fois dans la variable d’environnement
CEPH_ARGS
:
$ export CEPH_ARGS="--id <id>"
$ ceph health
Gestion des OSD
Ajuster variable
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
:
Remplacer un OSD
Identifier la machine sur laquelle se trouve l’OSD :
ceph-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 :
ceph-osd# N=1 # On suppose que l'OSD 1 est down
ceph-osd# ceph osd out osd.$N
ceph-osd# systemctl stop ceph-osd@$N.service
ceph-osd# ceph osd crush remove osd.$N
ceph-osd# ceph auth del osd.$N
ceph-osd# ceph osd rm osd.$N
ceph-osd# umount /var/lib/ceph/osd/ceph-$N
Une fois que le disque a été remplacé, on ajoute le nouvel OSD :
ceph-osd# ceph-volume lvm zap /dev/sdX
ceph-osd# ceph-volume lvm prepare --osd-id <id> --data /dev/sdX
ceph-osd# ceph osd find <id> | grep fsid
"osd_fsid": "<fsid>",
ceph-osd# ceph-volume lvm activate <id> <fsid>
Supprimer un OSD
Attention: section à revoir
ceph-osd# OSD=0
ceph-osd# ceph osd out $OSD
ceph-osd# sudo systemctl stop ceph-osd@$OSD
ceph-osd# ceph osd purge $OSD --yes-i-really-mean-it
Consulter l’occupation du stockage
# 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 d’images RBD, l’espace
utilisé affiché correspond à l’espace réclamé. Si on crée un volume de 1
Tio, mais qu’on y écrit 100 Gio de zéros, le volume occupera 100 Gio du
point de vue de ceph df
. La boucle suivante permet d’avoir
une approximation en Gio de l’espace effectivement alloué par les images
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" }'
Note : 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é.
Installer Ceph sur un nœud client
Installer le paquet
ceph-common
.Configurer le réseau tel que la machine cliente puisse joindre :
les monitors sur les ports 6789 et 3300,
les manager sur la plage de ports 6800-7300,
les OSD sur la plage de ports 6800-7300.
S’il n’existe pas encore, créer un utilisateur Ceph.
Si la machine cliente est un hyperviseur et qu’on compte attacher des images RBD aux machines virtuelles, suivre #connecter-libvirt-à-ceph.
Pools
Dans le contexte de Ceph, un pool est un ensemble d’objets du même type. Pour comparer avec LVM, c’est une sorte de volume group.
Les objets d’un pool sont regroupés en PG et la répartition des objets est déterminée par une règle CRUSH.
Un pool doit avoir un type. Nous utilisons principalement le type RBD. Un pool de ce type ne contiendra que des images RBD.
Un pool a une taille, size
, qui correspond au nombre
d’exemplaires des objets qui le composent. Si un pool a une taille de 3,
c’est la taille par défaut, alors chaque objet existera alors en trois
exemplaire : un original et deux réplicas.
Créer un pool
# ceph osd pool create <poolname> <pg_num> <pgp_num> replicated <crush_rule_name> --autoscaler-mode=off
Par défaut, il y a un autoscaler qui ajuste le nombre de PG
du pool. L’option --autoscale-mode=off
désactive
l’autoscaler pour ce pool.
Pour déclarer qu’un pool hébergera des images RBD :
# rbd pool init <pool>
Supprimer un pool
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
Taille d’un pool
Voir la taille d’un pool
# ceph osd pool get <pool> size
Changer la taille d’un pool
# ceph osd pool set <pool> size <size>
Par exemple :
# ceph osd pool set rbd size 2
Les objects qui se trouve dans le pool rbd
auront alors
un seul réplica.
Note : Si on change le nombre de réplicas, la commande
ceph -s
affichera HEALTH_WARN
. Cet
avertissement est normal, car le nombre d’objet n’est pas cohérent avec
ce qu’on a demandé. L’avertissement disparaitra quand Ceph aura ajusté
le nombre de copies par objet.
Attention Il peut être nécessaire d’adapter la
variable min_size
. Cette variable définie le nombre de
réplicats minimum pour que le cluster accepte des IO. Par
exemple, si les variables size
et min_size
sont à 2, lorsque qu’un des deux objets est indisponibles (disque ou
machine hors service, maintenance, etc.), l’objet sera inaccessible en
écriture et en lecture, puisque le nombre d’objets disponibles est
inférieur à min_size
. Dans ce cas, il faudrait mettre
min_size
à 1 pour éviter de bloquer les IO :
# ceph osd pool set <pool> min_size 1
.
RADOS Block Device (RBD)
Une image RBD (RADOS Block Device) est un disque virtuel comme un fichier QCOW2 ou un volume logique LVM. Pour faire une analogie avec LVM :
RBD LV
Pool VG
OSD PV
Les opérations sur les images RBD (création, suppression,
agrandissement, etc.) se font principalement par la commande rbd
.
Il est aussi possible d’utiliser Libvirt ou qemu-img
.
Une image RBD est spécifiée par le pool dans lequel elle se trouve et
son nom : <pool>/<image>
. Par exemple :
p/vm00_root
fait référence à l’image vm00_root
dans le pool p
. Les pages de man utilisent le mot
images-spec
pour désigner la notation
<pool>/<image>
.
Astuce Avec la commande rbd
, si on
précise seulement <image>
sans
<pool>/
, c’est le pool rbd
qui est
utilisé par défaut. Ainsi les deux commandes suivantes sont équivalentes
:
# rbd resize rbd/vm00_home --size 100G
# rbd resize vm00_home --size 100G
Lister les images RBD
# rbd ls
# rbd ls -l
# rbd ls <pool>
# rbd -p <pool> ls
Avec Libvirt :
kvm# virsh vol-list --pool POOL_LIBVIRT
Créer une image RBD
Avec la commande rbd
:
# rbd create --size TAILLE NOM_POOL/NOM_IMAGE
Avec la commande qemu-img
:
kvm# qemu-img create -f rbd rbd:NOM_POOL/NOM_IMAGE:id=libvirt:conf=/etc/ceph/cephv2.conf TAILLE
Avec la commande virsh
:
kvm# virsh vol-create-as --pool NOM_POOL_LIBVIRT NOM_IMAGE TAILLE
Pour utiliser virsh
, il faut d’abord #connecter-libvirt-à-ceph.
Attacher localement une image RBD
On peut utiliser directement un volume RBD en l’attachant à sa
machine avec la commande rbd device map
(Debian ≥ 11) ou rbd map
(Debian < 11).
Exemples :
debian10# rbd map <pool>/<image>
debian12# rbd device map <pool>/<image>
Une fois attaché, le volume RBD peut être utilisé comme n’importe
quel autre disque (mount
, fdisk
,
mkfs
…). Les images RBD attachées sont visibles sous
/dev/rbd*
.
/dev/rbd
└── rbd
└── mon-image -> ../../rbd0
/dev/rbd0
Lister les images RBD attachées : rbd device list
(Debian ≥ 11) ou rbd showmapped
(Debian < 11)
Connecter Libvirt à Ceph
Suivre les étapes de la section #installer-ceph-sur-un-nœud-client.
Installer
qemu-block-extra
.Générer un UUID, on le nomme
UUID_DU_SECRET
dans la suite.Créer un fichier libvirt_secret_ceph.xml :
<secret ephemeral='no' private='no'> <uuid>UUID_DU_SECRET</uuid> <usage type='ceph'> <name>cephsecret</name> </usage> </secret>
Créer un fichier
libvirt_secret_cephv2.b64
contenant seulement une ligne avec la clé de l’utilisateur Ceph sans lekey =
pour Libvirt.Définir le secret :
kvm# virsh secret-define --file libvirt_secret_ceph.xml
.Assigner la clé au secret :
kvm# virsh secret-set-value --secret UUID_DU_SECRET --file libvirt_secret_cephv2.b64
.Supprimer les fichiers
libvirt_secret_cephv2.b64
etlibvirt_secret_ceph.xml
.
TODO Partie rbd cache à vérifier
Attention Il est possible de migrer à chaud une
machine virtuelle à laquelle on a attaché des images RBD, mais
le cache RBD doit être activé. Dans le fichier
/etc/ceph/ceph.conf
du client :
[client]
rbd cache = true
La suite est requise seulement si on souhaite gérer les images avec
virsh
.
Créer un fichier
pool-rbd.xml
décrivant le pool Libvirt.<pool type='rbd'> <name>POOL_LIBVIRT</name> <!-- Nom pool Libvirt --> <source> <name>rbd</name> <host name='CEPH_MON1' port='6789'/> <!-- IP ou hostname des monitors --> <host name='CEPH_MON2' port='6789'/> <host name='CEPH_MON3' port='6789'/> <auth type='ceph' username='libvirt'> <secret uuid='UUID_SECRET'/> <!-- Voir virsh secret-list --> </auth> </source> </pool>
Définir et démarrer le pool Libvirt.
kvm# virsh pool-define ./pool-rbd.xml kvm# virsh pool-start libvirtrbd
Attacher une image RBD à une machine virtuelle
Créer un fichier XML décrivant le disque de la forme suivant en adaptant
UUID
,NOM_IMAGE
, lesCEPH_MON*
, etDEV
:<disk type='network' device='disk'> <driver name='qemu' type='raw'/> <!-- TODO ajouter cache='writeback' pour migration à chaud ? --> <auth username='libvirt'> <secret type='ceph' uuid='UUID'/> <!-- UUID secret Libvirt, voir virsh secret-list --> </auth> <source protocol='rbd' name='rbd/NOM_IMAGE'> <host name='CEPH_MON1' port='6789'/> <!-- IP ou hostname des monitors --> <host name='CEPH_MON2' port='6789'/> <host name='CEPH_MON3' port='6789'/> </source> <target dev='DEV' bus='virtio'/> <!-- prendre un vdX libre, voir virsh domblklist DOMAIN --> </disk>
Attacher le disque :
kvm# virsh attach-device <DOMAIN> /root/newdevice.xml --persistent
Redimensionner une image RBD
On aura besoin de la taille actuelle de l’image. On peut l’obtenir
avec la commande rbd info <image>
.
Pour agrandir une image RBD attachée à une machine virtuelle où
newsize
est la taille finale de l’image et
non la quantité que l’on souhaite ajouter :
kvm-host# virsh blockresize <domain> <target> <newsize>
S’aider de virsh domblklist <domain>
pour choisir
<target>
(vda
, vdb
,
vdc
…). L’opération est faisable à chaud.
Exemple : ajouter 25 Gio au volume vdc
de 75 Gio attaché
de machine virtuelle www00
:
kvm-host# virsh blockresize www00 vdc 100G
Il restera à faire les opérations sur le systèmes de fichiers dans la
machine virtuelle (resize2fs
).
Si l’image est attachée localement avec rbd device map
:
# rbd resize <image> --size <newsize>
Note : ajouter l’option --allow-shrink
à la commande
rbd resize
pour réduire la taille d’une image.
Le reste de la procédure dépend du système de fichiers utilisé.
Supprimer une image RBD
Par sécurité, on place les images RBD dans une corbeille avant de les supprimer. Pour mettre une image dans la corbeille :
# rbd trash mv <pool>/<image>
Si le pool d’images RBD est
rbd
, on peut entrer :# rbd trash mv <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.
# rbd trash ls -l
# rbd trash ls -l <pool>
Si on a besoin de restaurer une image :
# rbd trash restore <pool>/<id>
Pour supprimer définitivement une image :
# rbd trash rm <pool>/<id>
Pour supprimer directement un volume RBD sans passer par la corbeille :
# rbd rm <pool>/<id>
Supprimer une image, depuis la corbeille ou non, peut prendre du temps (plus d’une minute).
Gérer les snapshots d’image RBD
Créer une snapshot :
$ rbd snap create <pool>/<image>@<snapshot>
Lister les snapshots :
$ rbd snap ls <pool>/<image>
Restaurer une snapshot :
$ rbd snap rollback <pool>/<image>@<snapshot>
Supprimer une snapshot :
$ rbd snap rm <pool>/<image>@<snapshot>
Source : Ceph Documentation - Snapshots
On peut faire une sauvegarde d’une images RBD manière similaire à ce
qui est présenté dans HowtoLVM#les-snapshots-lvm. Voici un exemple
avec rbd device map
pour un système de fichier Ext4 sans table de partition.
- Créer le snapshot bar de l’image RBD foo et l’attacher localement.
client# rbd snap create foo@bar
client# rbd map foo@bar
/dev/rbd1
- Monter le système de fichier en lecture seule.
client# mount -o ro,noload /dev/rbd1 /baz
Copier les données…
Démonter, détacher puis supprimer le snapshot.
client# umount /dev/rbd1
client# rbd unmap foo@bar
client# rbd snap rm foo@bar
Renommer une image RBD
Attention : si l’image RBD est attachée à une virtuelle ! Nous n’avons pas encore essayé de faire de renommage à chaud.
# rbd mv <old_image_name> <new_image_name>
Si le volume est attaché à une machine virtuelle, il faudra mettre à
jour la définition de la machine virtuelle avec
virsh edit
.
RADOS Gateway (RGW)
Ces démons fournissent une interface à une API S3-like ou Swift-like. Les démons RGW sont des clients pour le cluster Ceph.
Installer un démon RGW
TODO On suppose que rgw-host
est un
nœud du cluster Ceph. À généraliser.
rgw-host# apt install radosgw # certainement déjà installé
rgw-host# mkdir /var/lib/ceph/radosgw/ceph-rgw.rgw-host
rgw-host# ceph auth get client.bootstrap-rgw | grep -e '^\[' -e '^[[:space:]]*key' > /var/lib/ceph/bootstrap-rgw/ceph.keyring
rgw-host# ceph --cluster ceph --name client.bootstrap-rgw --keyring /var/lib/ceph/bootstrap-rgw/ceph.keyring auth get-or-create client.rgw.rgw-host osd 'allow rwx' mon 'allow rw' -o /var/lib/ceph/radosgw/ceph-rgw.rgw-host/keyring
rgw-host# rm /var/lib/ceph/bootstrap-rgw/ceph.keyring
rgw-host# systemctl enable ceph-radosgw@rgw.rgw-host
rgw-host# systemctl start ceph-radosgw@rgw.rgw-host
rgw-host# systemctl enable ceph.target
Cette procédure va provoquer la création de plusieurs pools pour le stockage objet.
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>
Gestion des utilisateurs RGW
Les utilisateurs Ceph et RGW n’ont rien à voir. Ce sont deux choses différentes.
Créer un utilisateur RGW
# 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ées pour s’identifier en tant que client.
Retrouver les accès API d’un utilisateur RGW
# radosgw-admin user info --uid='USERNAME' | grep -e 'access_key' -e 'secret_key'
Lister les utilisateurs RGW
# 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 RGW
# 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 }'
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
Installer checks spécifiques pour Ceph
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
.
Pour check_ceph_rgw
, le dépôt Github des
plugins Nagios pour Ceph demande de créer un utilisateur Ceph
avec seulement les droits d’écriture pour les moniteurs. Le
check ne fonctionnera pas avec ces permissions et 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
.
Pour 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>
Adapter
check_disk
pour /var/lib/ceph/osd
Ce check retournera une alerte
car le répertoire /var/lib/ceph/osd
n’est pas accessible.
Il faut faire ignorer ce chemin :
command[check_disk]=/usr/lib/nagios/plugins/check_disk … -I '^/var/lib/ceph/osd/'
.
Troubleshooting
TODO Section à revoir
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.
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
:
ceph-mon# systemctl stop ceph-mon@hostname.service ceph-mon# 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 la valeur de la variable :
# ceph config get mon_auth_allow_insecure_global_id_reclaim
Source : Ceph Documention - Health checks
Connexion impossible après 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 vers les monitors.
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
.