Container Storage Interface (CSI) este o interfață unificată de interacțiune între Kubernetes și sistemele de stocare de date. Am discutat pe scurt despre ea anterior, , iar astăzi ne vom concentra mai în detaliu asupra legăturii dintre CSI și Ceph: vom arăta cum la clusterul Kubernetes.
Articolul oferă exemple reale, deși puțin simplificate pentru a fi mai ușor de înțeles. Nu vom discuta despre instalarea și configurarea clusterelor Ceph și Kubernetes.
Ești interesat să afli cum funcționează?

Deci, ai un cluster Kubernetes la dispoziție, de exemplu, . Alături, există un cluster Ceph — acesta poate fi de asemenea instalat, de exemplu, folosind acest . Sper că nu e nevoie să menționez că pentru producție ar trebui să existe o rețea între ele cu o lățime de bandă de cel puțin 10 Gbit/s.
Dacă toate acestea le ai, să începem!
Mai întâi, să accesăm unul dintre nodurile clusterului Ceph și să verificăm că totul este în ordine:
ceph health
ceph -sApoi, vom crea un pool pentru discurile RBD:
ceph osd pool create kube 32
ceph osd pool application enable kube rbdTrecem la clusterul Kubernetes. Acolo, primul pas este să instalăm driverul Ceph CSI pentru RBD. Îl vom instala, așa cum trebuie, prin Helm.
Adăugăm repository-ul cu chart-ul, obținem setul de variabile pentru chart-ul ceph-csi-rbd:
helm repo add ceph-csi https://ceph.github.io/csi-charts
helm inspect values ceph-csi/ceph-csi-rbd > cephrbd.ymlAcum trebuie să completăm fișierul cephrbd.yml. Pentru aceasta, vom afla ID-ul clusterului și adresele IP ale monitorilor din Ceph:
ceph fsid # astfel aflăm clusterID
ceph mon dump # iar așa vom obține adresele IP ale monitorilorValorile obținute se vor introduce în fișierul cephrbd.yml. Între timp, activăm crearea politicilor PSP (Pod Security Policies). Opțiunile din secțiunile nodeplugin și provisioner sunt deja în fișier, le putem modifica așa cum este arătat mai jos:
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: trueApoi, tot ce ne rămâne de făcut este să instalăm chart-ul în clusterul Kubernetes.
helm upgrade -i ceph-csi-rbd ceph-csi/ceph-csi-rbd -f cephrbd.yml -n ceph-csi-rbd --create-namespaceExcelent, driverul RBD funcționează!
Să creăm un nou StorageClass în Kubernetes. Pentru aceasta, va fi necesar să lucrăm puțin cu Ceph.
Creăm un nou utilizator în Ceph și îi dăm permisiuni de scriere în pool-ul kube:
ceph auth get-or-create client.rbdkube mon 'profile rbd' osd 'profile rbd pool=kube'Și acum, să vedem cheia de acces acolo unde am lăsat-o:
ceph auth get-key client.rbdkubeComanda va returna ceva de genul:
AQCO9NJbhYipKRAAMqZsnqqS/T8OYQX20xIa9A==Vom transmitem această valoare în Secretul din clusterul Kubernetes — acolo unde este necesară userKey:
---
apiVersion: v1
kind: Secret
metadata:
name: csi-rbd-secret
namespace: ceph-csi-rbd
stringData:
# Valorile cheilor corespund numelui de utilizator și cheii acestuia, așa cum este indicat în
# clusterul Ceph. ID-ul utilizatorului trebuie să aibă acces la pool-ul,
# specificat în clasa de stocare
userID: rbdkube
userKey:Și creăm secretul nostru:
kubectl apply -f secret.yamlApoi avem nevoie de un manifest StorageClass de genul:
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: csi-rbd-sc
provisioner: rbd.csi.ceph.com
parameters:
clusterID:
pool: kube
imageFeatures: layering
# Aceste secrete trebuie să conțină date pentru autorizare
# în pool-ul dvs.
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:
- discardTrebuie completat clusterID, pe care l-am aflat deja cu comanda ceph fsid, și aplicăm acest manifest în clusterul Kubernetes:
kubectl apply -f storageclass.yamlPentru a verifica funcționarea clusterelor împreună, voi crea un astfel de PVC (Persistent Volume Claim):
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: rbd-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: csi-rbd-scSă vedem imediat cum a creat Kubernetes volumul solicitat în Ceph:
kubectl get pvc
kubectl get pvSe pare că totul este în regulă! Cum arată din partea Ceph?
Obținem lista volumelor din pool și vizualizăm informațiile despre volumul nostru:
rbd ls -p kube
rbd -p kube info csi-vol-eb3d257d-8c6c-11ea-bff5-6235e7640653 # aici, evident, va fi un alt ID al volumului, generat de comanda anterioarăAcum să vedem cum funcționează modificarea dimensiunii volumului RBD.
Schimbăm dimensiunea volumului în manifestul pvc.yaml la 2Gi și îl aplicăm:
kubectl apply -f pvc.yamlSă așteptăm să intre în vigoare modificările și să verificăm din nou dimensiunea volumului.
rbd -p kube info csi-vol-eb3d257d-8c6c-11ea-bff5-6235e7640653
kubectl get pv
kubectl get pvcVedem că dimensiunea PVC-ului nu s-a modificat. Pentru a afla motivul, putem solicita descrierea PVC-ului de la Kubernetes în format YAML:
kubectl get pvc rbd-pvc -o yamlIată și problema:
message: Waiting for user to (re-)start a pod to finish file system resize of volume on node. type: FileSystemResizePending
Așa că discul s-a mărit, dar sistemul de fișiere de pe acesta nu.
Pentru a extinde sistemul de fișiere, trebuie să montăm volumul. PVC-ul/PV-ul nostru creat nu este utilizat acum în niciun fel.
Putem crea un Pod de test, de exemplu astfel:
---
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 acum să ne uităm la PVC:
kubectl get pvcDimensiunea s-a modificat, totul este în regulă.
În prima parte am lucrat cu un dispozitiv de blocare RBD (care se referă la Rados Block Device), dar nu este bine să procedăm astfel dacă se dorește acces simultan la acest disc din partea diferitelor microservicii. Pentru a lucra cu fișiere, mai degrabă decât cu o imagine de disc, CephFS este mult mai potrivit.
Pe baza clusterelor Ceph și Kubernetes, vom configura CSI și celelalte entități necesare pentru a lucra cu CephFS.
Vom obține valorile din noul Helm chart de care avem nevoie:
helm inspect values ceph-csi/ceph-csi-cephfs > cephfs.ymlDin nou, trebuie să completăm fișierul cephfs.yml. Așa cum am mai văzut, comenzile Ceph ne vor ajuta:
ceph fsid
ceph mon dumpCompletăm fișierul cu valorile aproximativ astfel:
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: trueRețineți că adresele monitorilor sunt specificate într-o formă simplă address:port. Pentru a monta cephfs pe nod, aceste adrese sunt transmise modulului kernel, care încă nu poate lucra cu protocolul monitorilor v2.
Portul pentru httpMetrics (unde Prometheus va obține metricile pentru monitorizare) este schimbat pentru a nu intra în conflict cu nginx-proxy, care este instalat de Kubespray. Aceasta, poate, nu va fi necesar pentru dvs.
Instalăm Helm chart-ul în clusterul Kubernetes:
helm upgrade -i ceph-csi-cephfs ceph-csi/ceph-csi-cephfs -f cephfs.yml -n ceph-csi-cephfs --create-namespaceTrecem la stocarea datelor Ceph pentru a crea un utilizator separat. În documentație se menționează că provisioner-ului CephFS îi sunt necesare privilegii de acces de administrator al clusterului. Dar vom crea un utilizator separat fs cu drepturi limitate:
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 imediat vom verifica cheia de acces, de care ne va fi nevoie mai departe:
ceph auth get-key client.fsVom crea un Secret și un StorageClass separate.
Nimic nou, am văzut deja acest lucru pe baza RBD:
---
apiVersion: v1
kind: Secret
metadata:
name: csi-cephfs-secret
namespace: ceph-csi-cephfs
stringData:
# Necesitate pentru volumele create dinamic
adminID: fs
adminKey:Aplicăm manifestul:
kubectl apply -f secret.yamlIar acum – un StorageClass separat:
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: csi-cephfs-sc
provisioner: cephfs.csi.ceph.com
parameters:
clusterID:
# Numele sistemului de fișiere CephFS în care va fi creat volum
fsName: cephfs
# (opțional) Pool-ul Ceph în care vor fi stocate datele volumului
# pool: cephfs_data
# (opțional) Opțiuni de montare separate prin virgulă pentru Ceph-fuse
# de exemplu:
# fuseMountOptions: debug
# (opțional) Opțiuni de montare CephFS pentru kernel, separate prin virgulă
# Consultați man mount.ceph pentru lista acestor opțiuni. De exemplu:
# kernelMountOptions: readdir_max_bytes=1048576,norbytes
# Secretele trebuie să conțină acces pentru administrator și/sau utilizatorul 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
# (opțional) Driverul poate folosi fie ceph-fuse (fuse),
# fie ceph kernelclient (kernel).
# Dacă nu este specificat, se va utiliza montarea volumelor implicit,
# aceasta fiind definită prin căutarea ceph-fuse și mount.ceph
# mounter: kernel
reclaimPolicy: Delete
allowVolumeExpansion: true
mountOptions:
- debugVom completa aici clusterID și vom aplica în Kubernetes:
kubectl apply -f storageclass.yamlVerificare
Pentru a verifica, la fel ca în exemplul anterior, vom crea un PVC:
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: csi-cephfs-pvc
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 5Gi
storageClassName: csi-cephfs-scȘi vom verifica prezența PVC/PV:
kubectl get pvc
kubectl get pvDacă doriți să vedeți fișierele și directoarele din CephFS, puteți monta acest sistem de fișiere undeva. De exemplu, așa cum este prezentat mai jos.
Să ne ducem pe unul dintre nodurile clusterului Ceph și să executăm aceste acțiuni:
# Точка монтирования
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/cephfsDesigur, o astfel de montare FS pe un nod Ceph este exclusiv pentru scopuri de învățare, ceea ce facem la cursurile noastre . Nu cred că cineva ar face asta în producție, riscul de a șterge accidental fișiere importante este mare.
Și, în cele din urmă, să verificăm cum stau lucrurile cu schimbarea dimensiunii volumului în cazul CephFS. Ne întoarcem în Kubernetes și edităm manifestul nostru pentru PVC — vom crește dimensiunea, de exemplu, la 7Gi.
Vom aplica fișierul editat:
kubectl apply -f pvc.yamlSă vedem în directorul montat cum s-a schimbat limita:
getfattr -n ceph.quota.max_bytesPentru a rula această comandă, este posibil să trebuiască să instalați în sistem pachetul attr.
Ochiul se teme, dar mâinile fac
La prima vedere, toate aceste incantații și lungi manifeste YAML par complicate, dar în practică, studenții de la Slyrm se descurcă destul de repede cu ele.
În acest articol nu ne-am aprofundat în detalii — pentru asta există documentația oficială. Dacă sunteți interesat de detaliile configurării stocării Ceph împreună cu clusterul Kubernetes, aceste linkuri vă vor ajuta:
În cursul Slyrm puteți merge puțin mai departe și desfășura o aplicație reală în Kubernetes care va folosi CephFS ca stocare pentru fișiere. Prin intermediul cererilor GET/POST, veți putea trimite și primi fișiere din Ceph.
Și dacă sunteți mai interesat de stocarea datelor, atunci înscrieți-vă la . În timp ce cursul este în testare beta, acesta poate fi obținut cu o reducere și aveți ocazia să influențați conținutul său.
Autorul articolului: Alexander Shvalov, inginer practician , Administrator Kubernetes Certificat, autor și dezvoltator de cursuri Slyrm.
Sursa: habr.com
