
Rook via Ceph n'approvisionne pas mes Persistent Volume Claims !
9 sept. 2019
- Catégories
- DevOps & SRE
- Tags
- PVC
- Linux
- Rook
- Ubuntu
- Ceph
- Cluster
- Internship
- Kubernetes [plus][moins]
Ne ratez pas nos articles sur l'open source, le big data et les systèmes distribués, fréquence faible d’un email tous les deux mois.
L’installation de Ceph dans un cluster Kubernetes peut être automatisé par l’utilisation de Rook. Actuellement en stage chez Adaltas, j’étais en charge de participer à la configuration d’un cluster Kubernetes (k8s). Pour éviter de casser quelque chose sur notre cluster production, nous avons décidé de faire nos expérimentations via l’installation d’un cluster k8s sur 3 machines virtuelles (un nœud maître n1, deux nœuds esclaves n2 et n3) en utilisant Vagrant avec VirtualBox sur le backend et Ubuntu 18.10 en tant qu’OS.
Lors de l’installation du cluster de test, nous avons rencontré un problème avec Rook en utilisant Ceph qui l’empêche d’approvisionner les Persistent Volume Claim (PVC). Cet article détaille comment effectuer une installation de base de Rook avec Ceph sur les machines virtuelles, le problème rencontré et comment le résoudre. Mais d’abord …
… un rappel rapide à propos du rôle des PVCs !
Lorsqu’un pod doit stocker diverses données (journaux ou métriques, par exemple) de manière persitante, elle doit décrire le type de stockage dont elle a besoin (taille, performance, …) dans un PVC. Le cluster fournira ensuite un Persistent Volume (PV) s’il correspond aux exigences du PVC. Le PV peut : soit être approvisionné statiquement si un administrateur a créé manuellement un PV correspondant, soit être approvisionné dynamiquement. La création manuelle de PVs peut être fastidieuses si beaucoup d’entre eux sont nécessaires aux pods, c’est pourquoi il est intéressant pour le cluster de pouvoir les approvisionner dynamiquement. Pour rendre le cluster capable de fournir de manière dynamique un PV, le PVC doit indiquer la Storage Class qu’il veut utiliser. Si une telle Storage Class est disponible sur le cluster, un PV sera fourni dynamiquement au pod.
Voici quelques liens que vous pouvez suivre si vous voulez en savoir à propos des PVCs, PVs et Storage Classes :
Installer Rook sur votre cluster k8s
L’installation d’un cluster k8s n’entrant pas dans le cadre de cet article, je vais supposer que vous avez déjà un cluster k8s opérationnel. Si ce n’est pas le cas, vous pouvez facilement trouver de la documentation sur internet afin de bootstraper rapidement un cluster k8s.
Le processus d’installation de Rook n’est pas compliqué, il suffit d’appliquer quelques manifestes. Première étape, clonez le repo git de Rook :
git clone https://github.com/rook/rook
Puis passez au dernier tag de version (qui est v1.0.1 au moment de l’écriture de cet article) en utilisant :
git checkout v1.0.1
Les fichiers d’intérêts (qui sont listés ci-dessous) se trouvent dans le dossier cluster/examples/kubernetes/ceph
.
common.yaml
operator.yaml
cluster.yaml
storageclass.yaml
Appliquez chacun d’entre eux dans l’ordre dans lequel ils sont listés avec :
kubectl apply -f <file.yaml>
La dernière étape est de définir la resources storageclass
, inscrite dans le fichier storageclass.yaml
que nous venons d’appliquer, comme storageclass
par défaut dans notre cluster. Pour ce faire, exécutez la commande suivante :
kubectl patch storageclass rook-ceph-block \
-p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'
Le problème
Le cluster Rook prendra un certain temps à se déployer, le temps de télécharger les images nécessaires et de déployer les pods. Après quelques minutes, la sortie de kubectl get pods -n rook-ceph
devrait ressembler à celle-ci :
NAME READY STATUS RESTARTS AGE
rook-ceph-agent-8zv7p 1/1 Running 0 4m8s
rook-ceph-agent-ghwgl 1/1 Running 0 4m8s
rook-ceph-mgr-a-6d8cf6d5d7-txnrj 1/1 Running 0 102s
rook-ceph-mon-a-588475cbdb-htt4h 1/1 Running 0 2m55s
rook-ceph-mon-b-5b7cdc894f-q6wwr 1/1 Running 0 2m47s
rook-ceph-mon-c-846fc479cb-96sjq 1/1 Running 0 119s
rook-ceph-operator-765ff54667-q5qk4 1/1 Running 0 4m43s
rook-ceph-osd-prepare-n2.k8s.test-d4p9w 0/2 Completed 0 80s
rook-ceph-osd-prepare-n3.k8s.test-lrkbc 0/2 Completed 0 80s
rook-discover-hxxtl 1/1 Running 0 4m8s
rook-discover-mmdl5 1/1 Running 0 4m8s
Comme nous pouvons le voir ici, il existe deux modules appelés rook-ceph-osd-prepare...
pour lesquels le statut est “Terminé”. Nous nous attendions à voir apparaitre des pods OSD (Object Storage Device) une fois le statut des modules rook-ceph-osd-prepare ...
terminés mais ce n’est pas le cas ici. Les pods OSD n’apparaissant pas, ce qui signifie que les futures PVC ne seront pas approvisionnés par Rook et resteront en attente. Nous pouvons voir un exemple de ce problème lorsque nous essayons de déployer une instance Gitlab avec Helm. Voici le résultat de kubectl get pvc -n gitlab
:
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
gitlab-minio Pending rook-ceph-block 6m7s
gitlab-postgresql Pending rook-ceph-block 6m7s
gitlab-prometheus-server Pending rook-ceph-block 6m7s
gitlab-redis Pending rook-ceph-block 6m7s
repo-data-gitlab-gitaly-0 Pending rook-ceph-block 6m6s
Nous pouvons voir qu’aucun PVC n’est approvisionné quand bien même ils ont été assigné la bonne Storage Class.
La solution
Après quelques recherches, nous avons découvert qu’en fait, pour que Rook fonctionne, nous avons besoin d’avoir un périphérique de stockage dédié qu’il peut utiliser pour stocker les PVs. Pour résoudre ce problème, nous avions besoin dans notre cas d’ajouter un nouveau disque virtuel à nos machines virtuelles via le fichier VagrantFile
.
Pour créer et attacher un nouveau disque virtuel à une machine virtuelle VirtualBox, nous devons utiliser la commande VBoxManage
, ou nous pouvons plus facilement le définir directement dans le VagrantFile
, comme dans cet extrait :
#[...]
config.vm.define :n2 do |node|
node.vm.box = box
node.vm.hostname = "n2"
node.vm.network :private_network, ip: "10.10.10.53"
node.vm.provider "virtualbox" do |d|
d.customize ["modifyvm", :id, "--memory", 4096]
d.customize ["modifyvm", :id, "--cpus", 2]
d.customize ["modifyvm", :id, "--ioapic", "on"]
# Creating a virtual disk called "disk_osd-n2" with a size of 125GB
d.customize ["createhd", "--filename", "disk_osd-n2", "--size", 125 * 1024]
# Attaching the newly created virtual disk to our node
d.customize ["storageattach", :id, "--storagectl", "SCSI", "--port", 3, "--device", 0, "--type", "hdd", "--medium", "disk_osd-n2.vdi"]
end
end
#[...]
Le champ à la suite de "--storagectl"
sur la dernière ligne doit correspondre au nom exact d’un contrôleur de stockage de la machine virtuelle utilisée. Il est possible d’obtenir ceux-ci à partir de la commande suivante, muni du nom de la machine virtuelle provenant de VBoxManage list vms
:
VBoxManage showvminfo <vm-name>| grep "Storage Controller"
Prenez le nom d’un contrôleur de stockage ayant des ports libres, et remplacez-le dans la configuration ci-dessus à la place de l’exemple SCSI
.
Si nous lançons une nouvelle fois l’installation dans son ensemble, nous pouvons voir que les pods OSD apparaissent :
NAME READY STATUS RESTARTS AGE
rook-ceph-agent-gs4sn 1/1 Running 0 3m55s
rook-ceph-agent-hwrrf 1/1 Running 0 3m55s
rook-ceph-mgr-a-dbdffd588-v2x2b 1/1 Running 0 75s
rook-ceph-mon-a-f5d5d4654-nmk6j 1/1 Running 0 2m28s
rook-ceph-mon-b-6c98476587-jq2s5 1/1 Running 0 104s
rook-ceph-mon-c-6f9f7f5bd6-8r8qw 1/1 Running 0 91s
rook-ceph-operator-765ff54667-vqj4p 1/1 Running 0 4m29s
rook-ceph-osd-0-5cf569ddf5-rw827 1/1 Running 0 28s <== Ici!
rook-ceph-osd-1-7577f777f9-vjxml 1/1 Running 0 22s <== Et ici
rook-ceph-osd-prepare-n2.k8s.test-bdw2g 0/2 Completed 0 51s
rook-ceph-osd-prepare-n3.k8s.test-26d86 0/2 Completed 0 51s
rook-discover-mblm6 1/1 Running 0 3m55s
rook-discover-wsk2z 1/1 Running 0 3m55s
Et si nous vérifions le PVC créé par l’installation faite par Helm de Gitlab :
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
gitlab-minio Bound pvc-5f32d9f5-7d76-11e9-b3fe-02897c39bcfa 10Gi RWO rook-ceph-block 19s
gitlab-postgresql Bound pvc-5f342615-7d76-11e9-b3fe-02897c39bcfa 8Gi RWO rook-ceph-block 19s
gitlab-prometheus-server Bound pvc-5f34feb5-7d76-11e9-b3fe-02897c39bcfa 8Gi RWO rook-ceph-block 19s
gitlab-redis Bound pvc-5f3a0d3d-7d76-11e9-b3fe-02897c39bcfa 5Gi RWO rook-ceph-block 19s
repo-data-gitlab-gitaly-0 Bound pvc-5fe63ad2-7d76-11e9-b3fe-02897c39bcfa 50Gi RWO rook-ceph-block 17s
Les PVCs sont enfin approvisionné !
Un peu plus loin, customiser cluster.yaml
Vous avez peut-être remarqué que nous n’avons donné aucune information à Rook sur la façon de procéder afin de trouver un périphérique approprié à utiliser pour le stockage ; il le détecte juste de manière autonome celui que nous avons attaché à la machine virtuelle et l’a utilisé. Pour beaucoup de raisons évidentes, ce n’est certainement pas un comportement souhaité étant donné que dans contexte réel, nous pourrions avoir nombreux dispositifs connectés ayant un but différent de celui de simplement fournir du stockage à Rook. Il est bien sûr possible de personnaliser la façon dont il trouve et utilise le stockage. Tout est défini dans le manifeste cluster.yaml
. Les catégorie associé du manifeste est storage
. Voici la configuration par défaut :
storage:
useAllNodes: true
useAllDevices: true # <==
deviceFilter:
location:
config:
Le champ useAllDevices
a la valeur true
. Depuis la documentation officielle de Rook : il indique “si tous les périphériques trouvés sur les nœuds du cluster doivent être automatiquement consommé par OSDs”. La solution consiste à indiquer à Rook où regarder au lieu de sélectionner automatiquement tout périphérique disponible. Si nous mettons useAllDevices
à false
, nous pouvons utiliser les champs suivants :
deviceFilter
pour définir un filtre regex ; par exemple^sd[a-d]
pour trouver un disque commençant par “sd” puis suivis par a, b, c ou d,devices
pour définir une liste de disques individuel qui pourront être utilisés,directories
pour définir une liste de répertoires qui seront utilisés comme espace de stockage pour le cluster.
Il est aussi possible de définir une configuration par node en réglant useAllNodes
à false
, mais cela sort du cadre de cet article. Si vous voulez en apprendre plus à propos de la configuration du stockage pour Rook, vous pouvez jeter un œil à la documention.
The end
Merci d’avoir lu cet article, j’espère qu’il vous aura apporté un peu de lumière si vous étiez confronté au même problème !