Shembulli praktik i lidhjes së ruajtjes së bazuar në Ceph në klasterin Kubernetes.

Container Storage Interface (CSI) është një ndërfaqe e unifikuar e bashkëveprimit midis Kubernetes dhe sistemeve të ruajtjes së të dhënave. Në shkurt, për të njohur atë, ne tashmë treguam, dhe sot do të shqyrtojmë më në detaje lidhjen CSI dhe Ceph: do të tregojmë se si të lidhim ruajtjen Ceph me klasterin Kubernetes.
Në këtë artikull do të sjellim shembuj realë, ndonëse pak të thjeshtuar për të lehtësuar kuptimin. Instalimi dhe konfigurimi i klasterëve Ceph dhe Kubernetes nuk do të shqyrtohen.

A jeni të interesuar për mënyrën se si funksionon kjo?

Shembulli praktik i lidhjes së ruajtjes së bazuar në Ceph në klasterin Kubernetes.

Kështu, keni në duar një klaster Kubernetes, i shpërndarë, për shembull, kubespray. Pranë tij funksionon një klaster Ceph — gjithashtu mund ta instaloni, për shembull, me këtë grup playbook-ësh. Shpresoj se nuk është e nevojshme të përmend se për prodhim, mes tyre duhet të ketë një rrjet me kapacitet minimal prej 10 Gbit/s.

Nëse gjithçka kjo e keni, le të fillojmë!

Së pari, hyjmë në një nga nodet e klasterit Ceph dhe kontrollojmë që gjithçka është në rregull:

ceph health
ceph -s

Më tej, menjëherë krijojmë një pool për disqet RBD:

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

Tani kalojmë në klasterin Kubernetes. Atje së pari do të instalojmë Ceph CSI driver për RBD. Do ta instalojmë, siç duhet, përmes Helm.
Shtojmë repository-n me chartin, dhe marrim setin e variablave të chartit ceph-csi-rbd:

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

Tani duhet të plotësojmë skedarin cephrbd.yml. Për këtë, mësojmë ID-në e klasterit dhe adresat IP të monitorëve në Ceph:

ceph fsid  # kështu do të mësojmë clusterID
ceph mon dump  # dhe kështu do të shohim adresat IP të monitorëve

Vlerat e marra i vendosim në skedarin cephrbd.yml. Ndërkohë, aktivizojmë krijimin e politikave PSP (Pod Security Policies). Opsionet në seksionet nodeplugin и provisioner s janë gjithashtu në skedar, mund t'i rregullojmë siç është treguar më poshtë:

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

Më pas, gjithçka që na mbetet është të instalojmë chartin në klasterin Kubernetes.

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

Shkëlqyer, RBD driver funksionon!
Të krijojmë një StorageClass të re në Kubernetes. Për këtë, do të kërkohet pak punë sërish me Ceph.

Krijojmë një përdorues të ri në Ceph dhe i japim të drejtat për të shkruar në pool-in kube:

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

Tani le të shohim çelësin e qasjes gjithë atje:

ceph auth get-key client.rbdkube

Komanda do të japë diçka të tillë:

AQCO9NJbhYipKRAAMqZsnqqS/T8OYQX20xIa9A==

Ta vendosim këtë vlerë në Secret në klasterin Kubernetes — aty ku është e nevojshme userKey:

---
apiVersion: v1
kind: Secret
metadata:
  name: csi-rbd-secret
  namespace: ceph-csi-rbd
stringData:
  # Vlerat e çelësve i përgjigjen emrit të përdoruesit dhe çelësit të tij, siç është e specifikuar në
  # clusterin Ceph. ID e përdoruesit duhet të ketë qasje në pool-in,
  # të caktuar në storage class
  userID: rbdkube
  userKey:

Dhe krijojmë sekretin tonë:

kubectl apply -f secret.yaml

Më pas na nevojitet një manifest StorageClass si ky:

---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
   name: csi-rbd-sc
provisioner: rbd.csi.ceph.com
parameters:
   clusterID: 
   pool: kube

   imageFeatures: layering

   # Këto sekrete duhet të përmbajnë të dhëna për autorizim
   # në pool-in tuaj.
   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

Duhet të plotësohet clusterID, të cilin ne tashmë e kemi mësuar me komandën ceph fsid, dhe të aplikojmë këtë manifest në klasterin Kubernetes:

kubectl apply -f storageclass.yaml

Për të kontrolluar funksionimin e klastereve në lidhje, le të krijojmë një PVC të tillë (Përdorimi i Volume të Përsëritshëm):

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

