Nuestras manos no son para el aburrimiento: recuperación del clúster Rook en K8s

Nuestras manos no son para el aburrimiento: recuperación del clúster Rook en K8s

Nosotros ya hemos hablado, cómo/por qué nos gusta Rook: en gran medida facilita el trabajo con los almacenes en clústeres de Kubernetes. Sin embargo, con esta simplicidad también vienen ciertas complejidades. Esperamos que este nuevo material ayude a entender mejor estas complejidades aún antes de que se manifiesten.

Y para que la lectura sea más interesante, comenzaremos con las consecuencias de un problema hipotético en el clúster.

¡Todo está perdido!

Imaginen que un día configuraron y lanzaron Rook en su clúster K8s, y funcionó maravillosamente, pero en algún momento 'maravilloso' sucede lo siguiente:

  • Nuevos pods no pueden montar imágenes RBD desde Ceph.
  • Comandos como lsblk y df no se ejecutan en los nodos de Kubernetes. Esto significa automáticamente que 'algo no está bien' con las imágenes RBD montadas en los nodos. No se pueden leer, lo que indica que los monitores no están disponibles...
  • Sí, no hay monitores activos en el clúster. Además, no hay ni pods con OSD, ni pod MGR.

Cuando se lanzó el pod rook-ceph-operator? Не так давно, как его деплоили. Почему? Rook-operator решил сделать новый кластер… Как же нам теперь восстановить работу кластера и данные в нём?

Para empezar, tomaremos el camino más largo e interesante, realizando una investigación cuidadosa sobre las 'entrañas' de Rook y una recuperación paso a paso de sus componentes. Por supuesto, hay un camino más corto y correcto: usar copias de seguridad. Como sabemos, los administradores se dividen en dos tipos: aquellos que no hacen copias de seguridad y aquellos que ya las hacen... Pero sobre eso, después de la investigación.

Un poco de práctica, o El camino largo

Examinemos y recuperemos los monitores

Así que, veamos la lista de ConfigMaps: allí están los necesarios para la reserva rook-ceph-config y rook-config-override. Aparecen tras un despliegue exitoso del clúster.

NB: En las nuevas versiones, después de aceptar este PR, los ConfigMaps dejaron de ser un indicador de éxito en el despliegue del clúster.

Para realizar más acciones, es necesario un reinicio forzado de todos los servidores en los que hay imágenes RBD montadas (ls /dev/rbd*). Esto debe hacerse a través de sysrq (o 'a pie' en el centro de datos). Este requisito se debe a la tarea de desconectar las RBD montadas, para lo cual un reinicio normal no es suficiente (intentar desmontarlas de forma normal no funcionará).

El teatro comienza con el perchero, y un clúster Ceph comienza con los monitores. Vamos a observarlos.

Rook monta en el pod del monitor estas entidades:

Volúmenes:
 rook-ceph-config:
   Tipo:      ConfigMap (un volumen poblado por un ConfigMap)
   Nombre:      rook-ceph-config
 rook-ceph-mons-keyring:
   Tipo:        Secreto (un volumen poblado por un Secreto)
   NombreSecreto:  rook-ceph-mons-keyring
 rook-ceph-log:
   Tipo:          HostPath (volumen de directorio host)
   Ruta:          /var/lib/rook/kube-rook/log
 ceph-daemon-data:
   Tipo:          HostPath (volumen de directorio host)
   Ruta:          /var/lib/rook/mon-a/data
Montajes:
  /etc/ceph desde rook-ceph-config (ro)
  /etc/ceph/keyring-store/ desde rook-ceph-mons-keyring (ro)
  /var/lib/ceph/mon/ceph-a desde ceph-daemon-data (rw)
  /var/log/ceph desde rook-ceph-log (rw)

Veamos qué hay en el secreto rook-ceph-mons-keyring:

tipo: Secreto
datos:
 keyring: LongBase64EncodedString=

Decodificamos y obtenemos un keyring normal con permisos para el administrador y los monitores:

[mon.]
       key = AQAhT19dlUz0LhBBINv5M5G4YyBswyU43RsLxA==
       caps mon = "allow *"
