Un exemple pràctic de connexió d'emmagatzematge basat en Ceph a un clúster de Kubernetes

Container Storage Interface (CSI) és una interfície unificada entre Kubernetes i els sistemes d'emmagatzematge. Ja n'hem parlat breument va dir, i avui veurem més de prop la combinació de CSI i Ceph: mostrarem com connecteu l'emmagatzematge Ceph al clúster de Kubernetes.
L'article proporciona exemples reals, encara que lleugerament simplificats, per facilitar la percepció. No considerem instal·lar i configurar clústers Ceph i Kubernetes.

Et preguntes com funciona?

Un exemple pràctic de connexió d'emmagatzematge basat en Ceph a un clúster de Kubernetes

Per tant, teniu un clúster de Kubernetes al vostre abast, desplegat, per exemple, kubespray. Hi ha un clúster Ceph funcionant a prop; també el podeu instal·lar, per exemple, amb això un conjunt de llibres de joc. Espero que no cal esmentar que per a la producció entre ells hi ha d'haver una xarxa amb una amplada de banda d'almenys 10 Gbit/s.

Si tens tot això, anem!

Primer, anem a un dels nodes del clúster Ceph i comproveu que tot estigui en ordre:

ceph health
ceph -s

A continuació, crearem immediatament una agrupació per a discs RBD:

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

Passem al clúster de Kubernetes. Allà, primer de tot, instal·larem el controlador Ceph CSI per a RBD. Instal·larem, com s'esperava, a través de Helm.
Afegim un repositori amb un gràfic, obtenim un conjunt de variables per al gràfic ceph-csi-rbd:

helm repo add ceph-csi https://ceph.github.io/csi-charts
helm inspect values ceph-csi/ceph-csi-rbd > cephrbd.yml

Ara heu d'omplir el fitxer cephrbd.yml. Per fer-ho, esbrineu l'ID del clúster i les adreces IP dels monitors a Ceph:

ceph fsid  # так мы узнаем clusterID
ceph mon dump  # а так увидим IP-адреса мониторов

Introduïm els valors obtinguts al fitxer cephrbd.yml. Al mateix temps, habilitem la creació de polítiques de PSP (Pod Security Policies). Opcions en seccions nodeplugin и subministrador ja al fitxer, es poden corregir tal com es mostra a continuació:

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

A continuació, només ens queda instal·lar el gràfic al clúster Kubernetes.

helm upgrade -i ceph-csi-rbd ceph-csi/ceph-csi-rbd -f cephrbd.yml -n ceph-csi-rbd --create-namespace

Genial, el controlador RBD funciona!
Creem una nova StorageClass a Kubernetes. Això de nou requereix una mica de retoc amb Ceph.

Creem un nou usuari a Ceph i li donem drets per escriure al grup cub:

ceph auth get-or-create client.rbdkube mon 'profile rbd' osd 'profile rbd pool=kube'

Ara vegem que la clau d'accés encara hi és:

ceph auth get-key client.rbdkube

L'ordre sortirà alguna cosa com això:

AQCO9NJbhYipKRAAMqZsnqqS/T8OYQX20xIa9A==

Afegim aquest valor a Secret al clúster de Kubernetes, on el necessitem clau d'usuari:

---
apiVersion: v1
kind: Secret
metadata:
  name: csi-rbd-secret
  namespace: ceph-csi-rbd
stringData:
  # Значения ключей соответствуют имени пользователя и его ключу, как указано в
  # кластере Ceph. ID юзера должен иметь доступ к пулу,
  # указанному в storage class
  userID: rbdkube
  userKey: <user-key>

I creem el nostre secret:

kubectl apply -f secret.yaml

A continuació, necessitem un manifest StorageClass com això:

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

S'ha d'omplir clusterID, que ja hem après per l'equip ceph fsid, i apliqueu aquest manifest al clúster de Kubernetes:

kubectl apply -f storageclass.yaml

Per comprovar com funcionen els clústers junts, creem el següent PVC (reclamació de volum persistent):

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: rbd-pvc
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
  storageClassName: csi-rbd-sc

Vegem immediatament com Kubernetes va crear el volum sol·licitat a Ceph:

kubectl get pvc
kubectl get pv

Tot sembla genial! Què sembla això al costat de Ceph?
Obtenim una llista de volums a la piscina i visualitzem informació sobre el nostre volum:

rbd ls -p kube
rbd -p kube info csi-vol-eb3d257d-8c6c-11ea-bff5-6235e7640653  # тут, конечно же, будет другой ID тома, который выдала предыдущая команда

Ara vegem com funciona el canvi de mida d'un volum RBD.
Canvieu la mida del volum al manifest pvc.yaml a 2Gi i apliqueu-lo:

kubectl apply -f pvc.yaml

Esperem que els canvis tinguin efecte i tornem a veure la mida del volum.

rbd -p kube info csi-vol-eb3d257d-8c6c-11ea-bff5-6235e7640653

kubectl get pv
kubectl get pvc

Veiem que la mida del PVC no ha canviat. Per esbrinar per què, podeu consultar a Kubernetes una descripció YAML del PVC:

kubectl get pvc rbd-pvc -o yaml

Aquest és el problema:

missatge: S'està esperant que l'usuari (re)iniciï un pod per acabar de canviar la mida del sistema de fitxers del volum al node. tipus: FileSystemResizePending