Të shohim se si Kubernetes ka krijuar volumet e kërkuara në Ceph:

kubectl get pvc
kubectl get pv

Duket se gjithçka është në rregull! Si duket kjo në ceph?
Marrim një listë volumesh në pool dhe shikojmë informacionin mbi volumin tonë:

rbd ls -p kube
rbd -p kube info csi-vol-eb3d257d-8c6c-11ea-bff5-6235e7640653  # këtu, sigurisht, do të jetë një ID tjetër volumi, i cili u dha nga komanda e mëparshme

Tani le të shohim se si funksionon ndryshimi i madhësisë së volumin RBD.
Ndryshojmë madhësinë e volumin në manifestin pvc.yaml në 2Gi dhe e aplikojmë:

kubectl apply -f pvc.yaml

Të presim derisa ndryshimet të hyjnë në fuqi dhe të shohim përsëri madhësinë e volumin.

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

kubectl get pv
kubectl get pvc

Shohim se madhësia e PVC nuk është ndryshuar. Për të mësuar arsyen, mund të kërkojmë për Kubernetes për të përshkruar PVC në formatin YAML:

kubectl get pvc rbd-pvc -o yaml

Ja dhe problemi:

message: Duke pritur që përdoruesi të (ri)fillojë një pod për të përfunduar zmadhen e sistemit të skedarëve të volumit në nod.

Kështu që disku është zgjeruar, por sistemi i skedarëve mbi të — jo.
Për të zgjeruar sistemin e skedarëve, duhet të montoni volumin. Ne kemi krijuar PVC/PV që tani nuk përdoret në asnjë mënyrë.

Mund të krijojmë një pod testues, për shembull kështu:

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

Tani tani të shohim PVC-në:

kubectl get pvc

Madhësia u ndryshua, gjithçka është në rregull.

Në pjesën e parë punuam me pajisjen bllok RBD (e cila do të thotë Rados Block Device), por kjo nuk është e mundur nëse nevojitet që disa mikro-shërbime të punojnë njëkohësisht me këtë disk. Për punë me skedarë, në vend të imazhit të disku, CephFS është opsioni më i mirë.
Do të konfiguroni CSI-në dhe entitetet e tjera të nevojshme për punë me CephFS në shembujt e klastereve Ceph dhe Kubernetes.

Të marrim vlerat nga Helm chart-i që na nevojitet:

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

Sërish është e nevojshme të plotësoni skedarin cephfs.yml. Si më parë, komandat Ceph do ju ndihmojnë:

ceph fsid
ceph mon dump

Plotësojmë skedarin me vlera në këtë mënyrë:

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

Vini re se adresat e monitorëve jepen në formën e thjeshtë address:port. Për montimin e cephfs në nyjë, këto adresa i kalohen modulit të bërthamës, i cili ende nuk është në gjendje të punojë me protokollin e monitorëve v2.
Ne ndryshojmë portin për httpMetrics (ku Prometheus do shkojë për metrikat e monitorimit) për të shmangur konfliktin me nginx-proxy, që instalohet nga Kubespray. Mund të mos e keni nevojshëm këtë.

Instalojmë Helm chart-in në klasterin Kubernetes:

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

Shkoni te ndarja e të dhënave Ceph për të krijuar një përdorues të veçantë atje. Në dokumentacion thuhet se provizioneri CephFS ka nevojë për të drejtat e administrators të klasterit. Por ne do të krijojmë një përdorues të veçantë fs me të drejta të kufizuara:

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'

Dhe menjëherë do të shikojmë çelësin e tij të aksesit, i cili do të na nevojitet më vonë:

ceph auth get-key client.fs

Të krijojmë një Secret dhe StorageClass të veçantë.
Nuk është ndonjë gjë e re, ne e kemi parë këtë në shembujt e RBD:

---
apiVersion: v1
kind: Secret
metadata:
  name: csi-cephfs-secret
  namespace: ceph-csi-cephfs
stringData:
  # E nevojshme për volumin e krijuar dinamikisht
  adminID: fs
  adminKey:

Aplikoni manifestin:

kubectl apply -f secret.yaml

Dhe tani - një StorageClass të veçantë:

