Container Storage Interface (CSI) est une interface unifiée entre Kubernetes et les systèmes de stockage. Nous en avons déjà parlé brièvement
L'article fournit des exemples réels, quoique légèrement simplifiés, pour faciliter la perception. Nous n'envisageons pas d'installer et de configurer les clusters Ceph et Kubernetes.
Vous vous demandez comment ça marche ?
Ainsi, vous avez à portée de main un cluster Kubernetes, déployé par exemple,
Si vous avez tout cela, c'est parti !
Tout d'abord, allons sur l'un des nœuds du cluster Ceph et vérifions que tout est en ordre :
ceph health
ceph -s
Ensuite, nous allons immédiatement créer un pool pour les disques RBD :
ceph osd pool create kube 32
ceph osd pool application enable kube rbd
Passons au cluster Kubernetes. Là, tout d’abord, nous installerons le pilote Ceph CSI pour RBD. Nous installerons, comme prévu, via Helm.
On ajoute un référentiel avec un graphique, on obtient un ensemble de variables pour le graphique ceph-csi-rbd :
helm repo add ceph-csi https://ceph.github.io/csi-charts
helm inspect values ceph-csi/ceph-csi-rbd > cephrbd.yml
Vous devez maintenant remplir le fichier cephrbd.yml. Pour ce faire, recherchez l'ID de cluster et les adresses IP des moniteurs dans Ceph :
ceph fsid # так мы узнаем clusterID
ceph mon dump # а так увидим IP-адреса мониторов
Nous entrons les valeurs obtenues dans le fichier cephrbd.yml. Parallèlement, nous permettons la création de politiques PSP (Pod Security Policy). Options dans les sections plugin de nœud и fournisseur déjà dans le fichier, ils peuvent être corrigés 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 la charte 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 une nouvelle StorageClass dans Kubernetes. Cela nécessite encore une fois un peu de bricolage avec Ceph.
Nous créons un nouvel utilisateur dans Ceph et lui donnons le droit d'écrire dans le pool Kube:
ceph auth get-or-create client.rbdkube mon 'profile rbd' osd 'profile rbd pool=kube'
Voyons maintenant que la clé d'accès est toujours là :
ceph auth get-key client.rbdkube
La commande affichera quelque chose comme ceci :
AQCO9NJbhYipKRAAMqZsnqqS/T8OYQX20xIa9A==
Ajoutons cette valeur à Secret dans le cluster Kubernetes - là où nous en avons besoin Clé utilisateur:
---
apiVersion: v1
kind: Secret
metadata:
name: csi-rbd-secret
namespace: ceph-csi-rbd
stringData:
# Значения ключей соответствуют имени пользователя и его ключу, как указано в
# кластере Ceph. ID юзера должен иметь доступ к пулу,
# указанному в storage class
userID: rbdkube
userKey: <user-key>
Et nous créons notre secret :
kubectl apply -f secret.yaml
Ensuite, nous avons besoin d’un manifeste StorageClass ressemblant à ceci :
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: csi-rbd-sc
provisioner: rbd.csi.ceph.com
parameters:
clusterID: <cluster-id>
pool: kube
imageFeatures: layering
# Эти секреты должны содержать данные для авторизации
# в ваш пул.
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
Doit être rempli ID de cluster, ce que nous avons déjà appris par l'équipe céph fsidet appliquez ce manifeste au cluster Kubernetes :
kubectl apply -f storageclass.yaml
Pour vérifier comment les clusters fonctionnent ensemble, créons le PVC (Persistent Volume Claim) suivant :
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: rbd-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: csi-rbd-sc
Voyons immédiatement comment Kubernetes a créé le volume demandé dans Ceph :
kubectl get pvc
kubectl get pv
Tout semble génial ! A quoi cela ressemble-t-il du côté de Ceph ?
Nous obtenons une liste des volumes dans le pool et visualisons des informations sur notre volume :
rbd ls -p kube
rbd -p kube info csi-vol-eb3d257d-8c6c-11ea-bff5-6235e7640653 # тут, конечно же, будет другой ID тома, который выдала предыдущая команда
Voyons maintenant comment fonctionne le redimensionnement d'un volume RBD.
Modifiez la taille du volume dans le manifeste pvc.yaml en 2Gi et appliquez-la :
kubectl apply -f pvc.yaml
Attendons que les modifications prennent effet et examinons à nouveau la taille du volume.
rbd -p kube info csi-vol-eb3d257d-8c6c-11ea-bff5-6235e7640653
kubectl get pv
kubectl get pvc
On voit que la taille du PVC n'a pas changé. Pour savoir pourquoi, vous pouvez interroger Kubernetes pour obtenir une description YAML du PVC :
kubectl get pvc rbd-pvc -o yaml
Voici le problème :
message : En attente que l'utilisateur (re)démarre un pod pour terminer le redimensionnement du système de fichiers du volume sur le nœud. tapez : FileSystemResizePending
Autrement dit, le disque a grandi, mais pas le système de fichiers qu'il contient.
Pour développer le système de fichiers, vous devez monter le volume. Dans notre pays, le PVC/PV créé n’est actuellement utilisé d’aucune manière.
On peut 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 le périphérique de bloc RBD (il signifie Rados Block Device), mais cela ne peut pas être fait si différents microservices doivent fonctionner simultanément avec ce disque. CephFS est bien mieux adapté pour travailler avec des fichiers plutôt qu'avec des images disque.
En utilisant l'exemple des clusters Ceph et Kubernetes, nous configurerons CSI et d'autres entités nécessaires pour fonctionner avec CephFS.
Obtenons les valeurs du nouveau graphique Helm dont nous avons besoin :
helm inspect values ceph-csi/ceph-csi-cephfs > cephfs.yml
Encore une fois, vous devez remplir le fichier cephfs.yml. Comme auparavant, les commandes Ceph aideront à :
ceph fsid
ceph mon dump
Remplissez le fichier avec des valeurs comme celle-ci :
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
Veuillez noter que les adresses des moniteurs sont spécifiées sous la forme simple adresse:port. Pour monter des cephfs sur un nœud, ces adresses sont transférées au module noyau, qui ne sait pas encore fonctionner avec le protocole de surveillance v2.
Nous modifions le port pour httpMetrics (Prometheus y ira pour surveiller les métriques) afin qu'il n'entre pas en conflit avec nginx-proxy, qui est installé par Kubespray. Vous n’en aurez peut-être pas besoin.
Installez la charte Helm dans le cluster Kubernetes :
helm upgrade -i ceph-csi-cephfs ceph-csi/ceph-csi-cephfs -f cephfs.yml -n ceph-csi-cephfs --create-namespace
Allons au magasin de données Ceph pour y créer un utilisateur distinct. La documentation indique que le fournisseur CephFS nécessite des droits d'accès d'administrateur de 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 regardons tout de suite sa clé d’accès, nous en aurons besoin plus tard :
ceph auth get-key client.fs
Créons des Secret et StorageClass séparés.
Rien de nouveau, nous l’avons déjà vu dans l’exemple du RBD :
---
apiVersion: v1
kind: Secret
metadata:
name: csi-cephfs-secret
namespace: ceph-csi-cephfs
stringData:
# Необходимо для динамически создаваемых томов
adminID: fs
adminKey: <вывод предыдущей команды>
Application du 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: <cluster-id>
# Имя файловой системы CephFS, в которой будет создан том
fsName: cephfs
# (необязательно) Пул Ceph, в котором будут храниться данные тома
# pool: cephfs_data
# (необязательно) Разделенные запятыми опции монтирования для Ceph-fuse
# например:
# fuseMountOptions: debug
# (необязательно) Разделенные запятыми опции монтирования CephFS для ядра
# См. man mount.ceph чтобы узнать список этих опций. Например:
# kernelMountOptions: readdir_max_bytes=1048576,norbytes
# Секреты должны содержать доступы для админа и/или юзера 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
# (необязательно) Драйвер может использовать либо ceph-fuse (fuse),
# либо ceph kernelclient (kernel).
# Если не указано, будет использоваться монтирование томов по умолчанию,
# это определяется поиском ceph-fuse и mount.ceph
# mounter: kernel
reclaimPolicy: Delete
allowVolumeExpansion: true
mountOptions:
- debug
Remplissons-le ici ID de cluster et applicable dans Kubernetes :
kubectl apply -f storageclass.yaml
Проверка
Pour vérifier, comme dans l'exemple précédent, créons un PVC :
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: csi-cephfs-pvc
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 5Gi
storageClassName: csi-cephfs-sc
Et vérifiez la présence de PVC/PV :
kubectl get pvc
kubectl get pv
Si vous souhaitez consulter des fichiers et des répertoires dans CephFS, vous pouvez monter ce système de fichiers quelque part. Par exemple, comme indiqué ci-dessous.
Allons sur 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
Bien entendu, monter FS sur un nœud Ceph comme celui-ci ne convient qu'à des fins de formation, ce que nous faisons sur notre
Et enfin, vérifions comment les choses fonctionnent avec le redimensionnement des volumes dans le cas de CephFS. Revenons à Kubernetes et modifions notre manifeste pour PVC - augmentez-y la taille, par exemple, à 7Gi.
Appliquons le fichier édité :
kubectl apply -f pvc.yaml
Regardons le répertoire monté pour voir comment le quota a changé :
getfattr -n ceph.quota.max_bytes <каталог-с-данными>
Pour que cette commande fonctionne, vous devrez peut-être installer le package sur votre système attribut.
Les yeux ont peur, et les mains font
Tous ces sorts et ces longs manifestes YAML semblent compliqués en apparence, mais en pratique, les étudiants de Slurm les maîtrisent assez rapidement.
Dans cet article, nous ne sommes pas allés au fond de la jungle - il existe une documentation officielle à ce sujet. Si vous êtes intéressé par les détails de la configuration du stockage Ceph avec un cluster Kubernetes, ces liens vous aideront :
Sur le parcours Slurm
Et si vous êtes plus intéressé par le stockage de données, inscrivez-vous à
Auteur de l'article : Alexander Shvalov, ingénieur en exercice
Source: habr.com