En la jaula de un geek

Los README son para los cobardes. Sé valiente. Ejecuta el programa.

«

»

Nov 27

Kubernetes con volumen GlusterFS (Centos 8)

Kubernetes tiene varias opciones para crear volúmenes, en otro artículo ya expliqué cómo utilizar NFS, ahora le toca a algo más profesional: GlusterFS.

GlusterFS es un sistema de réplica de datos, similar a crear una RAID a nivel de software, aunque tiene algunos extras, como la capacidad de hacer snapshots o la georeplicación. En caso de Kubernetes, únicamente nos interesa su capacidad para crear réplicas de los datos y compartirlas, similar a una carpeta compartida.

Debo avisar que GlusterFS es realmente grande y Kubernetes no está configurado «por defecto» para utilizarlo (requiere un intermediario: Heketi), así que su configuración es bastante compleja, y además hará falta obtener conocimientos de GlusterFS para gestionarlo manualmente si fuera necesario.

Explicación

Kubernetes es capaz de conectar con servicios externos siempre y cuando estos dispongan de un servicio REST, GlusterFS no dispone de estos, funciona por comandos para gestionar todo, y desde cualquier nodo se puede gestionar al resto.

Por otro lado, tenemos Heketi, que genera una capa por encima de GlusterFS, conecta con cada uno de los nodos para darles ordenes, aun así, Heketi tiene varios problemas:

  • Requiere desplegar un servicio REST, si este servicio falla, ya no se tiene acceso a la gestión del GlusterFS, así que es recomendable tener un clúster de este servicio
  • GlusterFS funciona creando volúmenes, los volúmenes creados manualmente, fuera de Heketi, no pueden ser configurados desde este
  • Heketi requiere una base de datos donde almacenar su información, lo que acaba siendo un problema, queremos solucionar el problema de no perder datos de volúmenes y este acaba teniendo ese mismo problema
  • Existe un proyecto con GlusterFS y Heketi para Kubernetes, que permite desplegar GlusterFS en todos los nodos de Kubernetes, despliega Heketi en clúster dentro del Kubernetes y se encarga de todo, genial ¿verdad? Pues no funciona tan bien como parece.

GlusterFS se recomienda desplegar con al menos 3 nodos, aunque todos se despliegan de la misma forma, con lo que explicaré uno y simplemente habrá que replicar los mismos pasos. En mi caso utilizaré los mismos nodos de Kubernetes como nodos de GlusterFS, aunque estos pasos se pueden utilizar para desplegar el GlusterFS sobre otros servidores.

Utilizaré el Kubernetes desplegado sobre CentOS 8 explicado anteriormente. Sea como sea, todos los nodos deben ser capaces de resolver su nombre, ya sea por tenerlos en un DNS o por añadirlos en el fichero /etc/hosts.

1- Preparar los nodos de GlusterFS

Cada nodo necesita un disco duro sin formatear que será el utilizado por este servicio, en mi caso será he asociado un nuevo disco duro a cada nodo que está en /dev/sdb

El script generado por el proyecto es capaz de desplegar GlusterFS en cada nodo de Kubernetes, pero en mi caso dio muchos errores, además, prefiero hacer este despliegue manualmente para tener un mejor control sobre él.

Por defecto, CentOS dispone de una versión vieja, así que habrá que activar la release propia para acceder a la última versión.

Instalamos y preparamos en cada nodo.

Abrimos los puertos necesarios para la comunicación de GlusterFS y de Heketi además de activar los componentes que estos necesitan.

A partir de aquí, ya tenemos el servicio preparado, desde cualquier nodo incluiremos al resto y comprobaremos que esté funcionando.

Esto nos mostrará todos los nodos asociados.

Esto nos deja los nodos funcionando, este servicio necesita además configurar un volumen para cada proyecto, pero le dejaremos este trabajo a Heketi.

2- Preparando el master de Kubernetes

Antes de empezar: este y los siguientes puntos empiezan a tener bastante complejidad, en algunos casos, un error nos hará eliminar manualmente varios procesos, y no tiene porqué ser fácil (puede requerir conocimientos de GlusterFS o de particiones de Linux), si disponemos de la opción de crear snapshots, será mejor utilizarlos.

El despliegue de Heketi y su preparación se puede hacer desde uno de los scripts del proyecto original, este requiere Git para descargarlo (podemos descargarlo a mano, pero es conveniente tener Git en un master de Kubernetes para poder guardar nuestros ficheros de configuración para cada despliegue) y también python, que el script utilizará para recuperar la lista de nodos.

CentOS nos creará la opción de python3 y python38, pero el script requiere tener «python», así que creamos un enlace blando para tenerlo disponible, ya que este problema es bastante típico y nos podrá surgir a futuro.

Ahora tendremos que descargar el proyecto, pero la versión al escribir este artículo, es únicamente compatible con Kubernetes 1.6, debido a versiones que han desaparecido. En un pull request lo han solucionado para 1.8 (hay otro para 1.7), sí que utilizaré ese para ahorrarme toda la faena.