---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: csi-cephfs-sc
provisioner: cephfs.csi.ceph.com
parameters:
  clusterID: 

  # Emri i sistemit të skedarëve CephFS, në të cilin do të krijohet volumi
  fsName: cephfs

  # (opsionale) Puli Ceph, në të cilin do të ruhen të dhënat e volumit
  # pool: cephfs_data

  # (opsionale) Opsionet e montimit për Ceph-fuse të ndara me presje
  # p.sh:
  # fuseMountOptions: debug

  # (opsionale) Opsionet e montimit CephFS për bërthamën të ndara me presje
  # Shihni man mount.ceph për një listë të këtyre opsioneve. P.sh:
  # kernelMountOptions: readdir_max_bytes=1048576,norbytes

  # Sekretet duhet të përmbajnë qasje për adminin dhe/ose përdoruesin 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

  # (opsionale) Drejtori mund të përdorë ose ceph-fuse (fuse), 
  # ose ceph kernelclient (kernel).
  # Nëse nuk përcaktohet, do të përdoret montimi i volumit të paracaktuar,
  # kjo përcaktohet duke kërkuar ceph-fuse dhe mount.ceph
  # mounter: kernel
reclaimPolicy: Delete
allowVolumeExpansion: true
mountOptions:
  - debug

Do ta plotësojmë këtu clusterID dhe do ta aplikojmë në Kubernetes:

kubectl apply -f storageclass.yaml

Kontrolli

Për kontroll, si në shembullin e kaluar, do të krijojmë një PVC:

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

Dhe do të kontrollojmë praninë e PVC/PV:

kubectl get pvc
kubectl get pv

Nëse dëshiron të shohësh skedarët dhe katalogët në CephFS, mund ta montosh këtë sistem skedarësh diku. Për shembull, siç tregohet më poshtë.

Do të shkojmë në një nga nodet e klasterit Ceph dhe do të kryejmë këto veprime:

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

Sigurisht, një montim i tillë FS në nodën Ceph është i përshtatshëm vetëm për qëllime mësimore, të cilat po i ndjekim në kursin tonë Slerm. Nuk mendoj se dikush do ta bënte këtë në prodhim, ka rrezik të madh për të fshirë rastësisht skedarë të rëndësishëm.

Dhe përfundimisht, le të kontrollojmë se si qëndron situata me ndryshimin e madhësisë së volumit në rastin e CephFS. Kthehemi në Kubernetes dhe redaktojmë manifestin tonë për PVC - do ta rrisim atje madhësinë, për shembull, në 7Gi.

Do ta aplikojmë skedarin e redaktuar:

kubectl apply -f pvc.yaml

Do të shohim në katalogun e montuar, si ka ndryshuar kuota:

getfattr -n ceph.quota.max_bytes

Për të funksionuar këtë komandë, ndoshta do t'ju duhet të instaloni në sistem paketën attr.

Syri friksohet, por duart punojnë

Me ndoshta gjithçka këto magji dhe manifestet e gjata YAML duken të komplikuara, por në praktikë studentët e Slyrm i kuptojnë ato mjaft shpejt.
Në këtë artikull ne nuk shkuam në thellësi — për këtë ka dokumentacionin zyrtar. Nëse jeni të interesuar për detajet e konfigurimit të ruajtjes Ceph së bashku me klasterin Kubernetes, këto lidhje do t'ju ndihmojnë:

Principet e përgjithshme të funksionimit të Kubernetes me volume
Dokumentacioni mbi RBD
Integrimi i RBD dhe Kubernetes nga këndvështrimi i Ceph
Integrimi i RBD dhe Kubernetes nga këndvështrimi i CSI
Dokumentacioni i përgjithshëm mbi CephFS
Integrimi i CephFS dhe Kubernetes nga këndvështrimi i CSI

Në kursin Slyrm Kubernetes Baza mund të shkoni edhe më tej dhe të zhvilloni në Kubernetes një aplikacion real që do të përdorë CephFS si një ruajtës për skedarët. Nëpërmjet kërkesave GET/POST mund të dërgoni skedarë dhe t'i merrni ato nga Ceph.

Dhe nëse jeni më të interesuar për ruajtjen e të dhënave, atëherë regjistrohuni për kursin e ri mbi Ceph. Ndërsa po zhvillohet testi beta, kursi mund të merret me zbritje dhe të ndikoni në përmbajtjen e tij.

Autori i artikullit: Aleksandër Shvalov, inxhinier praktikues Southbridge, Administrator i Certifikuar Kubernetes, autor dhe zhvillues kursesh Slyrm.

Burimi: habr.com

Купить надежный хостинг для сайтов с защитой от DDoS, VPS VDS серверы 🔥 Купить надежный хостинг для сайтов с защитой от DDoS, VPS VDS серверы | ProHoster