Conectando Cluster Externo CEPH w/Rook Operator en Kubernetes

squid-cover

Objetivo

Administrar un cluster Ceph externo a nuestro cluster de Kubernetes, utilizando Rook Operator y su csi-rbdplugin (RADOS)

Intro

En un cluster de Kubernetes los pods, o mejor dicho los contenedores dentro de nuestros pods, son stateless por definición, pero necesitamos almacenar y persistir información para disponibilizar a otros servicios/usuarios/APIs etc

La solución a este requerimiento es un objeto llamado Persistent Volume Claim o PVC, es lo que se recomienda en el mundo de Kubernetes para manejar aplicaciones stateful, con un PVC un pod puede pedir conectarse a storage (en forma de volúmenes) que existen, tienen un ciclo de vida y se gestionan de manera totalmente independiente al Pod que lo solicita.

Los PVC junto a las SC tienen la ventaja de desacoplar la complejidad de la implementación de storage de ciertas características y al mismo tiempo proveer una interface amigable para que el Dev team de cualquier compañía pueda consumir storage fácilmente, por ejemplo, los Cloud Engineers/SRE/Devops/Platform Engineers pueden aprovisionar volúmenes, y los developers pueden solicitar estos volúmenes y utilizarlos sin conocer detalles de la implementación de estos volúmenes y sus StorageClasses

Resumiendo PVC:

  • PVC: o PersistenVolumeClaim son solicitudes de almacenamiento por parte de un Pod, los PVC se montan en dichos pods y responden a una StorageClass.

  • PV: o PersistentVolume son los volúmenes propiamente dichos creados manualmente por los k8s admin o dinámicamente por un StorageClass asociado a un PVC.

  • StorageClass: son los objetos que tienen la configuración fina/detallada y agrupada de una clase de volumen específica, podemos crear varias, es común configurarlas por velocidad, así podemos tener una SC para volúmenes de alta velocidad de acceso y SC para realizar operaciones en donde no es necesario contar con alta velocidad de acceso de datos

Que es Ceph?

ceph

Ceph es un sistema de almacenamiento distribuido, escalable y de alto rendimiento sin SPOF (único punto de fallo), que significa todo esto? que es una muy buena opción a la hora de resolver el almacenamiento de aplicaciones stateful y además con HA (alta disponibilidad)

Ceph no es un solo objeto, es una familia de componentes:

  • Ceph Monitors (MON): son responsables de formar los QUÓRUM del Ceph cluster, todos los nodos del cluster informan y comparten información sobre sus cambios de estado.

  • Object Storage Daemon (OSD): son responsables de almacenar objetos en sistemas de archivo locales y proporcionar acceso a ellos a través de la red, por lo general un OSD está vinculado a un disco físico en el cluster; los Ceph Clients interactúan directamente con los OSD.

  • Ceph Manager (MGR): es el admin de todo, y a su vez nos ofrece soluciones de integración con otras tools de administración de storage.

  • RADOS: o Reliable Autonomic Distributed Object Store, es una solución de storage Open Source y es el núcleo de los clusters de almacenamiento Ceph, RADOS se asegura de que los datos almacenados sean consistentes, y también realiza replicación de datos, detección de errores, etc.

IMPORTANTE: para leer/escribir datos desde/hacia un Ceph cluster, un Ceph Client se debe comunicar en primer lugar con los MON de Ceph para obtener la copia más reciente del “clusterMap”, el cual contiene la topología del cluster, así como las ubicaciones de almacenamiento de datos, los CephClients utilizan el ClusterMap para determinar con qué OSD interactuar e iniciar una conexión

Que es Rook?

rook

Rook es un Operator que administra Ceph clusters por vos, hace que todo sea más sencillo, lo hace mediante la instalación de varios CRDs y un Controller custom para implementar y administrar recursos personalizados como por ejemplo un CephCluster (literalmente pueden hacer k get cephcluster) una maravilla del mundo mundial

al igual que Ceph, Rook es una familia de componentes:

  • Rook Operator: es el corazón de Rook, este operator es un pod simple de un solo contenedor que arranca automáticamente los clusters de storage y supervisa los daemons de storage para garantizar la salud de dichos clusters.

  • Rook Agents: se ejecutan en los nodos de almacenamiento y configura un plugin que se integra con el CSI de nuestro Kubernetes

  • Rook Discover: escucha conexiones de los clientes hacia los nodos del ceph cluster

Instalación y Configuración

Colectar Información en el Cluster CEPH externo

El objetivo es conectar a nuestro cluster de Kubernetes con un cluster Ceph externo, es por esto que primero necesitamos recolectar información del cluster Ceph que nos va a servir para establecer la conexión.

Una vez dentro de uno de los nodos Ceph vamos a correr este script, de la siguiente manera:

python3 create-external-cluster-resources.py --rbd-data-pool-name <my-pool> --format <bash> --namespace <ns>

  • rbd-data-pool-name: el nombre de nuestro pool Ceph
  • format: el formato de salida de nuestro script
  • namespace: el ns donde vamos a tener corriendo nuestro rook operator y el objeto cephcluster para administrar la conexión

Ejemplo de salida del script:

export NAMESPACE=ns
export ROOK_EXTERNAL_FSID=12345678-1111-2222-3333-5555566666
export ROOK_EXTERNAL_USERNAME=client.healthchecker
export ROOK_EXTERNAL_CEPH_MON_DATA=server=192.168.100.50:6789
export ROOK_EXTERNAL_USER_SECRET=jknwehnofuiyoiuewfqouiqouryouhuxeR36+A==
export CSI_RBD_NODE_SECRET=khqucqwtbybtybtyootceftbebtioetioM8/XKytDFe2A==
export CSI_RBD_NODE_SECRET_NAME=csi-rbd-node
export CSI_RBD_PROVISIONER_SECRET=hjknafbgcqbwebgyegbyrogeogoweiuglqweA7w==
export CSI_RBD_PROVISIONER_SECRET_NAME=csi-rbd-provisioner
export MONITORING_ENDPOINT=192.168.100.51
export MONITORING_ENDPOINT_PORT=9283
export RBD_POOL_NAME=mi-pool
export RGW_POOL_PREFIX=default

Instalar Rook en el Cluster de Kubernetes

Manifests Way

  1. Deployar Rook Commons

k apply -f common.yaml

  1. Deployar Rook Custom Resources

k apply -f crds.yaml

  1. Deployar Rook Operator

k apply -f operator.yaml

  1. Deployar Rook Common External

k apply -f common-external.yaml

  1. Deployar Rook Custer External

k apply -f cluster-external.yaml

Helm Way

Rook actualmente mantiene 2 charts, uno para la instalación del Rook Operator y otro con los CRDS, SC y demás objetos necesarios con los cuales el Operator va a interactuar dependiendo de lo que queramos hacer, ya que con Rook podemos deployar nuestro cluster Ceph dentro del cluster k8s o administrar uno pre-existente externo al cluster de k8s

  • Rook Ceph Operator:

      helm repo add rook-release https://charts.rook.io/release
      helm install --create-namespace --namespace rook-ceph rook-ceph rook-release/rook-ceph -f values.yaml
    
  • Rook Ceph Cluster:

      helm repo add rook-release https://charts.rook.io/release
      helm install --create-namespace --namespace rook-ceph rook-ceph-cluster \
         --set operatorNamespace=rook-ceph rook-release/rook-ceph-cluster -f values-override.yaml
    

IMPORTANTE: crear el values-override basados en el archivo values.yaml

Conectamos Kubernetes a un Cluster Ceph Externo

En este punto ya tendremos varios pods en estado running, incluyendo el rook operator, los plugins y provisioners de rbd y cephfs, además de un objeto llamado cephcluster, es decir podemos hacer algo como:

k get cephcluster

Y veremos un objeto cephcluster integrado a nuestra API k8s gracias a la magia de los CRD’s

En este punto lo veremos en estado desconectado, ahora el siguiente paso es sincronizar nuestro objeto k8s cephcluster con nuestro cluster real de Ceph que se encuentra fuera del cluster k8s, para ello vamos a setear todas las variables que nos arrojó el script en el cluster de Ceph y luego vamos a correr un script de import.

  1. Copiar y pegar el resultado del script que corrimos en el cluster externo Ceph
  2. Correr el script de import de Rook

. import-external-cluster.sh

  1. Ahora deberíamos ver nuestro cephcluster en k8s en estado conectado

     $ k -n rook-ceph-external  get CephCluster
     NAME                 DATADIRHOSTPATH   MONCOUNT   AGE    STATE       HEALTH
     rook-ceph-external   /var/lib/rook                162m   Connected   HEALTH_OK
    
  2. El script también creó un StorageClass para usarlo tanto para RBD (RADOS) o CEPHFS con sus nombres correspondientes

Probemos todo

squid-capitan

Creamos un PVC basado en el SC RBD (RADOS) que creó el script de import con el siguiente manifest:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: rbd-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
  storageClassName: ceph-rbd

Ahora creamos un Pod que consuma nuestro PVC creado anteriormente

apiVersion: v1
kind: Pod
metadata:
  name: csirbd-demo-pod
spec:
  containers:
    - name: web-server
      image: nginx
      volumeMounts:
        - name: mypvc
          mountPath: /var/lib/www/html
  volumes:
    - name: mypvc
      persistentVolumeClaim:
        claimName: rbd-pvc
        readOnly: false

Veremos como el PVC crea un PV de forma dinámica utilizando el SC especificado

También podemos ahorrarnos la creación del pvc por separado y probar con un Pod efimero:

kind: Pod
apiVersion: v1
metadata:
  name: csi-rbd-demo-ephemeral-pod
spec:
  containers:
    - name: web-server
      image: docker.io/library/nginx:latest
      volumeMounts:
        - mountPath: "/myspace"
          name: mypvc
  volumes:
    - name: mypvc
      ephemeral:
        volumeClaimTemplate:
          spec:
            accessModes: ["ReadWriteOnce"]
            storageClassName: "ceph-rbd"
            resources:
              requests:
                storage: 1Gi

Este manifest va a crear un PVC usando el nombre del Pod con la diferencia que dicho PVC tendrá el mismo ciclo de vida que el Pod.

Fuente

Material Extra: Curso “Devops en 5 Pasos” Disponible en Udemy

Temas:

  • Docker
  • Kubernetes
  • MultiCloud (AWS - Azure - GCP)
  • IaC (Terraform, Cloud Formation, ARM Templates, Cloud Resource Manager)
  • CI/CD Pipelines (GitlabCI, Azure Devops, CircleCI)

Descripción completa: Detalle y enlaces del curso

Invitame un CaféInvitame un Café