Lo primero es preparar la topología de nuestro GlusterFS.

En este fichero indicamos el nombre del nodo según Kubernetes (kubectl get nodes) en «manage», la IP (NO funciona con nombres de dominio) en «storage» y los discos para Gluster (en mi caso solo tengo /dev/sdb) en «devices».

También necesitamos que el master sea capaz de acceder al resto de nodos por SSH sin contraseña, para ello generamos unas claves (nos preguntará la contraseña, dejarla en blanco) y las enviamos a cada nodo.

Crearemos un namespace para que todo lo relacionado con Heketi y GlusterFS quede separado del resto.

Y terminamos con un pequeño detalle, al crear el PersistentVolume, tendremos que indicar una URL que el master debe ser capaz de resolver fuera de Kubernetes, por si mismo, así que o publicamos este REST a través de Ingress o similar, o utilizamos el nombre interno que genera Kubernetes para acceder a los deployments (<service>.<namespace>.svc.cluster.local), este último es el más práctico pero no es accesible por defecto, así que habrá que modificarlo.

Añadimos la siguiente línea encima de «hostNetwork: true», nos quedará así:

Reiniciamos el kubelet para aplicar este cambio.

Debo avisar que este cambio permite a los servicios como un PersistentVolume utilizar los DNS internos de Kubernetes, pero nuestro servidor seguirá sin poderlos utilizar.

3- Desplegar Heketi

Ya tenemos todo lo necesario para desplegar Heketi, crear un volumen de GlusterFS donde almacenar su base de datos y hacer que Heketi se despliegue totalmente en Kubernetes utilizando ese volumen, todo esto se puede hacer con el script que viene en el proyecto descargado por Git.

Cambiar los user-key y admin-key por vuestra contraseña.

Antes de ejecutarlo, este proceso es muy complejo de revertir, es el momento ideal para un snapshot.

Si todo ha ido bien, al terminar nos mostrará los pasos a seguir, aunque en la versión actual los logs son algo ilegibles, pero encontraremos algo como:

Podemos confirmar el funcionamiento con la web de hello de Heketi.

Y ver todo lo desplegado en el nuevo namespace.

Este es mi resultado.

Si todo es correcto, ¡genial! no es nada fácil llegar a hacerlo funcionar (en serio, no lo es …), pero aún no hemos acabado.

Tal como indica, se necesita tener el heketi-cli o utilizar el contenedor como intermediario, para tener más facilidad yo prefiero descargarlo y así tenerlo más a mano.

Actualmente tenemos 2 opciones, o descargar únicamente el cliente, o tener todo el paquete con ejemplos, estos comandos descargan ambos para que cada cuál pueda elegir, si alguno no te interesa, siempre lo puedes borrar.

Ahora ya tendremos acceso al cliente de heketi, podemos confirmarlo.

Cada comando que utilicemos habrá que pasarle la URL, usuario y contraseña, pero podemos declarar las variables (se pierden al cerrar la sesión, aunque podemos definirlas de otras formas para mantenerlas u ocultar mejor la contraseña).

Ya podremos conectar, estos son algunos de los comandos y respuestas típicas.

Resultado:

Información del clúster.

Resultado:

Información de nodos.

Resultado:

Topología.

Quizás el más importante sea la lista de volúmenes.

Resultado:

También podemos utilizar los comandos desde el contenedor.

4- Añadir servicio

Necesitamos definir un StorageClass que hará de base, todos los PersistentVolumeClaim irán asociados a él, en mi caso le asociaré un secret a la contraseña, si indicáramos la contraseña visible como otro parámetro podríamos unificar el storageclass dentro del namespace de glusterfs y reutilizarlo en todos los sitios, pero con un secret de por medio únicamente he logrado errores, así que en cada namespace se generará el storageclass y su secret, en mi caso lo dejaré en default.

Definimos el gluster-storageclass.yaml.

Para utilizar esto necesitamos crea un secret, primero prepararemos la contraseña.

Que utilizaremos para crear el secret, heketi-secret.yaml.

Con esto ya podemos definirlo dentro del namespace de glusterfs.

Podemos confirmar que se ha creado.

Resultado:

5- Desplegar Nginx en GlusterFS

Ya podemos crear un PersistentVolumeClaim (PVC) para que lo utilice Nginx, gluster-pvc-nginx.yaml.

Al crear el PVC, se genera el volumen con Heketi, así que lo crearemos y confirmamos que todo funcione antes de utilizarlo.

El PVC contendrá el volumen de GlusterFS y será el que utilizaremos para Nginx.

Resultado:

Si ha funcionado, también nos habrá creado el PV.

Resultado:

Ahora ya podemos desplegar el Nginx, nginx-deployment.yaml.

Desplegamos y revisamos que los pods se desplieguen.

6- Test y gestión de Heketi/GlusterFS

