Almacenamiento persistente para Kubernetes basado en Linstor / Sudo Null IT News
Muchos DevOps novatos que dominan Kubernetes se enfrentan a la pregunta: “¿Cómo organizar el almacenamiento persistente en su clúster de Kubernetes?” Hay muchas opciones para este propósito: ceph, nfs, mayastor, iscsi, linstor, longhorn. Hoy veremos uno de ellos: Linstor (también conocido como Pireo). Configuraremos nuestro Almacenamiento Persistente y lo conectaremos a nuestro clúster de Kubernetes.
Prefacio:
Acerca de PersistentStorage: qué es y para qué sirve, puede leerlo en este artículo.
Aquí se describe en detalle qué es linstor y cómo funciona.
Equipo inicial:
Aquí configuramos un clúster de Kubernetes de un solo nodo para nuestros experimentos. Es a esto a lo que conectaremos nuestro PersistentStorage.
Para implementar los objetivos de nuestro experimento, necesitaremos 7 GB de RAM para una máquina virtual con un clúster de cubos.
Dirección IP de la máquina virtual con nuestro cluster de cuber de un solo nodo: 172.20.0.31/24
Para el cluster linstor usaremos tres máquinas virtuales con RedOS8. Necesitamos tres máquinas virtuales para que las instancias de drbd puedan reunir un quórum para seleccionar una instancia principal.
Debido a la escasez de mis recursos, la configuración de cada máquina virtual será la siguiente:CPU: 2 / RAM: 2GB / HDD: 8GB + ещё один диск
en el que se ubicará el almacenamiento en sí, cuanto más grande sea este disco, más espacio habrá en nuestro Almacenamiento. Mi disco tendrá un tamaño de 10 GB.
Deje que los nombres de host de mis máquinas virtuales sean s1, s2, s3
(Los siguientes nombres de host se utilizarán al configurar un clúster de linstor).
Direcciones IP de máquinas virtuales: 172.20.0.21/24, 172.20.0.22/24, 172.20.0.23/24
Preparando máquinas virtuales:
A continuación se describen las acciones que deben realizarse en todas las máquinas virtuales de nuestro futuro clúster linstor, y también en máquinas virtuales clúster de kubernetes.
Primero que nada, necesitamos actualizar todas las máquinas virtuales:
dnf update -y && reboot
Instale los paquetes necesarios (no es necesario instalar docker-ce en la máquina virtual del clúster de Kubernetes):
dnf install -y docker-ce drbd drbd-kmod drbd-reactorzfs zfs-kmod
Configuramos el inicio automático de los módulos del kernel y lanzamos estos módulos:
echo -e "dm_cache\ndm_crypt\ndm_thin_pool\ndm_snapshot\ndm_writecache\ndrbd\ndrbd_transport_tcp\nlibcrc32c\nloop\nnvmet_rdma\nnvme_rdma\n" > /etc/modules-load.d/drbd.conf
echo "options drbd usermode_helper=disabled" > /etc/modprobe.d/drbd.conf
modprobe -a $(cat /etc/modules-load.d/drbd.conf)
Sintonicemos un poco lvm:
sed -i 's/# global_filter = .*/global_filter = \( \"r\|\^\/dev\/drbd\|\" \)/' /etc/lvm/lvm.conf
Instalación y lanzamiento de un clúster linstor
En las tres máquinas virtuales (s1, s2, s3) destinadas al clúster linstor, realice los siguientes pasos.
Crear un archivo /etc/systemd/system/linstor-satellite.service
para ejecutar linstor-satellit
cat <<EOF > /etc/systemd/system/linstor-satellite.service
(Unit)
Description=Linstor-Satellite container
After=docker.service
Wants=network-online.target docker.socket
Requires=docker.socket
(Service)
Restart=always
ExecStartPre=/bin/bash -c "/usr/bin/docker container inspect linstor-satellite 2> /dev/null || /usr/bin/docker run -d --name=linstor-satellite --net=host -v /dev:/dev -v /var/lib/drbd:/var/lib/drbd --privileged quay.io/piraeusdatastore/piraeus-server:v1.29.1"
ExecStart=/usr/bin/docker start -a linstor-satellite
ExecStop=/usr/bin/docker stop -t 10 linstor-satellite
(Install)
WantedBy=multi-user.target
EOF
Inicie el satélite linstor:
systemctl daemon-reload && systemctl enable --now linstor-satellite
En tarjetas virtuales s1 (solo en ella) crear un archivo /etc/systemd/system/linstor-controller.service
para iniciar el controlador linstor:
cat <<EOF > /etc/systemd/system/linstor-controller.service
(Unit)
Description=Linstor-Controller container
After=docker.service
Wants=network-online.target docker.socket
Requires=docker.socket
(Service)
Restart=always
ExecStartPre=/bin/bash -c "/usr/bin/docker container inspect linstor-controller 2> /dev/null || /usr/bin/docker run -d --name=linstor-controller --net=host -v /dev:/dev -v /var/lib/linstor/:/var/lib/linstor/ --privileged quay.io/piraeusdatastore/piraeus-server:v1.29.1 startController"
ExecStart=/usr/bin/docker start -a linstor-controller
ExecStop=/usr/bin/docker stop -t 10 linstor-controller
(Install)
WantedBy=multi-user.target
EOF
Iniciemos nuestro controlador linstor:
systemctl daemon-reload && systemctl enable --now linstor-controller
Puede verificar el éxito del lanzamiento de linstor-controller y linstor-satellite con el comando:
docker ps
Configurar un clúster de linstor
En VM s1 (donde ejecutamos linstor-cotroller) realizamos pasos simples para configurar el clúster de linstor.
Me gustaría enfatizar que todas las acciones realizadas en este párrafo del artículo “Configuración de un clúster de linstor” deben realizarse solo en la máquina virtual en la que se ejecuta linstor-controller.
Usamos un contenedor Docker que ya se está ejecutando. linstor-controller
: lanzamos una utilidad de consola dentro del contenedor para administrar el clúster de linstor con los parámetros que necesitamos.
Adjuntamos un nodo ubicado en la máquina virtual al cluster s1,
cuya dirección IP 172.20.0.21
docker exec -it linstor-controller linstor node create s1 172.20.0.21
De la misma manera, adjuntamos los nodos s2 (172.20.0.22) y s3 (172.20.0.23) al clúster:
docker exec -it linstor-controller linstor node create s2 172.20.0.22
docker exec -it linstor-controller linstor node create s3 172.20.0.23
Comprobemos el resultado:
docker exec -it linstor-controller linstor node list
Veamos cuánto espacio tenemos para nuestro PersistentStorage:
docker exec -it linstor-controller linstor physical-storage list
¡Excelente! Vemos que cada nodo tiene un disco libre. /dev/sdb
10 GB cada uno.
Creamos en estos discos (/dev/sdb
) StoragePool con nombre sp01
en cada nodo por separado: s1, s2, s3
(ejecute todos los comandos en la máquina virtual s1 con linstor-controller):
docker exec -it linstor-controller linstor physical-storage create-device-pool --pool-name lvmpool LVMTHIN s1 /dev/sdb --storage-pool sp01
docker exec -it linstor-controller linstor physical-storage create-device-pool --pool-name lvmpool LVMTHIN s2 /dev/sdb --storage-pool sp01
docker exec -it linstor-controller linstor physical-storage create-device-pool --pool-name lvmpool LVMTHIN s3 /dev/sdb --storage-pool sp01
Admiramos el resultado:
docker exec -it linstor-controller linstor storage-pool list
Conexión de PersistentStorage al clúster de Kubernetes
En la máquina virtual de nuestro cluster Kuber de un solo nodo realizamos los siguientes pasos.
Creemos un directorio de trabajo:
mkdir ~/piraeus && cd ~/piraeus
Clonación del operador del pireo
git clone --branch v2 https://github.com/piraeusdatastore/piraeus-operator
Establecemos en nuestro kuber-cluster helm-chart piraeus-operator:
helm install piraeus-operator piraeus-operator/charts/piraeus --create-namespace -n piraeus-datastore --set installCRDs="true"
Mientras el operador descarga y ejecuta, preparemos los archivos necesarios para la configuración.
Creemos un archivo con la configuración de linstor-cluster en nuestro cuber:
cat <<EOF > LinstorCluster.yaml
apiVersion: piraeus.io/v1
kind: LinstorCluster
metadata:
name: linstorcluster
spec:
externalController:
url:
EOF
Archivo con configuración de linstor-satellite:
cat <<EOF > LinstorSatelliteConfiguration.yaml
apiVersion: piraeus.io/v1
kind: LinstorSatelliteConfiguration
metadata:
name: satellite
spec:
podTemplate:
spec:
initContainers:
- name: drbd-module-loader
\$patch: delete
hostNetwork: true
EOF
El significado profundo de estos dos archivos es el siguiente: en nuestro cluster cuber crearemos un nodo adicional más (o varios si el cluster es de múltiples nodos) de nuestro cluster linstor. Estos nodos se conectarán a nuestro clúster linstor externo y replicarán las particiones drbd en el nodo del clúster cuber.
Entonces… usamos los archivos yaml creados:
kubectl apply -f LinstorCluster.yaml
kubectl apply -f LinstorSatelliteConfiguration.yaml
Esperamos un par de minutos y comprobamos el resultado:
kubectl get pods -n piraeus-datastore
¡Éxito! Se iniciaron todas las cápsulas necesarias.
nosotros creamos Clase de almacenamiento:
cat << EOF > StorageClass.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: linstor
provisioner: linstor.csi.linbit.com
parameters:
autoPlace: "2"
storagePool: sp01
resourceGroup: DfltRscGrp
EOF
kubectl apply -f StorageClass.yaml
¡Esto completa la configuración!
Comprobando el funcionamiento de PersistentStorage
Creamos nuestra prueba PersistentVolumeClaim, gracias a la cual el cuber creará un PersistentVolume conectado a nuestro clúster linstor:
cat <<EOF > testpvc.yaml
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: testpvc
spec:
storageClassName: linstor
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 500Mi
EOF
kubectl apply –f testpvc.yaml
kubectl get pvc
Creamos un pod que se conectará a testpvc, lo montaremos dentro del contenedor en el directorio /data
y comenzará a guardar una vez cada 10 segundos /data
un archivo a la vez:
cat <<EOF > testpod.yaml
apiVersion: v1
kind: Pod
metadata:
name: alpine
namespace: default
spec:
containers:
- name: alpine
image: alpine
command: (/bin/sh)
args: ("-c", "while true; do echo $(date '+%Y%m%d-%H%M%S') > /data/$(date '+%Y%m%d-%H%M%S') ; sleep 10; done")
volumeMounts:
- name: testpvc
mountPath: /data
volumes:
- name: testpvc
persistentVolumeClaim:
claimName: "testpvc"
EOF
kubectl apply –f testpod.yaml
Veamos qué pasó:
kubectl get pods
Entramos en el pod de shell y comprobamos el contenido del directorio. /data:
kubectl exec -it alpine -- ls -la /data
¡Maravilloso! eso lo vemos en /data
Los archivos aparecen cada 10 segundos.
Ahora eliminamos nuestro pod y lo volvemos a crear con la misma configuración:
kubectl delete pod alpine && kubectl apply –f testpod.yaml
Al eliminar un pod, el cuber elimina todo lo que estaba almacenado dentro del pod con la excepción de PersistentStorage. Comprobando el contenido del directorio. /data
en el pod recién creado:
kubectl exec -it alpine -- ls -la /data
Como puede ver, los archivos creados en el pod anterior permanecieron en el directorio /data
Se crea PersistentStorage, se conecta al clúster y funciona como se esperaba.
¡Felicitaciones por la finalización exitosa de su trabajo, colegas!