És a dir, el disc ha crescut, però el sistema de fitxers que hi ha no.
Per fer créixer el sistema de fitxers, cal muntar el volum. Al nostre país, el PVC/PV creat actualment no s'utilitza de cap manera.

Podem crear un pod de prova, per exemple com aquest:

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

I ara mirem el PVC:

kubectl get pvc

La mida ha canviat, tot està bé.

A la primera part, vam treballar amb el dispositiu de blocs RBD (significa Rados Block Device), però això no es pot fer si cal que diferents microserveis funcionin amb aquest disc simultàniament. CephFS és molt més adequat per treballar amb fitxers que no pas amb imatges de disc.
Utilitzant l'exemple dels clústers Ceph i Kubernetes, configurarem CSI i altres entitats necessàries per treballar amb CephFS.

Obtenim els valors del nou gràfic Helm que necessitem:

helm inspect values ceph-csi/ceph-csi-cephfs > cephfs.yml

De nou, heu d'omplir el fitxer cephfs.yml. Com abans, les ordres Ceph ajudaran:

ceph fsid
ceph mon dump

Ompliu el fitxer amb valors com aquest:

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

Tingueu en compte que les adreces del monitor s'especifiquen al formulari simple adreça:port. Per muntar cephfs en un node, aquestes adreces es passen al mòdul del nucli, que encara no sap com treballar amb el protocol de monitor v2.
Canviem el port per a httpMetrics (Prometheus hi anirà per controlar les mètriques) perquè no entri en conflicte amb nginx-proxy, que està instal·lat per Kubespray. Potser no ho necessiteu.

Instal·leu el gràfic Helm al clúster de Kubernetes:

helm upgrade -i ceph-csi-cephfs ceph-csi/ceph-csi-cephfs -f cephfs.yml -n ceph-csi-cephfs --create-namespace

Anem al magatzem de dades Ceph per crear-hi un usuari independent. La documentació indica que el subministrador de CephFS requereix drets d'accés d'administrador del clúster. Però crearem un usuari separat fs amb drets limitats:

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'

I mirem immediatament la seva clau d'accés, la necessitarem més endavant:

ceph auth get-key client.fs

Creem Secret i StorageClass separats.
Res de nou, això ja ho hem vist en l'exemple de RBD:

---
apiVersion: v1
kind: Secret
metadata:
  name: csi-cephfs-secret
  namespace: ceph-csi-cephfs
stringData:
  # Необходимо для динамически создаваемых томов
  adminID: fs
  adminKey: <вывод предыдущей команды>

Aplicació del manifest:

kubectl apply -f secret.yaml

I ara, una StorageClass independent:

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

Omplim-lo aquí clusterID i aplicable a Kubernetes:

kubectl apply -f storageclass.yaml

inspecció

Per comprovar, com en l'exemple anterior, creem un PVC:

---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: csi-cephfs-pvc
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 5Gi
  storageClassName: csi-cephfs-sc

I comproveu la presència de PVC/PV:

kubectl get pvc
kubectl get pv

Si voleu mirar fitxers i directoris a CephFS, podeu muntar aquest sistema de fitxers en algun lloc. Per exemple, com es mostra a continuació.

Anem a un dels nodes del clúster Ceph i realitzem les accions següents:

# Точка монтирования
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

Per descomptat, muntar FS en un node Ceph com aquest només és adequat per a finalitats d'entrenament, que és el que fem al nostre Cursos de slurm. No crec que ningú ho faci en producció, hi ha un alt risc d'esborrar accidentalment fitxers importants.

I, finalment, comprovem com funcionen les coses amb el canvi de mida dels volums en el cas de CephFS. Tornem a Kubernetes i editem el nostre manifest per a PVC; augmenteu-ne la mida, per exemple, a 7Gi.

Apliquem el fitxer editat:

kubectl apply -f pvc.yaml

Mirem el directori muntat per veure com ha canviat la quota:

getfattr -n ceph.quota.max_bytes <каталог-с-данными>

Perquè aquesta ordre funcioni, potser haureu d'instal·lar el paquet al vostre sistema attr.

Els ulls tenen por, però les mans sí

Tots aquests encanteris i llargs manifestos de YAML semblen complicats a la superfície, però a la pràctica, els estudiants de Slurm s'enfronten amb força rapidesa.
En aquest article no ens vam endinsar a la selva: hi ha documentació oficial per a això. Si esteu interessats en els detalls de la configuració de l'emmagatzematge Ceph amb un clúster Kubernetes, aquests enllaços us ajudaran:

Principis generals del treball de Kubernetes amb volums
Documentació RBD
Integrant RBD i Kubernetes des d'una perspectiva Ceph
Integrant RBD i Kubernetes des d'una perspectiva CSI
Documentació general de CephFS
Integració de CephFS i Kubernetes des d'una perspectiva CSI

En el curs de Slurm Base Kubernetes podeu anar una mica més enllà i desplegar una aplicació real a Kubernetes que utilitzarà CephFS com a emmagatzematge de fitxers. Mitjançant les sol·licituds GET/POST podreu transferir fitxers i rebre'ls de Ceph.

I si esteu més interessats en l'emmagatzematge de dades, registreu-vos-hi nou curs sobre Ceph. Mentre la prova beta està en curs, el curs es pot obtenir amb un descompte i podeu influir en el seu contingut.

Autor de l'article: Alexander Shvalov, enginyer en exercici Southbridge, Administrador certificat Kubernetes, autor i desenvolupador de cursos Slurm.

Font: www.habr.com