[client.admin]
       key = AQAhT19d9MMEMRGG+wxIwDqWO1aZiZGcGlSMKp==
       caps mds = "allow *"
       caps mon = "allow *"
       caps osd = "allow *"
       caps mgr = "allow *"

Recordemos. Y ahora veamos el keyring en el secreto rook-ceph-admin-keyring:

tipo: Secreto
datos:
 keyring: anotherBase64EncodedString=

¿Qué hay en él?

[client.admin]
       key = AQAhT19d9MMEMRGG+wxIwDqWO1aZiZGcGlSMKp==
       caps mds = "allow *"
       caps mon = "allow *"
       caps osd = "allow *"
       caps mgr = "allow *"

El mismo. Veamos más… Por ejemplo, el secreto rook-ceph-mgr-a-keyring:

[mgr.a]
       key = AQBZR19dbVeaIhBBXFYyxGyusGf8x1bNQunuew==
       caps mon = "allow *"
       caps mds = "allow *"
       caps osd = "allow *"

Al final encontramos algunos secretos más en el ConfigMap rook-ceph-mon:

tipo: Secreto
datos:
 admin-secret: AQAhT19d9MMEMRGG+wxIwDqWO1aZiZGcGlSMKp==
 cluster-name: a3ViZS1yb29r
 fsid: ZmZiYjliZDMtODRkOS00ZDk1LTczNTItYWY4MzZhOGJkNDJhCg==
 mon-secret: AQAhT19dlUz0LhBBINv5M5G4YyBswyU43RsLxA==

Y esta es la lista original de keyrings, de donde provienen todos los secretos descritos anteriormente.

Como se sabe (ver dataDirHostPath en la documentación), Rook almacena tales datos en dos lugares. Por lo tanto, vayamos a los nodos para ver los keyrings que están en los directorios montados en los pods con monitores y OSD. Para ello, encontremos en los nodos /var/lib/rook/mon-a/data/keyring y veremos:

# cat /var/lib/rook/mon-a/data/keyring
[mon.]
       key = AXAbS19d8NNUXOBB+XyYwXqXI1asIzGcGlzMGg==
       caps mon = "allow *"

De repente aquí el secreto resultó ser diferente — no como en los ConfigMaps.

¿Y qué pasa con el keyring del administrador? También lo tenemos:

# cat /var/lib/rook/kube-rook/client.admin.keyring
[client.admin]
       key = AXAbR19d8GGSMUBN+FyYwEqGI1aZizGcJlHMLgx= 
       caps mds = "allow *"
       caps mon = "allow *"
       caps osd = "allow *"
       caps mgr = "allow *"

Aquí está el problema. Ha habido alguna falla: el clúster se recreó… pero en realidad no.

Se hace evidente que en los secretos se almacenan keyrings regenerados, y ellos no son de nuestro viejo clúster. Por lo tanto:

  • tomamos el keyring del monitor del archivo /var/lib/rook/mon-a/data/keyring (o de una copia de seguridad);
  • modificamos el keyring en el secreto rook-ceph-mons-keyring;
  • escribimos el keyring del administrador y del monitor en el ConfigMap rook-ceph-mon;
  • eliminamos los controladores de los pods con monitores.

El milagro no tardará en llegar: los monitores aparecerán y se iniciarán. ¡Hurra, hemos comenzado!

Restauraremos OSD

Entramos en el pod rook-operator: llamada ceph mon dump muestra que todos los monitores están en su lugar, y ceph -s — sobre lo que están en quórum. Sin embargo, si miramos el árbol OSD (ceph osd tree), veremos algo extraño: los OSD comenzaron a aparecer, pero están vacíos. Resulta que también necesitaremos restaurarlos de alguna manera. ¿Pero cómo?

Mientras tanto, en los ConfigMap han aparecido los que tanto necesitamos rook-ceph-config y rook-config-override, así como muchos otros ConfigMap con nombres del tipo rook-ceph-osd-$nodename-config. Veamos dentro de ellos:

kind: ConfigMap
data:
 osd-dirs: '{"/mnt/osd1":16,"/mnt/osd2":18}'

¡Todo está mal, todo está confundido!

