Container Storage Interface (CSI) è un'interfaccia unificata tra Kubernetes e i sistemi di storage. Ne abbiamo già parlato brevemente
L'articolo fornisce esempi reali, anche se leggermente semplificati per facilitare la percezione. Non consideriamo l'installazione e la configurazione di cluster Ceph e Kubernetes.
Ti stai chiedendo come funziona?
Quindi hai un cluster Kubernetes a portata di mano, distribuito, ad esempio,
Se hai tutto questo, andiamo!
Per prima cosa andiamo in uno dei nodi del cluster Ceph e controlliamo che sia tutto in ordine:
ceph health
ceph -s
Successivamente, creeremo immediatamente un pool per i dischi RBD:
ceph osd pool create kube 32
ceph osd pool application enable kube rbd
Passiamo al cluster Kubernetes. Lì, prima di tutto, installeremo il driver Ceph CSI per RBD. Installeremo, come previsto, tramite Helm.
Aggiungi un repository con un grafico, ottieni un set di variabili del grafico ceph-csi-rbd:
helm repo add ceph-csi https://ceph.github.io/csi-charts
helm inspect values ceph-csi/ceph-csi-rbd > cephrbd.yml
Ora devi compilare il file cephrbd.yml. Per fare ciò, scopri l'ID del cluster e gli indirizzi IP dei monitor in Ceph:
ceph fsid # так мы узнаем clusterID
ceph mon dump # а так увидим IP-адреса мониторов
Inseriamo i valori ottenuti nel file cephrbd.yml. Allo stesso tempo, abilitiamo la creazione di policy PSP (Pod Security Policies). Opzioni nelle sezioni nodoplugin и provveditore già nel file, possono essere corretti 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: true
Successivamente non ci resta che installare il grafico nel cluster Kubernetes.
helm upgrade -i ceph-csi-rbd ceph-csi/ceph-csi-rbd -f cephrbd.yml -n ceph-csi-rbd --create-namespace
Ottimo, il driver RBD funziona!
Creiamo una nuova StorageClass in Kubernetes. Anche questo richiede un po' di manipolazione con Ceph.
Creiamo un nuovo utente in Ceph e gli diamo i diritti per scrivere nel pool cubo:
ceph auth get-or-create client.rbdkube mon 'profile rbd' osd 'profile rbd pool=kube'
Ora vediamo che la chiave di accesso è ancora lì:
ceph auth get-key client.rbdkube
Il comando restituirà qualcosa del genere:
AQCO9NJbhYipKRAAMqZsnqqS/T8OYQX20xIa9A==
Aggiungiamo questo valore a Secret nel cluster Kubernetes, dove ne abbiamo bisogno chiave utente:
---
apiVersion: v1
kind: Secret
metadata:
name: csi-rbd-secret
namespace: ceph-csi-rbd
stringData:
# Значения ключей соответствуют имени пользователя и его ключу, как указано в
# кластере Ceph. ID юзера должен иметь доступ к пулу,
# указанному в storage class
userID: rbdkube
userKey: <user-key>
E creiamo il nostro segreto:
kubectl apply -f secret.yaml
Successivamente, abbiamo bisogno di un manifest StorageClass simile a questo:
---
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
Deve essere compilato clusterID, che abbiamo già imparato dal team cefalo fside applica questo manifest al cluster Kubernetes:
kubectl apply -f storageclass.yaml
Per verificare come funzionano insieme i cluster, creiamo il seguente PVC (Persistent Volume Claim):
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: rbd-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: csi-rbd-sc
Vediamo subito come Kubernetes ha creato il volume richiesto in Ceph:
kubectl get pvc
kubectl get pv
Tutto sembra essere fantastico! E come appare dal lato Ceph?
Otteniamo un elenco di volumi nel pool e visualizziamo le informazioni sul nostro volume:
rbd ls -p kube
rbd -p kube info csi-vol-eb3d257d-8c6c-11ea-bff5-6235e7640653 # тут, конечно же, будет другой ID тома, который выдала предыдущая команда
Ora vediamo come funziona il ridimensionamento di un volume RBD.
Modifica la dimensione del volume nel manifest pvc.yaml in 2Gi e applicalo:
kubectl apply -f pvc.yaml
Aspettiamo che le modifiche abbiano effetto e guardiamo di nuovo la dimensione del volume.
rbd -p kube info csi-vol-eb3d257d-8c6c-11ea-bff5-6235e7640653
kubectl get pv
kubectl get pvc
Vediamo che la dimensione del PVC non è cambiata. Per scoprire il motivo, puoi interrogare Kubernetes per una descrizione YAML del PVC:
kubectl get pvc rbd-pvc -o yaml
Ecco il problema:
messaggio: In attesa che l'utente (ri)avvii un pod per completare il ridimensionamento del volume del file system sul nodo. tipo: FileSystemResizePending
Cioè, il disco è cresciuto, ma il file system su di esso no.
Per espandere il file system, è necessario montare il volume. Nel nostro Paese il PVC/PV creato non viene attualmente utilizzato in alcun modo.
Possiamo creare un pod di test, 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: false
E ora diamo un'occhiata al PVC:
kubectl get pvc
La dimensione è cambiata, va tutto bene.
Nella prima parte, abbiamo lavorato con il dispositivo a blocchi RBD (sta per Rados Block Device), ma ciò non può essere fatto se diversi microservizi devono funzionare contemporaneamente con questo disco. CephFS è molto più adatto per lavorare con file piuttosto che con immagini disco.
Utilizzando l'esempio dei cluster Ceph e Kubernetes, configureremo CSI e altre entità necessarie per funzionare con CephFS.
Otteniamo i valori dal nuovo grafico Helm di cui abbiamo bisogno:
helm inspect values ceph-csi/ceph-csi-cephfs > cephfs.yml
Anche in questo caso è necessario compilare il file cephfs.yml. Come prima, i comandi Ceph aiuteranno:
ceph fsid
ceph mon dump
Compila il file con valori come questo:
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
Tieni presente che gli indirizzi dei monitor sono specificati nella forma semplice indirizzo:porta. Per montare cephfs su un nodo, questi indirizzi vengono passati al modulo del kernel, che non sa ancora come funzionare con il protocollo monitor v2.
Modifichiamo la porta per httpMetrics (Prometheus andrà lì per monitorare le metriche) in modo che non entri in conflitto con nginx-proxy, che è installato da Kubespray. Potrebbe non essere necessario.
Installa il grafico Helm nel cluster Kubernetes:
helm upgrade -i ceph-csi-cephfs ceph-csi/ceph-csi-cephfs -f cephfs.yml -n ceph-csi-cephfs --create-namespace
Andiamo all'archivio dati Ceph per creare lì un utente separato. La documentazione afferma che il provisioner CephFS richiede diritti di accesso di 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 diamo subito un’occhiata alla sua chiave d’accesso, ci servirà dopo:
ceph auth get-key client.fs
Creiamo Secret e StorageClass separati.
Niente di nuovo, lo abbiamo già visto nell’esempio di RBD:
---
apiVersion: v1
kind: Secret
metadata:
name: csi-cephfs-secret
namespace: ceph-csi-cephfs
stringData:
# Необходимо для динамически создаваемых томов
adminID: fs
adminKey: <вывод предыдущей команды>
Applicazione del manifesto:
kubectl apply -f secret.yaml
E ora - una StorageClass separata:
---
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
Compiliamolo qui clusterID e applicabile in Kubernetes:
kubectl apply -f storageclass.yaml
Проверка
Per verificare, come nell'esempio precedente, creiamo una PVC:
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: csi-cephfs-pvc
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 5Gi
storageClassName: csi-cephfs-sc
E controlla la presenza di PVC/PV:
kubectl get pvc
kubectl get pv
Se vuoi esaminare file e 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 ed 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/cephfs
Naturalmente, montare FS su un nodo Ceph come questo è adatto solo a scopo di formazione, che è ciò che facciamo sul nostro
E infine, controlliamo come funzionano le cose con il ridimensionamento dei volumi nel caso di CephFS. Torniamo a Kubernetes e modifichiamo il nostro manifest per PVC: aumentiamo le dimensioni lì, ad esempio, a 7Gi.
Applichiamo il file modificato:
kubectl apply -f pvc.yaml
Diamo un'occhiata alla directory montata per vedere come è cambiata la quota:
getfattr -n ceph.quota.max_bytes <каталог-с-данными>
Affinché questo comando funzioni, potrebbe essere necessario installare il pacchetto attra.
Gli occhi hanno paura e le mani lo fanno
Tutti questi incantesimi e i lunghi manifest YAML sembrano complicati in superficie, ma in pratica gli studenti Slurm ne imparano abbastanza rapidamente.
In questo articolo non ci siamo addentrati nella giungla: esiste la documentazione ufficiale a riguardo. Se sei interessato ai dettagli sulla configurazione dello storage Ceph con un cluster Kubernetes, questi collegamenti ti saranno utili:
Sul corso Slurm
E se sei più interessato all'archiviazione dei dati, iscriviti
Autore dell'articolo: Alexander Shvalov, ingegnere praticante
Fonte: habr.com