Praktický příklad připojení úložiště založeného na Cephu ke clusteru Kubernetes

Container Storage Interface (CSI) je jednotné rozhraní mezi Kubernetes a úložnými systémy. Krátce o něm už jsme řekla, a dnes se blíže podíváme na kombinaci CSI a Ceph: ukážeme si jak mount úložiště Ceph do clusteru Kubernetes.
Článek obsahuje reálné, i když pro snadnější vnímání mírně zjednodušené příklady. Neuvažujeme o instalaci a konfiguraci clusterů Ceph a Kubernetes.

Zajímá vás, jak to funguje?

Praktický příklad připojení úložiště založeného na Cephu ke clusteru Kubernetes

Máte tedy po ruce cluster Kubernetes, nasazený např. kubespray. Nedaleko funguje cluster Ceph - můžete ho dát například i tímto sada herních knih. Snad nemusím zmiňovat, že pro výrobu mezi nimi musí být síť s šířkou pásma alespoň 10 Gb/s.

Pokud tohle všechno máte, pojďme!

Nejprve pojďme do jednoho z uzlů clusteru Ceph a zkontrolujeme, zda je vše v pořádku:

ceph health
ceph -s

Dále okamžitě vytvoříme fond pro disky RBD:

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

Pojďme ke clusteru Kubernetes. Tam nejprve nainstalujeme ovladač Ceph CSI pro RBD. Nainstalujeme podle očekávání přes Helm.
Přidejte úložiště s grafem a získejte sadu proměnných grafu ceph-csi-rbd:

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

Nyní je potřeba vyplnit soubor cephrbd.yml. K tomu zjistíme ID clusteru a IP adresy monitorů v Ceph:

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

Výsledné hodnoty se zadají do souboru cephrbd.yml. Zároveň umožňujeme vytváření zásad PSP (Pod Security Policies). Možnosti sekce plugin uzlu и proviant již v souboru, lze je opravit, jak je uvedeno níže:

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

Pak už nám zbývá jen nainstalovat graf do clusteru Kubernetes.

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

Skvělé, ovladač RBD funguje!
Pojďme vytvořit novou StorageClass v Kubernetes. To opět vyžaduje nějakou práci s Cephem.

Vytvořte nového uživatele v Ceph a dejte mu oprávnění zapisovat do fondu kostka:

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

A nyní se podívejme, že přístupový klíč stále existuje:

ceph auth get-key client.rbdkube

Příkaz vypíše něco takového:

AQCO9NJbhYipKRAAMqZsnqqS/T8OYQX20xIa9A==

Tuto hodnotu dáme do Secret v clusteru Kubernetes – tam, kde ji potřebujeme uživatelský klíč:

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

A vytváříme naše tajemství:

kubectl apply -f secret.yaml

Dále potřebujeme něco jako tento manifest StorageClass:

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

Potřeba vyplnit clusterID, což jsme se již od týmu dozvěděli ceph fsida použijte tento manifest na cluster Kubernetes:

kubectl apply -f storageclass.yaml

Chcete-li zkontrolovat fungování clusterů ve svazku, vytvořte následující PVC (Persistent Volume Claim):

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

Okamžitě se podívejme, jak Kubernetes vytvořil požadovaný svazek v Ceph:

kubectl get pvc
kubectl get pv

Všechno se zdá být skvělé! A jak to vypadá na straně Ceph?
Získáme seznam svazků ve fondu a zobrazíme informace o našem objemu:

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

Nyní se podívejme, jak funguje změna velikosti svazku RBD.
Změňte velikost svazku v manifestu pvc.yaml na 2Gi a použijte jej:

kubectl apply -f pvc.yaml

Počkáme, až se změny projeví, a podívejme se ještě jednou na velikost svazku.

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

kubectl get pv
kubectl get pvc

Vidíme, že velikost PVC se nezměnila. Můžete požádat Kubernetes o popis PVC ve formátu YAML, abyste zjistili proč:

kubectl get pvc rbd-pvc -o yaml

A tady je problém:

zpráva: Čeká se, až uživatel (re-)spustí modul, aby dokončil změnu velikosti svazku v systému souborů na uzlu. typ: FileSystemResizePending

To znamená, že disk narostl, ale systém souborů na něm ne.
Chcete-li rozšířit systém souborů, musíte připojit svazek. V našem případě se vytvořené PVC / PV nyní nijak nevyužívá.

Můžeme vytvořit testovací modul takto:

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

A nyní se podívejme na PVC:

kubectl get pvc

