La Interfaz de Almacenamiento de Contenedores (CSI) es una interfaz unificada que permite la interacción entre Kubernetes y los sistemas de almacenamiento de datos. Ya hemos hablado brevemente sobre ella, y hoy examinaremos más a fondo la conexión entre CSI y Ceph: mostraremos cómo al clúster de Kubernetes.
El artículo presenta ejemplos reales, aunque un poco simplificados para facilitar la comprensión. No abordamos la instalación y configuración de los clústeres Ceph y Kubernetes.
¿Te interesa saber cómo funciona?

Entonces, tienes a mano un clúster de Kubernetes desplegado, por ejemplo, Cerca hay un clúster Ceph, que también se puede instalar, por ejemplo, con este Espero que no sea necesario mencionar que para la producción, entre ellos debe haber una red con un ancho de banda de al menos 10 Gbit/s.
Si tienes todo esto, ¡vamos!
Primero, accedamos a uno de los nodos del clúster Ceph y verifiquemos que todo esté en orden:
ceph health
ceph -sA continuación, crearemos un pool para discos RBD:
ceph osd pool create kube 32
ceph osd pool application enable kube rbdPasamos al clúster de Kubernetes. Allí, lo primero que haremos será instalar el controlador Ceph CSI para RBD. Lo haremos, como corresponde, a través de Helm.
Agregamos el repositorio con el chart y obtenemos un conjunto de variables 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.ymlAhora necesitamos completar el archivo cephrbd.yml. Para hacer esto, averiguamos el ID del clúster y las direcciones IP de los monitores en Ceph:
ceph fsid # así averiguamos el clusterID
ceph mon dump # y así veremos las direcciones IP de los monitoresLos valores obtenidos se ingresan en el archivo cephrbd.yml. A la vez, activamos la creación de políticas PSP (Pod Security Policies). Las opciones en las secciones nodeplugin y proveedor ya están en el archivo, se pueden corregir como se muestra a continuación:
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: trueA continuación, lo único que nos queda es instalar el chart en el clúster de Kubernetes.
helm upgrade -i ceph-csi-rbd ceph-csi/ceph-csi-rbd -f cephrbd.yml -n ceph-csi-rbd --create-namespace¡Genial, el controlador RBD está funcionando!
Creemos una nueva StorageClass en Kubernetes. Para ello, será necesario trabajar un poco más con Ceph.
Crearemos un nuevo usuario en Ceph y le otorgaremos derechos de escritura en el pool kube.:
ceph auth get-or-create client.rbdkube mon 'profile rbd' osd 'profile rbd pool=kube'Y ahora veamos la clave de acceso allí mismo:
ceph auth get-key client.rbdkubeEl comando devolverá algo como esto:
AQCO9NJbhYipKRAAMqZsnqqS/T8OYQX20xIa9A==Introduciremos este valor en un Secret en el clúster de Kubernetes, donde se necesita userKey:
---
apiVersion: v1
kind: Secret
metadata:
name: csi-rbd-secret
namespace: ceph-csi-rbd
stringData:
# Los valores de las claves correspondan al nombre de usuario y su clave, como se indica en
# el clúster Ceph. El ID del usuario debe tener acceso al pool,
# especificado en la clase de almacenamiento
userID: rbdkube
userKey:Y creamos nuestro secreto:
kubectl apply -f secret.yamlA continuación, necesitamos un manifiesto StorageClass similar al siguiente:
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: csi-rbd-sc
provisioner: rbd.csi.ceph.com
parameters:
clusterID:
pool: kube
imageFeatures: layering
# Estos secretos deben contener datos para la autorización
# en su 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:
- discardNecesitamos llenar clusterID, que ya hemos obtenido con el comando ceph fsid, y aplicar este manifiesto en el clúster de Kubernetes:
kubectl apply -f storageclass.yamlPara verificar el funcionamiento de los clústeres en conjunto, crearemos un PVC (Persistent Volume Claim) como el siguiente:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: rbd-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: csi-rbd-scVeamos de inmediato cómo Kubernetes creó el volumen solicitado en Ceph:
kubectl get pvc
kubectl get pv¡Todo parece estar bien! ¿Y cómo se ve esto del lado de Ceph?
Obtenemos una lista de volúmenes en el pool y revisamos la información de nuestro volumen:
rbd ls -p kube
rbd -p kube info csi-vol-eb3d257d-8c6c-11ea-bff5-6235e7640653 # aquí, por supuesto, habrá un ID diferente del volumen que proporcionó el comando anteriorAhora veamos cómo funciona el cambio de tamaño del volumen RBD.
Cambiamos el tamaño del volumen en el manifiesto pvc.yaml a 2Gi y lo aplicamos:
kubectl apply -f pvc.yamlEsperemos a que los cambios surtan efecto y miremos nuevamente el tamaño del volumen.
rbd -p kube info csi-vol-eb3d257d-8c6c-11ea-bff5-6235e7640653
kubectl get pv
kubectl get pvcVemos que el tamaño del PVC no ha cambiado. Para averiguar la razón, podemos solicitar a Kubernetes la descripción del PVC en formato YAML:
kubectl get pvc rbd-pvc -o yamlY aquí está el problema:
message: Waiting for user to (re-)start a pod to finish file system resize of volume on node. type: FileSystemResizePending
Es decir, el disco ha aumentado, pero el sistema de archivos en él no.
Para aumentar el sistema de archivos, es necesario montar el volumen. El PVC/PV que hemos creado no se está utilizando en este momento.
Podemos crear un Pod de prueba, por ejemplo, de esta manera:
---
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: falseY ahora veamos el PVC:
kubectl get pvcEl tamaño ha cambiado, todo está bien.
En la primera parte trabajamos con el dispositivo de bloque RBD (que se traduce como Rados Block Device), pero esto no se puede hacer si se requiere que diferentes microservicios trabajen con este disco al mismo tiempo. Para trabajar con archivos, en lugar de con la imagen del disco, CephFS es mucho más adecuado.
Usaremos los clústeres Ceph y Kubernetes para configurar CSI y las otras entidades necesarias para trabajar con CephFS.
Obtendremos los valores del nuevo Helm-chart que necesitamos:
helm inspect values ceph-csi/ceph-csi-cephfs > cephfs.ymlDe nuevo, necesitamos completar el archivo cephfs.yml. Como antes, las órdenes de Ceph serán útiles:
ceph fsid
ceph mon dumpCompletamos el archivo con los valores de la siguiente manera:
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: trueTenga en cuenta que las direcciones de los monitores se indican en la forma simple address:port. Para montar cephfs en el nodo, estas direcciones se pasan al módulo del núcleo, que aún no puede trabajar con el protocolo de monitores v2.
Cambiamos el puerto para httpMetrics (donde Prometheus irá a recoger métricas para la supervisión) para que no entre en conflicto con nginx-proxy, que se instala con Kubespray. Puede que esto no sea necesario para usted.
Instalamos el Helm-chart en el clúster de Kubernetes:
helm upgrade -i ceph-csi-cephfs ceph-csi/ceph-csi-cephfs -f cephfs.yml -n ceph-csi-cephfs --create-namespaceVamos al almacenamiento de datos Ceph para crear un usuario separado. La documentación indica que el provisionador de CephFS necesita derechos de acceso de administrador del clúster. Pero crearemos un usuario separado fs con derechos limitados:
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'Y de inmediato veremos su clave de acceso, que nos será útil más adelante:
ceph auth get-key client.fsCrearemos un Secret y un StorageClass separados.
Nada nuevo, ya lo hemos visto en el ejemplo de RBD:
---
apiversion: v1
kind: Secret
metadata:
name: csi-cephfs-secret
namespace: ceph-csi-cephfs
stringData:
# Necesario para volúmenes creados dinámicamente
adminID: fs
adminKey:Aplicamos el manifiesto:
kubectl apply -f secret.yamlY ahora – un StorageClass separado:
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: csi-cephfs-sc
provisioner: cephfs.csi.ceph.com
parameters:
clusterID:
# Nombre del sistema de archivos CephFS donde se creará el volumen
fsName: cephfs
# (opcional) Pool Ceph donde se almacenarán los datos del volumen
# pool: cephfs_data
# (opcional) Opciones de montaje separadas por comas para Ceph-fuse
# por ejemplo:
# fuseMountOptions: debug
# (opcional) Opciones de montaje de CephFS para el núcleo, separadas por comas
# Consulte man mount.ceph para obtener una lista de estas opciones. Por ejemplo:
# kernelMountOptions: readdir_max_bytes=1048576,norbytes
# Los secretos deben contener accesos para el administrador y/o el usuario de 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
# (opcional) El controlador puede usar ceph-fuse (fuse)
# o ceph kernelclient (kernel).
# Si no se especifica, se utilizará el montaje de volúmenes por defecto,
# lo cual se determina buscando ceph-fuse y mount.ceph
# mounter: kernel
reclaimPolicy: Delete
allowVolumeExpansion: true
mountOptions:
- debugLlenemos esto aquí clusterID y aplicamos en Kubernetes:
kubectl apply -f storageclass.yamlVerificación
Para verificar, como en el ejemplo anterior, crearemos un PVC:
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: csi-cephfs-pvc
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 5Gi
storageClassName: csi-cephfs-scY verificamos la existencia de PVC/PV:
kubectl get pvc
kubectl get pvSi deseas ver los archivos y directorios en CephFS, puedes montar este sistema de archivos en algún lugar. Por ejemplo, como se muestra a continuación.
Viajamos a uno de los nodos del clúster Ceph y realizamos las siguientes acciones:
# Точка монтирования
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/cephfsPor supuesto, este tipo de montaje de FS en un nodo Ceph es adecuado exclusivamente para fines de aprendizaje, que es lo que estamos haciendo en nuestros . No creo que alguien haga esto en producción, ya que existe un alto riesgo de sobrescribir archivos importantes.
Y para terminar, comprobemos cómo se maneja el cambio de tamaño del volumen en el caso de CephFS. Volvemos a Kubernetes y editamos nuestro manifiesto para el PVC, aumentamos su tamaño, por ejemplo, a 7Gi.
Aplicamos el archivo editado:
kubectl apply -f pvc.yamlVeamos en el directorio montado cómo ha cambiado la cuota:
getfattr -n ceph.quota.max_bytesPara ejecutar este comando, es posible que necesites instalar el paquete attr.
Los ojos tienen miedo, pero las manos lo hacen
A simple glance at all these spells and lengthy YAML manifests might seem daunting, but in practice, Slurm students manage to grasp them quite quickly.
In this article, we haven't delved deep — for that, there is the official documentation. If you're interested in the details of configuring Ceph storage in conjunction with a Kubernetes cluster, these links will help:
In the Slurm course you can go a step further and deploy a real application in Kubernetes that will use CephFS as its storage for files. Through GET/POST requests, you will be able to transfer files to and retrieve them from Ceph.
And if you are more interested in data storage, then sign up for . While the beta testing is ongoing, the course can be obtained at a discount and you can influence its content.
Author of the article: Alexander Shvalov, practicing engineer , Certified Kubernetes Administrator, author and developer of Slurm courses.
Fuente: habr.com
