Container Storage Interface (CSI) è un'interfaccia unificata per l'interazione tra Kubernetes e i sistemi di storage. Ne abbiamo già parlato brevemente , e oggi esamineremo più in dettaglio l'integrazione di CSI e Ceph: mostreremo come al cluster Kubernetes.
L'articolo presenta esempi reali, sebbene un po' semplificati per una migliore comprensione. Non tratteremo l'installazione e la configurazione dei cluster Ceph e Kubernetes.
Ti interessa sapere come funziona?

Quindi, hai a disposizione un cluster Kubernetes già distribuito, per esempio, . Accanto a esso opera un cluster Ceph, che può essere anche installato, ad esempio, con questo . Spero che non sia necessario menzionare che per l'ambiente di produzione deve esserci una rete con una larghezza di banda 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 -sSuccessivamente creiamo un pool per i dischi RBD:
ceph osd pool create kube 32
ceph osd pool application enable kube rbdPassiamo al cluster Kubernetes. Lì installeremo prima il driver Ceph CSI per RBD. Lo installeremo come da prassi, tramite Helm.
Aggiungiamo il repository con il chart, 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 compilare 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 # e così vediamo gli indirizzi IP dei monitorAnnotiamo i valori ottenuti nel file cephrbd.yml. Durante questo, abilitiamo la creazione delle politiche PSP (Pod Security Policies). Le opzioni nelle sezioni nodeplugin e provisioner sono già nel file, possono essere modificate 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: truePoi 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 questo avremo di nuovo bisogno di lavorare un po' con Ceph.
Creiamo un nuovo utente in Ceph e gli concediamo i diritti di scrittura nel pool kube:
ceph auth get-or-create client.rbdkube mon 'profile rbd' osd 'profile rbd pool=kube'E ora vediamo la chiave di accesso tutto lì:
ceph auth get-key client.rbdkubeIl comando restituirà qualcosa di simile:
AQCO9NJbhYipKRAAMqZsnqqS/T8OYQX20xIa9A==Registriamo questo valore nel Secret nel cluster Kubernetes — 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 specificato in
# nel cluster Ceph. L'ID utente deve avere accesso al pool,
# specificato nella classe di storage
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:
- discardDeve essere compilato clusterID, che abbiamo già appreso con il comando ceph fsid, e applicare questo manifesto nel cluster Kubernetes:
kubectl apply -f storageclass.yamlPer verificare il funzionamento dei cluster insieme, creiamo un PVC (Persistent Volume Claim) di questo tipo:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: rbd-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: csi-rbd-scVediamo subito come Kubernetes ha creato il volume richiesto in Ceph:
kubectl get pvc
kubectl get pvSembra tutto a posto! E come si presenta dal lato di Ceph?
Otteniamo l'elenco dei 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 il ridimensionamento 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 rivediamo la 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 richiedere a Kubernetes la descrizione del 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 aumentato, ma il file system su di esso no.
Per aumentare il file system, è necessario montare il volume. Attualmente, il nostro PVC/PV creato non è utilizzato in alcun modo.
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 il dispositivo di blocco RBD (che sta per Rados Block Device), ma non è possibile farlo se diversi microservizi devono accedere a questo disco contemporaneamente. Per lavorare con file, e non con un'immagine del disco, CephFS è molto più adatto.
Utilizzando i cluster Ceph e Kubernetes, configureremo CSI e tutte le altre entità necessarie per lavorare con CephFS.
Ottenendo i valori dal nuovo Helm chart che ci interessa:
helm inspect values ceph-csi/ceph-csi-cephfs > cephfs.ymlDobbiamo nuovamente completare 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 forniti nella forma semplice address:port. Per montare cephfs sul nodo, questi indirizzi vengono passati al modulo del kernel, che non è ancora in grado di lavorare con il protocollo dei monitor v2.
Cambiamo la porta per httpMetrics (da cui Prometheus raccoglierà le metriche per il monitoraggio) affinché non confligga con il nginx-proxy, che viene installato da Kubespray. Potreste non averne bisogno.
Installiamo il chart Helm nel cluster Kubernetes:
helm upgrade -i ceph-csi-cephfs ceph-csi/ceph-csi-cephfs -f cephfs.yml -n ceph-csi-cephfs --create-namespacePassiamo allo storage di dati Ceph per creare un utente separato. La documentazione indica che il provisioning di CephFS richiede diritti di accesso da amministratore del cluster. Ma 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 vediamo la sua chiave di accesso, ci servirà in seguito:
ceph auth get-key client.fsCreiamo un Secret e uno StorageClass separati.
Niente di nuovo, lo abbiamo già visto con l'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 – una StorageClass separata:
---
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 virgole per Ceph-fuse
# per esempio:
# fuseMountOptions: debug
# (opzionale) Opzioni di montaggio CephFS per il kernel, separate da virgole
# Vedi man mount.ceph per l'elenco di queste opzioni. Per 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 il ceph kernelclient (kernel).
# Se non specificato, verrà utilizzato il montaggio dei volumi predefiniti,
# 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 nell'esempio 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 l'esistenza di PVC/PV:
kubectl get pvc
kubectl get pvSe si desidera visualizzare file e directory in CephFS, è possibile montare questo file system da qualche parte. Ad esempio, come mostrato di seguito.
Andiamo su uno dei nodi del cluster Ceph e eseguiamo le seguenti azioni:
# Точка монтирования
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/cephfsNaturalmente, questo tipo di montaggio FS su un nodo Ceph è adatto esclusivamente per scopi didattici, che è ciò che stiamo facendo nei nostri . Non credo che qualcuno lo farebbe in produzione, poiché c'è un alto rischio di cancellare accidentalmente file importanti.
Infine, verifichiamo come vanno le cose con la modifica delle dimensioni del volume in CephFS. Torniamo su Kubernetes e modifichiamo il nostro manifesto per PVC — aumentiamo la dimensione, ad esempio, a 7Gi.
Applichiamo il file modificato:
kubectl apply -f pvc.yamlControlliamo nella directory montata come è cambiata la quota:
getfattr -n ceph.quota.max_bytesPer eseguire questo comando, potrebbe essere necessario installare il pacchetto attr.
Gli occhi temono, ma le mani agiscono
A prima vista, tutte queste configurazioni e lunghe manifestazioni YAML possono sembrare complesse, ma nella pratica gli studenti di Slurm le comprendono piuttosto rapidamente.
In questo articolo non ci siamo addentrati nei dettagli — per quello c'è la documentazione ufficiale. Se sei interessato ai dettagli per configurare lo storage Ceph in combinazione con un cluster Kubernetes, queste sono le fonti utili:
Nel corso di Slurm puoi andare un po' oltre e implementare un'applicazione reale in Kubernetes che utilizza CephFS come storage per i file. Attraverso richieste GET/POST puoi inviare e ricevere file da Ceph.
E se sei più interessato allo storage dei dati, iscriviti al . Durante la fase beta, il corso è disponibile a un prezzo scontato e puoi influenzare il suo contenuto.
Autore dell'articolo: Alexander Shvalov, ingegnere pratico , Certified Kubernetes Administrator, autore e sviluppatore dei corsi Slurm.
Fonte: habr.com