Velikost se změnila, vše v pořádku.

V první části jsme pracovali s blokovým zařízením RBD (je to zkratka pro Rados Block Device), ale to nelze udělat, pokud chcete pracovat s tímto diskem různých mikroslužeb současně. Pro práci se soubory, spíše než s obrazem disku, se mnohem lépe hodí CephFS.
Na příkladu clusterů Ceph a Kubernetes nakonfigurujeme CSI a další potřebné entity pro práci s CephFS.

Pojďme získat hodnoty z nového grafu Helm, které potřebujeme:

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

Opět je potřeba vyplnit soubor cephfs.yml. Stejně jako dříve pomohou příkazy Ceph:

ceph fsid
ceph mon dump

Soubor naplníme hodnotami, jako je tento:

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

Všimněte si, že adresy monitorů se zadávají v jednoduchém tvaru adresa:port. Pro připojení cephfs na hostitele jsou tyto adresy předány modulu jádra, který ještě neví, jak pracovat s protokolem monitor v2.
Změníme port pro httpMetrics (prometheus tam půjde pro sledování metrik), aby nebyl v konfliktu s nginx-proxy, který instaluje Kubespray. Možná to nebudete potřebovat.

Nainstalujte graf Helm v clusteru Kubernetes:

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

Přesuňme se do úložiště dat Ceph, abychom tam vytvořili samostatného uživatele. V dokumentaci je uvedeno, že poskytovatel CephFS potřebuje přístupová práva správce clusteru. My ale vytvoříme samostatného uživatele fs s omezenými právy:

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'

A hned se podíváme na jeho přístupový klíč, bude se nám dále hodit:

ceph auth get-key client.fs

Vytvořme samostatné Secret a StorageClass.
Nic nového, už jsme to viděli na příkladu RBD:

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

Použití manifestu:

kubectl apply -f secret.yaml

A nyní - samostatná 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

Vyplňte zde clusterID a použitelné v Kubernetes:

kubectl apply -f storageclass.yaml

Проверка

Pro kontrolu, jako v předchozím příkladu, vytvořte PVC:

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

A zkontrolujte PVC/PV:

kubectl get pvc
kubectl get pv

Pokud se chcete podívat na soubory a adresáře v CephFS, můžete tento souborový systém někam připojit. Například, jak je uvedeno níže.

Jdeme do jednoho z uzlů clusteru Ceph a provedeme následující akce:

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

Samozřejmě, že taková montáž FS na uzel Ceph je vhodná pouze pro účely učení, což děláme na našich Slurm kurzy. Nemyslím si, že by to někdo dělal ve výrobě, je tam velké riziko nechtěného přepsání důležitých souborů.

A nakonec se podívejme, jak to funguje se změnou velikosti svazku v případě CephFS. Vrátíme se do Kubernetes a upravíme náš manifest pro PVC – zvětšíme tam velikost například na 7Gi.

Použijte upravený soubor:

kubectl apply -f pvc.yaml

Podívejme se, jak se změnila kvóta v připojeném adresáři:

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

Aby tento příkaz fungoval, možná budete muset balíček nainstalovat attr.

Oči se bojí a ruce dělají

Na první pohled se všechna tato kouzla a dlouhé YAML manifesty zdají komplikované, ale v praxi se s nimi studenti Slurm vypořádají docela rychle.
V tomto článku jsme se neponořili do divočiny - existuje k tomu oficiální dokumentace. Pokud vás zajímají podrobnosti o nastavení úložiště Ceph s clusterem Kubernetes, pomohou vám tyto odkazy:

Obecné principy Kubernetes se svazky
Dokumentace RBD
Integrace RBD a Kubernetes z pohledu Ceph
Integrace RBD a Kubernetes z pohledu CSI
Obecná dokumentace CephFS
Integrace CephFS a Kubernetes z pohledu CSI

Samozřejmě Slurm Základna Kubernetes můžete jít o krok dále a nasadit skutečnou aplikaci v Kubernetes, která bude používat CephFS jako úložiště pro soubory. Prostřednictvím požadavků GET/POST budete moci přenášet soubory a přijímat je od Ceph.

A pokud vás více zajímá úložiště dat, pak se přihlaste nový kurz Ceph. Zatímco běží beta test, můžete kurz získat se slevou a ovlivnit jeho obsah.

Autor článku: Alexander Shvalov, praktický inženýr Southbridge, certifikovaný správce Kubernetes, autor a vývojář kurzů Slurm.

Zdroj: www.habr.com