L'Interface de Stockage de Conteneurs (CSI) est une interface unifiée pour l'interaction entre Kubernetes et les systèmes de stockage. Nous en avons déjà parlé brièvement, , et aujourd'hui, nous allons examiner plus en détail le lien entre CSI et Ceph : nous allons vous montrer comment au cluster Kubernetes.
Cet article présente des exemples réels, bien qu'un peu simplifiés pour faciliter la compréhension. Nous ne traiterons pas de l'installation et de la configuration des clusters Ceph et Kubernetes.
Vous vous demandez comment cela fonctionne ?

Donc, vous avez un cluster Kubernetes déployé, par exemple, . À côté, un cluster Ceph fonctionne également — vous pouvez également l'installer, par exemple, avec cet J'espère qu'il n'est pas nécessaire de mentionner que pour la production, il doit y avoir un réseau entre eux avec une bande passante d'au moins 10 Gbit/s.
Si tout cela est en place, allons-y !
Tout d'abord, connectons-nous à l'un des nœuds du cluster Ceph et vérifions que tout fonctionne correctement :
ceph health
ceph -sEnsuite, créons un pool pour les disques RBD :
ceph osd pool create kube 32
ceph osd pool application enable kube rbdPassons au cluster Kubernetes. Là, nous allons d'abord installer le pilote Ceph CSI pour RBD. Nous allons l'installer comme il se doit, à l'aide de Helm.
Ajoutons le dépôt avec le chart et obtenons un ensemble de variables pour le chart ceph-csi-rbd :
helm repo add ceph-csi https://ceph.github.io/csi-charts
helm inspect values ceph-csi/ceph-csi-rbd > cephrbd.ymlMaintenant, nous devons remplir le fichier cephrbd.yml. Pour cela, découvrons l'ID du cluster et les adresses IP des moniteurs dans Ceph :
ceph fsid # ainsi, nous découvrons le clusterID
ceph mon dump # ici, nous verrons les adresses IP des moniteursInsérons les valeurs obtenues dans le fichier cephrbd.yml. En même temps, activons la création de politiques PSP (Pod Security Policies). Les options dans les sections nodeplugin et provisioner sont déjà présentes dans le fichier, elles peuvent être modifiées comme indiqué ci-dessous :
csiConfig:
- clusterID: "bcd0d202-fba8-4352-b25d-75c89258d5ab"
monitors:
- "v2:172.18.8.5:3300/0,v1:172.18.8.5:6789/0"
- "v2:172.18.8.6:3300/0,v1:172.18.8.6:6789/0"
- "v2:172.18.8.7:3300/0,v1:172.18.8.7:6789/0"
nodeplugin:
podSecurityPolicy:
enabled: true
provisioner:
podSecurityPolicy:
enabled: trueEnsuite, il ne nous reste plus qu'à installer le chart dans le cluster Kubernetes.
helm upgrade -i ceph-csi-rbd ceph-csi/ceph-csi-rbd -f cephrbd.yml -n ceph-csi-rbd --create-namespaceSuper, le pilote RBD fonctionne !
Créons un nouveau StorageClass dans Kubernetes. Pour cela, nous devrons à nouveau travailler un peu avec Ceph.
Créons un nouvel utilisateur dans Ceph et donnons-lui des droits d'écriture sur le pool kube:
ceph auth get-or-create client.rbdkube mon 'profile rbd' osd 'profile rbd pool=kube'Et maintenant, regardons la clé d'accès au même endroit :
ceph auth get-key client.rbdkubeLa commande renverra quelque chose comme :
AQCO9NJbhYipKRAAMqZsnqqS/T8OYQX20xIa9A==Inscrivons cette valeur dans un Secret dans le cluster Kubernetes — où elle est nécessaire userKey:
---
apiVersion: v1
kind: Secret
metadata:
name: csi-rbd-secret
namespace: ceph-csi-rbd
stringData:
# Les valeurs des clés correspondent au nom d'utilisateur et à sa clé, comme indiqué dans
# le cluster Ceph. L'ID de l'utilisateur doit avoir accès au pool,
# spécifié dans la classe de stockage
userID: rbdkube
userKey:Et créons notre secret :
kubectl apply -f secret.yamlEnsuite, nous avons besoin d'un manifeste StorageClass comme celui-ci :
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: csi-rbd-sc
provisioner: rbd.csi.ceph.com
parameters:
clusterID:
pool: kube
imageFeatures: layering
# Ces secrets doivent contenir des données pour l'authentification
# dans votre pool.
csi.storage.k8s.io/provisioner-secret-name: csi-rbd-secret
csi.storage.k8s.io/provisioner-secret-namespace: ceph-csi-rbd
csi.storage.k8s.io/controller-expand-secret-name: csi-rbd-secret
csi.storage.k8s.io/controller-expand-secret-namespace: ceph-csi-rbd
csi.storage.k8s.io/node-stage-secret-name: csi-rbd-secret
csi.storage.k8s.io/node-stage-secret-namespace: ceph-csi-rbd
csi.storage.k8s.io/fstype: ext4
reclaimPolicy: Delete
allowVolumeExpansion: true
mountOptions:
- discardIl faut remplir clusterID, que nous avons déjà appris avec la commande ceph fsid, et appliquer ce manifeste dans le cluster Kubernetes :
kubectl apply -f storageclass.yamlPour vérifier le fonctionnement des clusters en tandem, créons un PVC (Persistent Volume Claim) comme ceci :
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: rbd-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: csi-rbd-scVoyons tout de suite comment Kubernetes a créé le volume demandé dans Ceph :
kubectl get pvc
kubectl get pvTout semble parfait ! Et comment cela se présente-t-il du côté de Ceph ?
Obtenons la liste des volumes dans le pool et consultons les informations sur notre volume :
rbd ls -p kube
rbd -p kube info csi-vol-eb3d257d-8c6c-11ea-bff5-6235e7640653 # ici, il y aura bien sûr un autre ID de volume, que vous a donnée la commande précédenteMaintenant, voyons comment fonctionne l'augmentation de la taille du volume RBD.
Modifiez la taille du volume dans le manifeste pvc.yaml à 2Gi et appliquez-le :
kubectl apply -f pvc.yamlAttendez que les changements prennent effet, puis regardez à nouveau la taille du volume.
rbd -p kube info csi-vol-eb3d257d-8c6c-11ea-bff5-6235e7640653
kubectl get pv
kubectl get pvcNous voyons que la taille du PVC n'a pas changé. Pour connaître la raison, vous pouvez demander à Kubernetes la description du PVC au format YAML :
kubectl get pvc rbd-pvc -o yamlEt voici le problème :
message: Waiting for user to (re-)start a pod to finish file system resize of volume on node. type: FileSystemResizePending
C'est-à-dire que le disque a été agrandi, mais le système de fichiers dessus ne l'est pas.
Pour augmenter le système de fichiers, il faut monter le volume. Actuellement, notre PVC/PV créé n'est pas utilisé.
Nous pouvons créer un Pod de test, par exemple comme ceci :
---
apiVersion: v1
kind: Pod
metadata:
name: csi-rbd-demo-pod
spec:
containers:
- name: web-server
image: nginx:1.17.6
volumeMounts:
- name: mypvc
mountPath: /data
volumes:
- name: mypvc
persistentVolumeClaim:
claimName: rbd-pvc
readOnly: falseEt maintenant, regardons le PVC :
kubectl get pvcLa taille a changé, tout va bien.
Dans la première partie, nous avons travaillé avec un dispositif de bloc RBD (c'est exactement ce que signifie - Rados Block Device), mais ce n'est pas possible si plusieurs microservices doivent accéder simultanément à ce disque. Pour le travail avec des fichiers, plutôt qu'avec une image de disque, CephFS est beaucoup mieux adapté.
Prenons l'exemple des clusters Ceph et Kubernetes pour configurer CSI et les autres entités nécessaires pour travailler avec CephFS.
Nous allons obtenir les valeurs à partir de notre nouveau Helm chart :
helm inspect values ceph-csi/ceph-csi-cephfs > cephfs.ymlNous devons de nouveau remplir le fichier cephfs.yml. Comme précédemment, les commandes Ceph vont nous aider :
ceph fsid
ceph mon dumpRemplissons le fichier avec les valeurs comme suit :
csiConfig:
- clusterID: "bcd0d202-fba8-4352-b25d-75c89258d5ab"
monitors:
- "172.18.8.5:6789"
- "172.18.8.6:6789"
- "172.18.8.7:6789"
nodeplugin:
httpMetrics:
enabled: true
containerPort: 8091
podSecurityPolicy:
enabled: true
provisioner:
replicaCount: 1
podSecurityPolicy:
enabled: trueNotez que les adresses des moniteurs sont indiquées sous la forme simple address:port. Pour monter cephfs sur le nœud, ces adresses sont transmises au module du noyau, qui ne sait pas encore travailler avec le protocole des moniteurs v2.
Nous changeons le port pour httpMetrics (c'est là que Prometheus ira chercher les métriques pour le suivi) afin qu'il ne soit pas en conflit avec nginx-proxy, qui est installé par Kubespray. Ce n'est peut-être pas nécessaire pour vous.
Installons le Helm chart dans le cluster Kubernetes :
helm upgrade -i ceph-csi-cephfs ceph-csi/ceph-csi-cephfs -f cephfs.yml -n ceph-csi-cephfs --create-namespaceNous passons au stockage de données Ceph pour créer un utilisateur distinct. La documentation indique que le provisionneur CephFS a besoin de droits d'accès administrateur au cluster. Mais nous allons créer un utilisateur distinct fs avec des droits limités :
ceph auth get-or-create client.fs mon 'allow r' mgr 'allow rw' mds 'allow rws' osd 'allow rw pool=cephfs_data, allow rw pool=cephfs_metadata'Et nous allons immédiatement regarder sa clé d'accès, elle nous sera utile par la suite :
ceph auth get-key client.fsCréons des Secret et StorageClass distincts.
Rien de nouveau, nous l'avons déjà vu avec l'exemple RBD :
---
apiVersion: v1
kind: Secret
metadata:
name: csi-cephfs-secret
namespace: ceph-csi-cephfs
stringData:
# Nécessaire pour les volumes créés dynamiquement
adminID: fs
adminKey:Appliquons le manifeste :
kubectl apply -f secret.yamlEt maintenant - une StorageClass distincte :
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: csi-cephfs-sc
provisioner: cephfs.csi.ceph.com
parameters:
clusterID:
# Nom du système de fichiers CephFS dans lequel le volume sera créé
fsName: cephfs
# (facultatif) Pool Ceph où les données du volume seront stockées
# pool: cephfs_data
# (facultatif) Options de montage séparées par des virgules pour Ceph-fuse
# par exemple:
# fuseMountOptions: debug
# (facultatif) Options de montage séparées par des virgules pour CephFS pour le noyau
# Voir man mount.ceph pour la liste de ces options. Par exemple:
# kernelMountOptions: readdir_max_bytes=1048576,norbytes
# Les secrets doivent contenir les accès pour l'administrateur et/ou l'utilisateur Ceph.
csi.storage.k8s.io/provisioner-secret-name: csi-cephfs-secret
csi.storage.k8s.io/provisioner-secret-namespace: ceph-csi-cephfs
csi.storage.k8s.io/controller-expand-secret-name: csi-cephfs-secret
csi.storage.k8s.io/controller-expand-secret-namespace: ceph-csi-cephfs
csi.storage.k8s.io/node-stage-secret-name: csi-cephfs-secret
csi.storage.k8s.io/node-stage-secret-namespace: ceph-csi-cephfs
# (facultatif) Le pilote peut utiliser soit ceph-fuse (fuse),
# soit ceph kernelclient (kernel).
# Si non spécifié, le montage des volumes par défaut sera utilisé,
# cela est déterminé par la recherche de ceph-fuse et mount.ceph
# mounter: kernel
reclaimPolicy: Delete
allowVolumeExpansion: true
mountOptions:
- debugRemplissons ceci clusterID et appliquons-le dans Kubernetes :
kubectl apply -f storageclass.yamlVérification
Pour vérifier, comme dans l'exemple précédent, créons PVC :
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: csi-cephfs-pvc
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 5Gi
storageClassName: csi-cephfs-scEt vérifions la présence de PVC/PV :
kubectl get pvc
kubectl get pvSi vous souhaitez voir les fichiers et répertoires dans CephFS, vous pouvez monter ce système de fichiers quelque part. Par exemple, comme indiqué ci-dessous.
Accédons à l'un des nœuds du cluster Ceph et effectuons les actions suivantes :
# Точка монтирования
mkdir -p /mnt/cephfs
# Создаём файл с ключом администратора
ceph auth get-key client.admin >/etc/ceph/secret.key
# Добавляем запись в /etc/fstab
# !! Изменяем ip адрес на адрес нашего узла
echo "172.18.8.6:6789:/ /mnt/cephfs ceph name=admin,secretfile=/etc/ceph/secret.key,noatime,_netdev 0 2" >> /etc/fstab
mount /mnt/cephfsÉvidemment, un tel montage FS sur un nœud Ceph est strictement destiné à des fins pédagogiques, ce que nous faisons dans nos . Je ne pense pas que quelqu'un va faire cela en production, le risque d'écraser accidentellement des fichiers importants est grand.
Enfin, vérifions comment cela se passe avec le changement de taille des volumes dans le cas de CephFS. Revenons à Kubernetes et modifions notre manifeste pour PVC — augmentons la taille, par exemple, à 7Gi.
Appliquons le fichier modifié :
kubectl apply -f pvc.yamlVérifions dans le répertoire monté comment la quota a changé :
getfattr -n ceph.quota.max_bytesPour exécuter cette commande, vous devrez peut-être installer le paquet attr.
Les yeux ont peur, mais les mains font
À première vue, tous ces sorts et ces longs manifestes YAML semblent compliqués, mais en pratique, les étudiants de Slyrm s'en sortent assez rapidement.
Dans cet article, nous n'avons pas approfondi le sujet — pour cela, il existe la documentation officielle. Si vous êtes intéressé par les détails de la configuration du stockage Ceph avec un cluster Kubernetes, ces liens vous seront utiles :
Dans le cours Slyrm vous pouvez aller encore un peu plus loin et déployer une vraie application dans Kubernetes qui utilisera CephFS comme stockage pour les fichiers. Grâce aux requêtes GET/POST, vous pourrez transférer des fichiers et les récupérer depuis Ceph.
Si vous êtes davantage intéressé par le stockage des données, inscrivez-vous à . Pendant la phase de bêta-test, le cours est disponible à prix réduit et vous pouvez influencer son contenu.
Auteur de l'article : Alexandre Chvalov, ingénieur praticien , Administrateur Kubernetes Certifié, auteur et développeur des cours Slyrm.
Source : habr.com
