Cómo reparar un Placement Group (pg) en un sistema de almacenamiento hiperconvergente con Ceph, sobre virtualización Proxmox.

Error pg inconsistente en Ceph de Proxmox

En un sistema de virtualización Proxmox en clúster, si uno o varios pg (Placement Group) del sistema de almacenamiento hiperconvergente Ceph muestra este error:

HEALTH_ERR: Possible data damage: 1 pg inconsistent
pg 2.11 is active+remapped+inconsistent+backfill_wait, acting [8,1,3]

El sistema de almacenamiento está indicando que tiene uno o varios errores en uno o varios PG.

Un PG es una unidad lógica de agrupación de objetos dentro de un pool de Ceph. Es como una «carpeta virtual» que contiene múltiples objetos y determina en qué OSD (Object Storage Daemon) se almacenarán esos objetos. A su vez, un OSD es el daemon/proceso de Ceph que almacena los datos en cada disco del clúster. Cada OSD corresponde típicamente a:

  • 1 unidad de almacenamiento independiente.
  • 1 disco físico (HDD o SSD).
  • 1 proceso del sistema operativo.

Haciendo una analogía con una biblioteca distribuida (varias bibliotecas del mismo formato distribuidas en una ciudad), para entender el concepto de Objetos, OSD y PG de Ceph:

  • Objetos: los libros específicos.
  • Cluster Ceph: la red de bibliotecas de una ciudad.
  • OSD: cada biblioteca individual.
  • PG: una sección temática que existe en múltiples bibliotecas.

En nuestro caso, y en cualquier caso, un PG se almacena en múltiples OSD:
PG 2.11 → [OSD.8, OSD.1, OSD.5] # 3 réplicas
PG 2.12 → [OSD.3, OSD.7, OSD.2] # 3 réplicas

Y un OSD almacena múltiples PG:
OSD.8 → [PG 2.11, PG 1.5, PG 3.2, …] # Decenas o cientos de PGs

Para obtener todos los pg (Placement Group) del clúster Ceph, así como los posibles avisos o errores, ejecutaremos el comando (desde el shell de cualquier nodo del clúster Proxmox):

ceph health detail

En este caso, al principio del comando, devuelve el error del pg 2.11:

HEALTH_ERR 1 scrub errors; Possible data damage: 1 pg inconsistent; 28 pgs not deep-scrubbed in time; 28 pgs not scrubbed in time
[ERR] OSD_SCRUB_ERRORS: 1 scrub errors
[ERR] PG_DAMAGED: Possible data damage: 1 pg inconsistent
pg 2.11 is active+remapped+inconsistent+backfill_wait, acting [8,1,3]

Si queremos obtener todos los datos del pg 2.11 (el que tenemos averiado), ejecutaremos el comando:

ceph pg 2.11 query

Devolverá un JSON extenso con toda la información del pg. Puede descargarse desde el siguiente enlace un JSON de ejemplo real de un pg con inconsistencias/errores:

Reparar pg (Placement Group) en Ceph sobre Proxmox

En primer lugar, haremos un deep-scrub del pg 2.11, lo que hace un deep-scrub:

  1. Lectura completa de datos: lee todos los objetos en el PG indicado byte por byte
  2. Verificación de checksums: calcula checksums SHA1 de cada objeto y los compara con los checksums almacenados.
  3. Comparación entre réplicas: compara los datos y checksums entre todas las réplicas del PG (en los OSD a los que corresponda).
  4. Detección de corrupción: identifica si hay:
    • Datos corruptos en disco.
    • Inconsistencias entre réplicas.
    • Checksums que no coinciden.
  5. Registro de inconsistencias: si encuentra problemas, los registra en los logs y marca el PG como «inconsistent».

Para realizar el deep-scrub en el pg 2.11, ejecutaremos el comando:

ceph pg deep-scrub 2.11

Este comando, lanzará el deep-scrub en segundo plano, nos devolverá el OSD al que pertenece el pg:

instructing pg 2.11 on osd.8 to deep-scrub

Si queremos consultar el estado de la reparación, ejecutaremos el comando:

ceph -w

Esperaremos a que finalice el deep-scrub, en el comando anterior, mientras muestre esta línea:

1 active+clean+scrubbing+deep+inconsistent

Indica que el deep-scrub aún no ha finalizado, hay que esperar a que indique alguno de estos estados:

active+clean+inconsistent

O bien:

active+clean

También podremos consultar el estado específico del pg 2.11 con el comando:

ceph pg 2.11 query | grep statete

Mientras devuelva el estado:

    "state": "active+clean+scrubbing+deep+inconsistent",
            "state": "active+clean+scrubbing+deep+inconsistent",
                "state": "active+remapped+inconsistent+backfilling",
                "state": "active+remapped+inconsistent+backfilling",
    "recovery_state": [
    "agent_state": {}

Indica que el proceso deep-scrub aún está activo, hay que esperar a que el estado cambie a:

«state»: «active+clean+inconsistent»

O bien a:

«state»: «active+clean+inconsistent»

Si lo anterior no repara el pg, tras finalizar el deep-scrub, podremos realizar otras acciones más específicas. Por ejemplo, listar los posibles objetos «unfound» en el pg averiado, con el comando:

ceph pg 2.11 list_unfound

Si devuelve algo así:

{
    "num_missing": 0,
    "num_unfound": 0,
    "objects": [],
    "state": "Active",
    "available_might_have_unfound": true,
    "might_have_unfound": [],
    "more": false
}

Es buena señal, porque no hay objetos «unfound». En este caso, podremos forzar una reparación del pg 2.11 con el comando:

ceph pg repair 2.11

Comprobar estado del clúster Ceph, de los pg y de los OSD

Para ver el estado de la reparación, ejecutaremos el comando:

ceph pg 2.11 query | grep state

Nos devolverá un JSON indicando si aún está reparándose el pg:

    "state": "active+clean+inconsistent",
            "state": "active+clean+inconsistent+repair",
                "state": "active+remapped+inconsistent+backfilling",
                "state": "active+remapped+inconsistent+backfilling",
    "recovery_state": [
    "agent_state": {}

En cuanto finalice la reparación, revisaremos el estado de nuevo:

El siguiente comando:

ceph health detail

Si todos los pg están OK, devolverá:

HEALTH_OK

Y el comando:

ceph status

Devolverá:

  cluster:
    id:     878fda0c-1988-4695-9788-ba4e801ef432
    health: HEALTH_OK

  services:
    mon: 3 daemons, quorum proxmox,proxmox2,proxmox3 (age 4h)
    mgr: proxmox2(active, since 4h)
    osd: 12 osds: 12 up (since 4h), 12 in (since 4h)

  data:
    pools:   2 pools, 33 pgs
    objects: 84.39k objects, 327 GiB
    usage:   940 GiB used, 11 TiB / 12 TiB avail
    pgs:     33 active+clean

  io:
    client:   7.0 KiB/s wr, 0 op/s rd, 0 op/s wr

Otro comando para ver los OSD y sus pg:

ceph osd tree

En el modo gráfico, en «Datacenter» – «Ceph», aparecerá «HEALTH_OK»: