Container Storage Interface (CSI) es una interfaz unificada entre Kubernetes y los sistemas de almacenamiento. Ya hemos hablado brevemente de ello.
El artículo proporciona ejemplos reales, aunque ligeramente simplificados para facilitar la percepción. No consideramos instalar ni configurar clústeres de Ceph y Kubernetes.
¿Te preguntas cómo funciona?
Entonces, tiene un clúster de Kubernetes a su alcance, implementado, por ejemplo,
Si tienes todo esto, ¡vamos!
Primero, vayamos a uno de los nodos del clúster Ceph y comprobemos que todo está en orden:
ceph health
ceph -s
A continuación, crearemos inmediatamente un grupo para discos RBD:
ceph osd pool create kube 32
ceph osd pool application enable kube rbd
Pasemos al clúster de Kubernetes. Allí, en primer lugar, instalaremos el controlador Ceph CSI para RBD. Lo instalaremos, como era de esperar, a través de Helm.
Agregamos un repositorio con un gráfico, obtenemos un conjunto de variables para el gráfico ceph-csi-rbd:
helm repo add ceph-csi https://ceph.github.io/csi-charts
helm inspect values ceph-csi/ceph-csi-rbd > cephrbd.yml
Ahora necesita completar el archivo cephrbd.yml. Para hacer esto, averigüe el ID del clúster y las direcciones IP de los monitores en Ceph:
ceph fsid # так мы узнаем clusterID
ceph mon dump # а так увидим IP-адреса мониторов
Ingresamos los valores obtenidos en el archivo cephrbd.yml. Al mismo tiempo habilitamos la creación de políticas PSP (Pod Security Policies). Opciones en secciones complemento de nodo и 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: true
A continuación, solo nos queda instalar el gráfico 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 funciona!
Creemos una nueva StorageClass en Kubernetes. Nuevamente, esto requiere algunos retoques con Ceph.
Creamos un nuevo usuario en Ceph y le damos derechos para escribir en el grupo. cubo:
ceph auth get-or-create client.rbdkube mon 'profile rbd' osd 'profile rbd pool=kube'
Ahora veamos que la clave de acceso sigue ahí:
ceph auth get-key client.rbdkube
El comando generará algo como esto:
AQCO9NJbhYipKRAAMqZsnqqS/T8OYQX20xIa9A==
Agreguemos este valor a Secret en el clúster de Kubernetes, donde lo necesitemos. clave de usuario:
---
apiVersion: v1
kind: Secret
metadata:
name: csi-rbd-secret
namespace: ceph-csi-rbd
stringData:
# Значения ключей соответствуют имени пользователя и его ключу, как указано в
# кластере Ceph. ID юзера должен иметь доступ к пулу,
# указанному в storage class
userID: rbdkube
userKey: <user-key>
Y creamos nuestro secreto:
kubectl apply -f secret.yaml
A continuación, necesitamos un manifiesto StorageClass similar a este:
---
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
Necesita ser completado ID de clúster, que ya hemos aprendido por el equipo ceph fsidy aplique este manifiesto al clúster de Kubernetes:
kubectl apply -f storageclass.yaml
Para comprobar cómo funcionan los clústeres juntos, creemos el siguiente PVC (reclamación de volumen persistente):
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: rbd-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: csi-rbd-sc
Veamos inmediatamente cómo Kubernetes creó el volumen solicitado en Ceph:
kubectl get pvc
kubectl get pv
¡Todo parece ir genial! ¿Cómo se ve esto en el lado de Ceph?
Obtenemos una lista de volúmenes en el grupo y vemos información sobre nuestro volumen:
rbd ls -p kube
rbd -p kube info csi-vol-eb3d257d-8c6c-11ea-bff5-6235e7640653 # тут, конечно же, будет другой ID тома, который выдала предыдущая команда
Ahora veamos cómo funciona el cambio de tamaño de un volumen RBD.
Cambie el tamaño del volumen en el manifiesto pvc.yaml a 2Gi y aplíquelo:
kubectl apply -f pvc.yaml
Esperemos a que los cambios surtan efecto y volvamos a mirar el tamaño del volumen.
rbd -p kube info csi-vol-eb3d257d-8c6c-11ea-bff5-6235e7640653
kubectl get pv
kubectl get pvc
Vemos que el tamaño del PVC no ha cambiado. Para saber por qué, puede consultar a Kubernetes para obtener una descripción YAML del PVC:
kubectl get pvc rbd-pvc -o yaml
Aquí está el problema:
Mensaje: Esperando a que el usuario (re)inicie un pod para finalizar el cambio de tamaño del sistema de archivos del volumen en el nodo. tipo: FileSystemResizePending
Es decir, el disco ha crecido, pero el sistema de archivos que contiene, no.
Para hacer crecer el sistema de archivos, necesita montar el volumen. En nuestro país, el PVC/PV creado actualmente no se utiliza de ninguna manera.
Podemos crear un Pod de prueba, por ejemplo así:
---
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
Y ahora veamos el PVC:
kubectl get pvc
La talla ha cambiado, todo está bien.
En la primera parte, trabajamos con el dispositivo de bloque RBD (que significa Rados Block Device), pero esto no se puede hacer si diferentes microservicios necesitan trabajar con este disco simultáneamente. CephFS es mucho más adecuado para trabajar con archivos que con imágenes de disco.
Usando el ejemplo de los clústeres de Ceph y Kubernetes, configuraremos CSI y otras entidades necesarias para trabajar con CephFS.
Obtengamos los valores del nuevo gráfico de Helm que necesitamos:
helm inspect values ceph-csi/ceph-csi-cephfs > cephfs.yml
Nuevamente debe completar el archivo cephfs.yml. Como antes, los comandos Ceph ayudarán:
ceph fsid
ceph mon dump
Complete el archivo con valores como este:
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
Tenga en cuenta que las direcciones de los monitores se especifican en el formato simple dirección:puerto. Para montar cephfs en un nodo, estas direcciones se pasan al módulo del kernel, que aún no sabe cómo trabajar con el protocolo de monitor v2.
Cambiamos el puerto para httpMetrics (Prometheus irá allí para monitorear las métricas) para que no entre en conflicto con nginx-proxy, que instala Kubespray. Puede que no necesites esto.
Instale el gráfico Helm 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-namespace
Vayamos al almacén de datos de Ceph para crear un usuario independiente allí. La documentación indica que el aprovisionador de CephFS requiere 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 miremos inmediatamente su clave de acceso, la necesitaremos más tarde:
ceph auth get-key client.fs
Creemos Secret y StorageClass separados.
Nada nuevo, esto ya lo hemos visto en el ejemplo de RBD:
---
apiVersion: v1
kind: Secret
metadata:
name: csi-cephfs-secret
namespace: ceph-csi-cephfs
stringData:
# Необходимо для динамически создаваемых томов
adminID: fs
adminKey: <вывод предыдущей команды>
Aplicando el manifiesto:
kubectl apply -f secret.yaml
Y ahora, una StorageClass separada:
---
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
Completemoslo aquí ID de clúster y aplicable en Kubernetes:
kubectl apply -f storageclass.yaml
Проверка
Para comprobarlo, como en el ejemplo anterior, creemos un PVC:
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: csi-cephfs-pvc
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 5Gi
storageClassName: csi-cephfs-sc
Y comprobar la presencia de PVC/PV:
kubectl get pvc
kubectl get pv
Si desea ver archivos y directorios en CephFS, puede montar este sistema de archivos en algún lugar. Por ejemplo, como se muestra a continuación.
Vayamos a uno de los nodos del clúster Ceph y realicemos 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/cephfs
Por supuesto, montar FS en un nodo Ceph como este sólo es adecuado para fines de capacitación, que es lo que hacemos en nuestro
Y finalmente, veamos cómo funcionan las cosas al cambiar el tamaño de los volúmenes en el caso de CephFS. Volvamos a Kubernetes y editemos nuestro manifiesto para PVC; aumentemos el tamaño allí, por ejemplo, a 7Gi.
Apliquemos el archivo editado:
kubectl apply -f pvc.yaml
Miremos el directorio montado para ver cómo ha cambiado la cuota:
getfattr -n ceph.quota.max_bytes <каталог-с-данными>
Para que este comando funcione, es posible que necesite instalar el paquete en su sistema attr.
Los ojos tienen miedo y las manos están haciendo
Todos estos hechizos y manifiestos YAML largos parecen complicados en la superficie, pero en la práctica, los estudiantes de Slurm los dominan con bastante rapidez.
En este artículo no nos adentramos en la jungla; existe documentación oficial para ello. Si está interesado en los detalles sobre cómo configurar el almacenamiento Ceph con un clúster de Kubernetes, estos enlaces le ayudarán:
En el curso de Slurm
Y si está más interesado en el almacenamiento de datos, regístrese en
Autor del artículo: Alexander Shvalov, ingeniero en ejercicio
Fuente: habr.com