Exemple pratique de connexion d'un stockage basé sur Ceph à un cluster Kubernetes

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, ont raconté, et aujourd'hui, nous allons examiner plus en détail le lien entre CSI et Ceph : nous allons vous montrer comment connecter le stockage Ceph 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 ?

Exemple pratique de connexion d'un stockage basé sur Ceph à un cluster Kubernetes

Donc, vous avez un cluster Kubernetes déployé, par exemple, kubespray. À côté, un cluster Ceph fonctionne également — vous pouvez également l'installer, par exemple, avec cet ensemble de playbooks.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 -s

Ensuite, créons un pool pour les disques RBD :

ceph osd pool create kube 32
ceph osd pool application enable kube rbd

Passons 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.yml

Maintenant, 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 moniteurs

Insé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: true

Ensuite, 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-namespace

Super, 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.rbdkube

La 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.yaml

Ensuite, 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:
  - discard

Il 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.yaml

Pour 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-sc

Voyons tout de suite comment Kubernetes a créé le volume demandé dans Ceph :

kubectl get pvc
kubectl get pv

Tout 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édente

Maintenant, 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.yaml

Attendez 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 pvc

Nous 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 yaml

Et 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: false

Et maintenant, regardons le PVC :

kubectl get pvc

La 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.yml

Nous devons de nouveau remplir le fichier cephfs.yml. Comme précédemment, les commandes Ceph vont nous aider :

ceph fsid
ceph mon dump

Remplissons 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: true

Notez 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-namespace

Nous 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.fs

Cré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.yaml

Et 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:
  - debug

Remplissons ceci clusterID et appliquons-le dans Kubernetes :

kubectl apply -f storageclass.yaml

Vé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-sc

Et vérifions la présence de PVC/PV :

kubectl get pvc
kubectl get pv

Si 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 cours Slurm. 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.yaml

Vérifions dans le répertoire monté comment la quota a changé :

getfattr -n ceph.quota.max_bytes

Pour 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 :

Principes généraux du fonctionnement de Kubernetes avec des volumes
Documentation sur RBD
Intégration de RBD et Kubernetes du point de vue de Ceph
Intégration de RBD et Kubernetes du point de vue du CSI
Documentation générale sur CephFS
Intégration de CephFS et Kubernetes du point de vue du CSI

Dans le cours Slyrm Base Kubernetes 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 à un nouveau cours sur Ceph. 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 Southbridge, Administrateur Kubernetes Certifié, auteur et développeur des cours Slyrm.

Source : habr.com

Acheter un hébergement fiable pour les sites avec protection DDoS, serveurs VPS VDS 🔥 Acheter un hébergement fiable pour les sites avec protection DDoS, serveurs VPS VDS | ProHoster