Escalaremos a cero el pod del operador, eliminaremos los Deployments generados de los pods con OSD y corregiremos estos ConfigMap. Pero, ¿de dónde obtenemos el mapa correcto de OSD por nodos?

  • Intentemos nuevamente explorar los directorios /mnt/osd[1-2] en los nodos—con la esperanza de que podamos encontrar algo allí.
  • En el directorio /mnt/osd1 hay 2 subdirectorios: osd0 y osd16. El último, ¿es precisamente ese ID que se indica en el ConfigMap (16)?
  • Verificamos por tamaños y veremos que osd0 es mucho más grande osd16.

Llegamos a la conclusión de que osd0 — este es el OSD que se indicó como /mnt/osd1 en el ConfigMap (ya que estamos usando directory based osd.)

Paso a paso revisamos todos los nodos y corregimos los ConfigMap. Después de todas las indicaciones, podemos iniciar el pod del operador Rook y leer sus registros. Y en ellos, todo es maravilloso:

  • yo soy el operador del clúster;
  • encontré discos en los nodos;
  • encontré monitores;
  • los monitores se conectaron, es decir, formaron quórum;
  • iniciando los deployments de OSD…

Nuevamente, entraremos en el pod del operador Rook y verificaremos la vitalidad del clúster… sí, cometimos un pequeño error con las conclusiones sobre los nombres de los OSD en algunos nodos. No importa: nuevamente corregimos los ConfigMap, eliminamos los directorios sobrantes de los nuevos OSD y llegamos al estado tan esperado HEALTH_OK!

Verificamos las imágenes en el pool:

# rbd ls -p kube
pvc-9cfa2a98-b878-437e-8d57-acb26c7118fb
pvc-9fcc4308-0343-434c-a65f-9fd181ab103e
pvc-a6466fea-bded-4ac7-8935-7c347cff0d43
pvc-b284d098-f0fc-420c-8ef1-7d60e330af67
pvc-b6d02124-143d-4ce3-810f-3326cfa180ae
pvc-c0800871-0749-40ab-8545-b900b83eeee9
pvc-c274dbe9-1566-4a33-bada-aabeb4c76c32
…

Todo en su lugar: ¡el clúster está salvado!

Soy perezoso haciendo copias de seguridad, o La forma rápida

Si se hicieron copias de seguridad para Rook, el procedimiento de recuperación se vuelve significativamente más simple y se limita a lo siguiente:

  1. Escalamos a cero el deployment del operador Rook;
  2. Eliminamos todos los deployments, excepto el operador Rook;
  3. Restauramos de la copia de seguridad todos los secretos y ConfigMap;
  4. Restauramos el contenido de los directorios /var/lib/rook/mon-* en los nodos;
  5. Restauramos (si acaso se perdieron) las CRD CephCluster, CephFilesystem, CephBlockPool, CephNFS, CephObjectStore;
  6. Escalamos nuevamente el deployment del operador Rook a 1.

Consejos útiles

¡Haz copias de seguridad!

Y para evitar situaciones en las que se necesite restaurar desde ellas:

  1. Antes de realizar trabajos masivos con el clúster, que implican reinicios de servidores, escale a cero el operador Rook para que no haga cosas innecesarias.
  2. A los monitores anticipadamente agreguen nodeAffinity.
  3. Presten atención a la preparación configuración de timeouts ROOK_MON_HEALTHCHECK_INTERVAL y ROOK_MON_OUT_TIMEOUT.

En conclusión

No hay razón para discutir que Rook, siendo una capa adicional en el esquema general de organización de almacenamiento en Kubernetes, simplifica muchas cosas, pero también añade nuevas complejidades y problemas potenciales en la infraestructura. La decisión queda en hacer una elección ponderada y justificada entre estos riesgos por un lado y los beneficios que la solución aporta en su caso particular por el otro.

Por cierto, recientemente se añadió a la documentación de Rook una sección "Adoptar un cluster Rook Ceph existente en un nuevo cluster Kubernetes". En ella se detalla más específicamente qué se necesita hacer para migrar los datos existentes a un nuevo cluster de Kubernetes o para restaurar un cluster que se haya colapsado por alguna razón.

P.D.

También puedes leer en nuestro blog:

Fuente: habr.com

Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS 🔥 Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS | ProHoster