Con Nginx ejecutado sobre un nuevo volumen de GlusterFS, queda hacer las pruebas y entender cómo gestionar todo esto.

Podemos mostrar la lista de volúmenes de Heketi.

Nos mostrará el volumen con la base de datos de Heketi y el nuevo.

Perfecto, tenemos el identificador de Heketi, el name corresponde a su mismo valor en GlusterFS, pero ¿qué pasa cuando tengamos 5? No hay forma de saber qué volumen de Kubernetes corresponde a cuál en GlusterFS. Para resolver esto primero hay que entender un poco más de cómo funciona todo esto.

Al crear un PVC, este llama a Heketi para crear un nuevo volumen y que él se encargue de crearlo en los nodos de GlusterFS, Heketi genera un Id para el nuevo volumen y lo devuelve, él no almacena nada externo, para solucionar esto, el PV creado por el PVC sí que almacena el identificador de Heketi (que además necesitará si, por ejemplo, quisiéramos hacer modificaciones del volumen), debido a que es un dato especial, con un get no podemos extraerlo, pero se puede conseguir con una template.

Este nos devuelve el Id del volumen de Kubernetes, el nombre de nuestro PVC y el nombre del volumen en GlusterFS.

Con esto podemos ir a uno de los nodos y mirar el listado de volúmenes.

Ahora sí, podemos identificar el volumen real.

Y, con ello, extraer toda la información del volumen.

Por defecto todos los volúmenes son Replica 3, y podemos ver en qué rutas está exactamente.

Ya tenemos lo suficiente para hacer pruebas, así que accedemos a uno de los pods, mirando en qué nodo está, y nos vamos a un nodo diferente para acceder a su ruta de montaje para crear y listar ficheros desde nodos diferentes y confirmar que la réplica está funcionando.

Aquí creamos un fichero nuevo y comprobamos que nos aparece.

Si desde un nodo vamos a la ruta que nos indica el volumen y mostramos los ficheros, encontraremos el index.html

Si seguimos probando, veremos que podemos crear un fichero en el nodo y este será mostrado por Nginx, aun así, debo advertir que las réplicas no son inmediatas, y, curiosamente, habrá veces que curl sea capaz de mostrar ficheros que con ls aun no vemos.

7- Borrar volumenes

Cuando borramos un PVC, este borrará el PV, pero no borrará ni el volumen en Heketi ni en GlusterFS, y debido a que la asociación con estas particiones es dinámica, cuando creamos un nuevo PVC, este creará un nuevo volumen en vez de reutilizar uno anterior, así que ojo con ello, ya que con esta configuración nunca podremos reenganchar con un volumen ya creado si perdemos su PVC.

Por esta misma regla, debido a que utilizamos el PV para identificar qué volumen de Kubernetes corresponde a qué volumen en GlusterFS, si lo borramos sin mirar antes la correspondencia, nos será más difícil de encontrar el volumen a borrar.

También hay que tener en cuenta, que la gestión de volúmenes se hace desde Heketi, si borramos un volumen directamente en GlusterFS, Heketi no lo sabrá y nos dará información errónea.

Borrar requiere un orden, primero debemos utilizar el comando explicado previamente para obtener los Ids de los volúmenes a cada lado.

De este podemos extraer la siguiente información:

  • name=pvc-e92993a2-5c38-4290-972d-e0fd55e0190f: Nombre del PV a borrar, si reemplazamos «pvc-» por «glusterfs-dynamic-«, obtendremos el service a borrar
  • claimName=gluster-nginx: Nombre del PVC a borrar
  • heketiName=vol_859c773486f43186c95f35e67aab16f3: Si eliminamos el «vol_», obtenemos el Id necesario para borrar el volumen

Con estos datos procedemos a borrar toda la información del volumen en todos los lugares.

La destrucción del volumen en Heketi, también destruirá los datos en GlusterFS, así que cuidado con ello.

Final

Llegar hasta aquí no es nada fácil, y mucho me temo que en próximas versiones, algunos de estos pasos pueden dejar de funcionar como ha ido pasando en cada versión de Kubernetes.

También, el despliegue de Heketi dentro de Kubernetes nos hace la vida mucho más sencillo, pudiendo crear automáticamente PVC y que estos se encarguen de todo, si utilizaramos GlusterFS y lo compartiéramos con otros métodos, nos obligaría a tener que crear manualmente los volúmenes, o a utilizar los comandos de Heketi para hacerlo manualmente, esto no es algo malo, simplemente es más lento y puede entorpecer a algunos sistemas, sobretodo a aquellos más automatizados, es nuestra elección decidir qué preferimos.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Puedes usar las siguientes etiquetas y atributos HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">

Si continuas utilizando este sitio aceptas el uso de cookies. más información

Los ajustes de cookies de esta web están configurados para "permitir cookies" y así ofrecerte la mejor experiencia de navegación posible. Si sigues utilizando esta web sin cambiar tus ajustes de cookies o haces clic en "Aceptar" estarás dando tu consentimiento a esto.

Cerrar