L'interfaccia di archiviazione dei contenitori (CSI) è un'interfaccia unificata tra Kubernetes e i sistemi di archiviazione dei dati. In breve, ne abbiamo già parlato , e oggi esamineremo più in dettaglio l'integrazione tra CSI e Ceph: mostreremo come a un cluster Kubernetes.
Nell'articolo sono forniti esempi reali, anche se leggermente semplificati per una migliore comprensione. Non esamineremo l'installazione e la configurazione dei cluster Ceph e Kubernetes.
Sei curioso di sapere come funziona?

Quindi, hai a disposizione un cluster Kubernetes, ad esempio . Accanto a esso c'è un cluster Ceph, che puoi anche installare, ad esempio, con questo . Spero non sia necessario menzionare che per l'ambiente di produzione tra di loro deve esserci una rete con una capacità di almeno 10 Gbit/s.
Se hai tutto questo, andiamo!
Innanzitutto, accediamo a uno dei nodi del cluster Ceph e verifichiamo che tutto sia a posto:
ceph health
ceph -sPoi creeremo immediatamente un pool per dischi RBD:
ceph osd pool create kube 32
ceph osd pool application enable kube rbdPassiamo al cluster Kubernetes. Lì, prima di tutto, installeremo il driver Ceph CSI per RBD. Lo installeremo, come da prassi, tramite Helm.
Aggiungiamo il repository con il chart e otteniamo un insieme di variabili del chart ceph-csi-rbd:
helm repo add ceph-csi https://ceph.github.io/csi-charts
helm inspect values ceph-csi/ceph-csi-rbd > cephrbd.ymlOra dobbiamo completare il file cephrbd.yml. Per fare ciò, scopriamo l'ID del cluster e gli indirizzi IP dei monitor in Ceph:
ceph fsid # così scopriamo il clusterID
ceph mon dump # in questo modo vediamo gli indirizzi IP dei monitorInseriamo i valori ottenuti nel file cephrbd.yml. Nel frattempo, attiviamo la creazione delle politiche PSP (Pod Security Policies). Le opzioni nelle sezioni nodeplugin e provisioner sono già presenti nel file e possono essere corrette come mostrato di seguito:
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: trueDopo, tutto ciò che ci resta è installare il chart nel cluster Kubernetes.
helm upgrade -i ceph-csi-rbd ceph-csi/ceph-csi-rbd -f cephrbd.yml -n ceph-csi-rbd --create-namespaceOttimo, il driver RBD funziona!
Creiamo un nuovo StorageClass in Kubernetes. Per fare ciò, dovremo lavorare un po' di nuovo con Ceph.
Creiamo un nuovo utente in Ceph e concediamogli diritti di scrittura nel pool kube:
ceph auth get-or-create client.rbdkube mon 'profile rbd' osd 'profile rbd pool=kube'Ora controlliamo la chiave di accesso là dove di consueto:
ceph auth get-key client.rbdkubeIl comando restituirà qualcosa di simile:
AQCO9NJbhYipKRAAMqZsnqqS/T8OYQX20xIa9A==Inseriremo questo valore in un Secret nel cluster Kubernetes, lì dove è necessario userKey:
---
apiVersion: v1
kind: Secret
metadata:
name: csi-rbd-secret
namespace: ceph-csi-rbd
stringData:
# I valori delle chiavi corrispondono al nome utente e alla sua chiave, come indicato nel
# cluster Ceph. L'ID utente deve avere accesso al pool,
# indicato nella storage class
userID: rbdkube
userKey:E creiamo il nostro segreto:
kubectl apply -f secret.yamlOra abbiamo bisogno di un manifesto StorageClass simile a questo:
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: csi-rbd-sc
provisioner: rbd.csi.ceph.com
parameters:
clusterID:
pool: kube
imageFeatures: layering
# Questi segreti devono contenere dati per l'autenticazione
# nel tuo pool.
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:
- discardDevi compilare clusterID, di cui abbiamo già parlato con il comando ceph fsid, e applicare questo manifesto nel cluster Kubernetes:
kubectl apply -f storageclass.yamlPer verificare il funzionamento dei cluster collegati, creiamo un PVC (Persistent Volume Claim) come questo:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: rbd-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: csi-rbd-scDiamo subito un'occhiata a come Kubernetes ha creato il volume richiesto in Ceph:
kubectl get pvc
kubectl get pvSembra tutto a posto! E come appare dal lato di Ceph?
Otteniamo un elenco di volumi nel pool e controlliamo le informazioni sul nostro volume:
rbd ls -p kube
rbd -p kube info csi-vol-eb3d257d-8c6c-11ea-bff5-6235e7640653 # qui, ovviamente, ci sarà un altro ID volume fornito dal comando precedenteOra vediamo come funziona l'ampliamento del volume RBD.
Modifichiamo la dimensione del volume nel manifesto pvc.yaml a 2Gi e lo applichiamo:
kubectl apply -f pvc.yamlAspettiamo che le modifiche abbiano effetto e diamo un'altra occhiata alla dimensione del volume.
rbd -p kube info csi-vol-eb3d257d-8c6c-11ea-bff5-6235e7640653
kubectl get pv
kubectl get pvcVediamo che la dimensione del PVC non è cambiata. Per scoprire il motivo, possiamo chiedere a Kubernetes di descrivere il PVC in formato YAML:
kubectl get pvc rbd-pvc -o yamlEcco il problema:
message: Waiting for user to (re-)start a pod to finish file system resize of volume on node. type: FileSystemResizePending
Quindi il disco è stato ampliato, ma il file system su di esso no.
Per aumentare il file system, occorre montare il volume. Al momento, il PVC/PV creato non è utilizzato.
Possiamo creare un Pod di prova, ad esempio in questo modo:
---
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: falseE ora diamo un'occhiata al PVC:
kubectl get pvcLa dimensione è cambiata, tutto va bene.
Nella prima parte abbiamo lavorato con un dispositivo di blocco RBD (che si traduce come Rados Block Device), ma non è possibile farlo se è necessaria la collaborazione simultanea di diversi microservizi su questo disco. Per lavorare con i file, e non con un'immagine del disco, CephFS è molto più adatto.
Prendiamo degli esempi dei cluster Ceph e Kubernetes per configurare CSI e le altre entità necessarie per lavorare con CephFS.
Otteniamo i valori dal nuovo Helm chart che ci interessa:
helm inspect values ceph-csi/ceph-csi-cephfs > cephfs.ymlÈ di nuovo necessario riempire il file cephfs.yml. Come prima, ci aiuteranno i comandi Ceph:
ceph fsid
ceph mon dumpCompiliamo il file con i valori in questo modo:
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: trueSi prega di notare che gli indirizzi dei monitor sono indicati nella forma semplice address:port. Per montare cephfs su un nodo, questi indirizzi vengono passati al modulo del kernel, che non è ancora in grado di lavorare con il protocollo dei monitor v2.
Modifichiamo la porta per httpMetrics (dove Prometheus andrà a cercare le metriche per il monitoraggio) in modo che non confligga con nginx-proxy, che è installato da Kubespray. Potrebbe non essere necessario per voi.
Installiamo l'Helm chart nel cluster Kubernetes:
helm upgrade -i ceph-csi-cephfs ceph-csi/ceph-csi-cephfs -f cephfs.yml -n ceph-csi-cephfs --create-namespacePassiamo al sistema di archiviazione Ceph per creare un utente separato. La documentazione indica che il provisioner CephFS necessita di diritti di accesso come amministratore del cluster. Ma noi creeremo un utente separato fs con diritti limitati:
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'E subito dopo guardiamo la sua chiave di accesso, che ci servirà in seguito:
ceph auth get-key client.fsCreiamo un Secret e un StorageClass separati.
Niente di nuovo, lo abbiamo già visto nell'esempio RBD:
---
apiVersion: v1
kind: Secret
metadata:
name: csi-cephfs-secret
namespace: ceph-csi-cephfs
stringData:
# Necessario per i volumi creati dinamicamente
adminID: fs
adminKey:Applichiamo il manifesto:
kubectl apply -f secret.yamlE ora – un StorageClass separato:
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: csi-cephfs-sc
provisioner: cephfs.csi.ceph.com
parameters:
clusterID:
# Nome del file system CephFS in cui verrà creato il volume
fsName: cephfs
# (opzionale) Pool Ceph in cui saranno memorizzati i dati del volume
# pool: cephfs_data
# (opzionale) Opzioni di montaggio separate da virgola per Ceph-fuse
# ad esempio:
# fuseMountOptions: debug
# (opzionale) Opzioni di montaggio CephFS per il kernel separate da virgola
# Vedi il man mount.ceph per un elenco di queste opzioni. Ad esempio:
# kernelMountOptions: readdir_max_bytes=1048576,norbytes
# I segreti devono contenere accessi per l'amministratore e/o l'utente 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
# (opzionale) Il driver può utilizzare o ceph-fuse (fuse),
# o ceph kernelclient (kernel).
# Se non specificato, verrà utilizzato il montaggio dei volumi predefinito,
# questo è determinato dalla ricerca di ceph-fuse e mount.ceph
# mounter: kernel
reclaimPolicy: Delete
allowVolumeExpansion: true
mountOptions:
- debugCompiliamo qui clusterID e applichiamo in Kubernetes:
kubectl apply -f storageclass.yamlVerifica
Per verificare, come nel caso precedente, creiamo un PVC:
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: csi-cephfs-pvc
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 5Gi
storageClassName: csi-cephfs-scE controlliamo la presenza di PVC/PV:
kubectl get pvc
kubectl get pvSe vuoi vedere i file e le directory in CephFS, puoi montare questo file system da qualche parte. Ad esempio, come mostrato di seguito.
Andiamo su uno dei nodi del cluster Ceph e facciamo queste operazioni:
# Точка монтирования
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/cephfsCerto, questo tipo di montaggio FS su un nodo Ceph è adatto esclusivamente per scopi didattici, come stiamo facendo nei nostri . Non penso che qualcuno lo farebbe in produzione, c'è un alto rischio di sovrascrivere accidentalmente file importanti.
E infine, verifichiamo come si presenta la situazione con la modifica delle dimensioni del volume in CephFS. Torniamo in Kubernetes e modifichiamo il nostro manifesto per il PVC — aumentando la dimensione, ad esempio, a 7Gi.
Applichiamo il file modificato:
kubectl apply -f pvc.yamlControlliamo nella directory montata come è cambiato il limite:
getfattr -n ceph.quota.max_bytesPer eseguire questo comando, potrebbe essere necessario installare il pacchetto attr.
Gli occhi hanno paura, ma le mani lavorano
A prima vista, tutti questi incantesimi e lunghi manifesti YAML possono sembrare complicati, ma nella pratica gli studenti di Slurm riescono a comprenderli abbastanza rapidamente.
In questo articolo non ci siamo addentrati nei dettagli — per questo c'è la documentazione ufficiale. Se sei interessato ai dettagli per configurare lo storage Ceph insieme al cluster Kubernetes, possono aiutarti questi link:
Nel corso di Slurm puoi andare ancora oltre e distribuire in Kubernetes un'applicazione reale che utilizzerà CephFS come storage per i file. Attraverso richieste GET/POST potrai inviare e ricevere file da Ceph.
E se ti interessa di più lo storage dei dati, iscriviti al . Finché è in fase di beta testing, il corso è disponibile a un prezzo scontato e puoi influenzare il suo contenuto.
Autore dell'articolo: Aleksandr Shvalov, ingegnere praticante , Certified Kubernetes Administrator, autore e sviluppatore dei corsi Slurm.
Fonte: habr.com
