Praktičen primer povezovanja pomnilnika, ki temelji na Cephu, z gručo Kubernetes

Container Storage Interface (CSI) je poenoten vmesnik med Kubernetesom in sistemi za shranjevanje. O tem smo že na kratko govorili povedal, danes pa si bomo podrobneje ogledali kombinacijo CSI in Ceph: pokazali bomo, kako povežite shrambo Ceph v gručo Kubernetes.
Članek ponuja resnične, čeprav nekoliko poenostavljene primere za lažje dojemanje. Ne upoštevamo namestitve in konfiguracije gruč Ceph in Kubernetes.

Se sprašujete, kako deluje?

Praktičen primer povezovanja pomnilnika, ki temelji na Cephu, z gručo Kubernetes

Torej imate na dosegu roke gručo Kubernetes, razporejeno npr. kubespray. V bližini deluje gruča Ceph - lahko jo tudi namestite, na primer s tem komplet iger. Upam, da ni treba omenjati, da mora za proizvodnjo med njima obstajati omrežje s pasovno širino vsaj 10 Gbit/s.

Če imate vse to, gremo!

Najprej pojdimo na eno od vozlišč gruče Ceph in preverimo, ali je vse v redu:

ceph health
ceph -s

Nato bomo takoj ustvarili bazen za diske RBD:

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

Preidimo na gručo Kubernetes. Tam bomo najprej namestili gonilnik Ceph CSI za RBD. Namestili bomo, kot je bilo pričakovano, prek Helma.
Dodamo repozitorij z grafikonom, dobimo nabor spremenljivk za grafikon ceph-csi-rbd:

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

Zdaj morate izpolniti datoteko cephrbd.yml. Če želite to narediti, poiščite ID gruče in naslove IP monitorjev v Cephu:

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

Dobljene vrednosti vnesemo v datoteko cephrbd.yml. Hkrati omogočamo izdelavo politik PSP (Pod Security Policies). Možnosti v razdelkih nodeplugin и ponudnik že v datoteki, jih je mogoče popraviti, kot je prikazano spodaj:

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

Nato nam preostane le še namestitev grafikona v gručo Kubernetes.

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

Super, gonilnik RBD deluje!
Ustvarimo nov StorageClass v Kubernetesu. To spet zahteva malo poigravanja s Cephom.

V Cephu ustvarimo novega uporabnika in mu podelimo pravice za pisanje v bazen Kocka:

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

Zdaj pa poglejmo, da je ključ za dostop še vedno tam:

ceph auth get-key client.rbdkube

Ukaz bo izpisal nekaj takega:

AQCO9NJbhYipKRAAMqZsnqqS/T8OYQX20xIa9A==

Dodajmo to vrednost Secret v gruči Kubernetes – kjer jo potrebujemo uporabniško geslo:

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

In ustvarjamo svojo skrivnost:

kubectl apply -f secret.yaml

Nato potrebujemo manifest StorageClass nekaj takega:

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

Treba ga je izpolniti clusterID, kar smo se naučili že z ekipo ceph fsidin uporabite ta manifest za gručo Kubernetes:

kubectl apply -f storageclass.yaml

Če želite preveriti, kako gruče delujejo skupaj, ustvarimo naslednji PVC (Persistent Volume Claim):

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

Takoj poglejmo, kako je Kubernetes ustvaril zahtevani nosilec v Cephu:

kubectl get pvc
kubectl get pv

Zdi se, da je vse super! Kako to izgleda na Cephovi strani?
Dobimo seznam nosilcev v bazenu in si ogledamo informacije o našem obsegu:

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

Zdaj pa poglejmo, kako deluje spreminjanje velikosti nosilca RBD.
Spremenite velikost nosilca v manifestu pvc.yaml na 2Gi in jo uporabite:

kubectl apply -f pvc.yaml

Počakajmo, da spremembe začnejo veljati, in ponovno poglejmo velikost glasnosti.

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

kubectl get pv
kubectl get pvc

Vidimo, da se velikost PVC-ja ni spremenila. Če želite izvedeti zakaj, lahko Kubernetes povprašate po YAML opisu PVC-ja:

kubectl get pvc rbd-pvc -o yaml

Tukaj je težava:

sporočilo: čakanje, da uporabnik (ponovno) zažene pod, da konča spreminjanje velikosti datotečnega sistema nosilca na vozlišču. vrsta: FileSystemResizePending

To pomeni, da je disk zrasel, datotečni sistem na njem pa ne.
Če želite povečati datotečni sistem, morate priklopiti nosilec. Pri nas se ustvarjeni PVC/PV trenutno ne uporablja na noben način.

Ustvarimo lahko testno enoto, na primer takole:

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

Zdaj pa poglejmo PVC:

kubectl get pvc

Velikost se je spremenila, vse je v redu.

V prvem delu smo delali z blokovno napravo RBD (okrajšava za Rados Block Device), vendar tega ni mogoče narediti, če morajo s tem diskom sočasno delati različne mikrostoritve. CephFS je veliko bolj primeren za delo z datotekami kot s slikami diskov.
Na primeru gruč Ceph in Kubernetes bomo konfigurirali CSI in druge potrebne entitete za delo s CephFS.

Vzemimo vrednosti iz novega grafikona Helm, ki ga potrebujemo:

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

Spet morate izpolniti datoteko cephfs.yml. Kot prej bodo ukazi Ceph pomagali:

ceph fsid
ceph mon dump

Izpolnite datoteko z vrednostmi, kot je ta:

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

Upoštevajte, da so naslovi monitorjev podani v preprosti obliki naslov:vrata. Za namestitev cephfs na vozlišče se ti naslovi prenesejo v modul jedra, ki še ne zna delati s protokolom monitorja v2.
Spremenimo vrata za httpMetrics (Prometheus bo šel tja za spremljanje metrik), tako da ni v nasprotju z nginx-proxy, ki ga namesti Kubespray. Tega morda ne boste potrebovali.

Namestite grafikon Helm v gručo Kubernetes:

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

Pojdimo v shrambo podatkov Ceph, da tam ustvarimo ločenega uporabnika. V dokumentaciji je navedeno, da ponudnik CephFS zahteva pravice skrbniškega dostopa do gruče. Vendar bomo ustvarili ločenega uporabnika fs z omejenimi pravicami:

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'

In takoj poglejmo njegov dostopni ključ, potrebovali ga bomo kasneje:

ceph auth get-key client.fs

Ustvarimo ločena Secret in StorageClass.
Nič novega, to smo že videli na primeru RBD:

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

Uporaba manifesta:

kubectl apply -f secret.yaml

In zdaj - ločen StorageClass:

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

Izpolnimo ga tukaj clusterID in velja v Kubernetesu:

kubectl apply -f storageclass.yaml

Проверка

Za preverjanje, kot v prejšnjem primeru, ustvarimo PVC:

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

In preverite prisotnost PVC/PV:

kubectl get pvc
kubectl get pv

Če si želite ogledati datoteke in imenike v CephFS, lahko ta datotečni sistem nekam namestite. Na primer, kot je prikazano spodaj.

Pojdimo na eno od vozlišč gruče Ceph in izvedite naslednja dejanja:

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

Seveda je namestitev FS na vozlišče Ceph, kot je ta, primerna le za namene usposabljanja, kar počnemo na našem Slurm tečaji. Mislim, da tega nihče ne bi naredil v proizvodnji; obstaja veliko tveganje, da bi pomotoma izbrisali pomembne datoteke.

In končno, preverimo, kako stvari delujejo s spreminjanjem velikosti nosilcev v primeru CephFS. Vrnimo se v Kubernetes in uredimo naš manifest za PVC - tam povečajmo velikost na primer na 7Gi.

Uporabimo urejeno datoteko:

kubectl apply -f pvc.yaml

Poglejmo nameščeni imenik, da vidimo, kako se je spremenila kvota:

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

Da bo ta ukaz deloval, boste morda morali namestiti paket v svoj sistem attr.

Oči se bojijo, roke pa

Vse te čarovnije in dolgi manifesti YAML se na videz zdijo zapleteni, toda v praksi se jih učenci Slurma precej hitro naučijo.
V tem članku nismo šli globoko v džunglo - za to obstaja uradna dokumentacija. Če vas zanimajo podrobnosti o nastavitvi shrambe Ceph z gručo Kubernetes, vam bodo te povezave v pomoč:

Splošna načela Kubernetesa pri delu z nosilci
Dokumentacija RBD
Integracija RBD in Kubernetes z vidika Ceph
Integracija RBD in Kubernetes z vidika CSI
Splošna dokumentacija CephFS
Integracija CephFS in Kubernetes z vidika CSI

Na tečaju Slurm Baza Kubernetes lahko greste malo dlje in v Kubernetes namestite pravo aplikacijo, ki bo uporabljala CephFS kot shrambo datotek. Z zahtevami GET/POST boste lahko prenašali datoteke in jih prejemali od Ceph.

In če vas bolj zanima shranjevanje podatkov, se prijavite za nov tečaj o Cephu. Medtem ko je beta test v teku, je tečaj na voljo s popustom in lahko vplivate na njegovo vsebino.

Avtor članka: Alexander Shvalov, inženir Southbridge, certificirani skrbnik Kubernetes, avtor in razvijalec tečajev Slurm.

Vir: www.habr.com