Ceph hiperconvergido en Proxmox VE

Por: Artiko
proxmoxproxmox-vecephrbdcephfsosdcrushhcisysadminalmacenamiento

Ceph hiperconvergido en Proxmox VE

En el capítulo 11 montaste el cluster, entendiste el quorum y activaste HA. Ahí apareció un requisito que no se puede esquivar: para que ha-manager reinicie una VM en otro nodo, el disco de esa VM tiene que estar accesible desde el nodo que la recoge. Con storage local no hay HA real, solo replicación asíncrona con una ventana de pérdida de datos.

La respuesta clásica es una cabina externa por NFS o iSCSI. Funciona, pero mete en la ecuación un equipo más, con su propia fuente de alimentación, su propia controladora y su propio riesgo de ser un punto único de fallo. La respuesta hiperconvergida es distinta: los mismos tres nodos que ejecutan las VMs también forman un cluster de almacenamiento distribuido, replicado y auto-reparable. Eso es Ceph dentro de Proxmox VE, y pveceph es la herramienta que lo despliega sin salir del hipervisor.

Al terminar este capítulo tendrás un cluster Ceph de tres nodos con monitores en quorum, OSDs repartidos, un pool RBD replicado montado como storage de VMs y contenedores, un CephFS para ISOs y plantillas, y — más importante — sabrás leer ceph -s cuando el cluster te avise de que algo va mal a las tres de la mañana.

La referencia de este capítulo es Proxmox VE 9.2 sobre Debian 13 Trixie, con Ceph Tentacle 20.2.1 como versión por defecto para instalaciones nuevas y Ceph Squid 19.2.3 todavía disponible.

Qué es hiperconvergido y qué daemons lo forman

Un despliegue hiperconvergido (HCI) significa que cómputo y almacenamiento comparten los mismos servidores. En Proxmox VE eso se traduce en que, sobre los nodos del cluster que ya tienes, instalas los daemons de Ceph y les entregas discos crudos. No hay cabina, no hay servidor de storage separado: cada nodo aporta capacidad y consume capacidad.

Ceph se compone de cuatro tipos de daemon, y cada uno hace exactamente una cosa:

DaemonProcesoFunción¿Obligatorio?
Ceph Monitorceph-monMantiene la copia maestra del cluster map: quién existe, quién está vivo, cómo se distribuyen los datosSí, y en número impar
Ceph Managerceph-mgrInterfaz de monitorización y módulos como el PG-autoscaling, el device health monitoring y la telemetríaSí, requerido desde Luminous
Ceph Metadata Serverceph-mdsMetadatos del sistema de ficheros POSIXSolo si usas CephFS
Ceph OSDceph-osdAlmacena los objetos. Uno por disco físicoSí, muchos

El MGR merece un matiz. La documentación lo describe así: no es una dependencia dura del cluster, pero “it is crucial for a Ceph cluster, as it handles important features like PG-autoscaling, device health monitoring, telemetry and more”. Un cluster sin MGR arranca; un cluster sin MGR se queda ciego y sin autoscaler.

El OSD es donde vive el dato de verdad. La regla de uno por disco físico es literal: si un nodo tiene cuatro SSD dedicados a Ceph, ese nodo ejecuta cuatro procesos ceph-osd. El backend de almacenamiento es BlueStore, el default desde Luminous; Filestore ya no se puede crear con pveceph desde Nautilus.

flowchart TD
    subgraph N1["Nodo pve1"]
        M1["MON + MGR activo"]
        D1["MDS activo"]
        O1["OSD.0 y OSD.1"]
    end
    subgraph N2["Nodo pve2"]
        M2["MON + MGR standby"]
        D2["MDS standby"]
        O3["OSD.2 y OSD.3"]
    end
    subgraph N3["Nodo pve3"]
        M3["MON"]
        O5["OSD.4 y OSD.5"]
    end
    M1 -. quorum .- M2
    M2 -. quorum .- M3
    M3 -. quorum .- M1
    RBD["Pool RBD replicado size=3 min_size=2"] --> O1
    RBD --> O3
    RBD --> O5
    CFS["CephFS: cephfs_data + cephfs_metadata"] --> D1
    CFS --> O1
    CFS --> O3
    CFS --> O5

Fíjate en un detalle del diagrama: los MON forman su propio quorum, independiente del de corosync. Son dos consensos distintos corriendo sobre la misma máquina, y si uno se rompe el otro no lo arregla.

Las dos redes de Ceph y el riesgo real para el quorum de corosync

Ceph define dos redes lógicas, y entender la diferencia separa un cluster que aguanta de uno que se cae solo durante un recovery.

RedQué transportaObligatoria
Public NetworkTráfico de storage entre clientes (VMs con RBD, montajes CephFS) y los servicios Ceph, y entre los propios servicios
Cluster NetworkReplicación entre OSDs, heartbeat y recoveryNo, pero muy recomendada

La Public Network es por donde una VM pide un bloque y el OSD se lo entrega. La Cluster Network es por donde los OSDs se copian datos entre sí cuando escribes con size=3, cuando muere un disco y hay que reconstruir, o cuando añades un nodo y el cluster rebalancea. El segundo tipo de tráfico es enormemente más agresivo que el primero: durante un recovery, la Cluster Network va a intentar mover terabytes tan rápido como el hardware se lo permita.

Advertencia: este es el gotcha que más clusters ha tumbado. La documentación oficial lo dice sin rodeos: “The volume of traffic, especially during recovery, will interfere with other services on the same network, especially the latency sensitive Proxmox VE corosync cluster stack can be affected, resulting in possible loss of cluster quorum”. Traducido: si pones corosync y Ceph en la misma NIC, el día que muera un disco Ceph saturará el enlace, corosync empezará a perder heartbeats, el cluster perderá quorum, los nodos con HA activo se autoexpulsarán por watchdog y te quedarás sin VMs por un fallo de un solo disco. Corosync no necesita ancho de banda — con 1 Gbit sobra — necesita latencia baja y consistente, por debajo de 5 milisegundos, y la recomendación oficial de cluster es una NIC física dedicada solo para él.

El diseño de referencia usa tres redes físicas separadas:

flowchart LR
    VM["VMs con disco RBD"] --> P
    CT["Contenedores LXC"] --> P
    ISO["Montajes CephFS"] --> P
    P["Public Network 10+ Gbps<br/>trafico cliente a servicio"] --> MONS["MON y MGR"]
    P --> OSDS["OSDs"]
    OSDS --> C["Cluster Network 25+ Gbps<br/>replicacion heartbeat y recovery"]
    C --> OSDS
    NODES["Nodos pve1 pve2 pve3"] --> K["Red corosync 1 Gbps dedicada<br/>quorum del cluster Proxmox VE"]

Números concretos verificados:

Uno. Mínimo 10 Gbps dedicados para Ceph. Por debajo de eso el recovery es doloroso y la latencia de escritura sube.

Dos. Setup de alto rendimiento: 25+ Gbps para el tráfico interno de Ceph, 10+ Gbps para el público (y opcionalmente para guests y live-migration), 1 Gbps exclusiva para corosync.

Tres. Un solo NVMe moderno puede saturar 10 Gbps él solo. Si montas un pool all-NVMe y le pones un enlace de 10 Gbps, la red es el cuello de botella; para exprimir los discos hacen falta 25, 40 o más.

Cuatro. Con tres a cinco nodos y sin switches de 10+ Gbps, una red mesh (nodos conectados directamente entre sí) es una alternativa viable para la red de Ceph. Las Fabrics de SDN que viste en el capítulo 9 con OpenFabric u OSPF automatizan el routing de ese mesh.

Si tienes el firewall activo — lo cubriste en el capítulo 10 — hay que abrir los puertos de Ceph. Lo más simple es usar la macro predefinida Ceph, que cubre tcp/6789, tcp/3300 y el rango tcp/6800:7300:

IN Ceph(ACCEPT) -source 10.55.10.0/24

Hardware mínimo realista

Aquí no hay atajos, y las cifras oficiales son bastante exigentes.

Nodos. Texto literal: “you must use at least three (preferably) identical servers”. Y la recomendación completa: “We recommend a Ceph cluster with at least three nodes and at least 12 OSDs, evenly distributed among the nodes”. Tres nodos, cuatro OSDs cada uno.

CPU. Los daemons intensivos son OSD y MDS; se benefician de frecuencia base alta y muchos núcleos. MON y MGR son de uso moderado. La regla práctica es al menos un core (o hilo) por servicio Ceph. El ejemplo oficial: “if you plan to run a Ceph monitor, a Ceph manager and 6 Ceph OSDs services on a node you should reserve 8 CPU cores purely for Ceph”. Con NVMe empresariales que sostienen más de 100.000 IOPS, sube a 4-6 hilos por OSD.

Memoria. “The current recommendation is to configure OSDs with at least 8 GiB of memory for good performance. The OSD daemon requires 4 GiB by default”. El consumo total lo determina principalmente el número de OSDs, pero en operaciones críticas todos los servicios pueden pedir más. Deja margen: recovery, rebalance y backfill consumen por encima de lo habitual. Regla de dimensionamiento del propio Proxmox: para Ceph y ZFS, suma aproximadamente 1 GB de RAM por cada TB de almacenamiento usado. Para subir el objetivo de memoria de los OSD a los 8 GiB recomendados:

ceph config set osd osd_memory_target 8G

Discos. En setups pequeños, SSD antes que HDD: reduce drásticamente el tiempo de recovery. Y una recomendación que se ignora demasiado: “Ceph performs best with an evenly sized, and an evenly distributed amount of disks per node. For example, 4 x 500 GB disks within each node is better than a mixed setup with a single 1 TB and three 250 GB disk”. Un disco mucho más grande que sus vecinos recibe más PGs, se convierte en el más lleno y es el que dispara el OSD_NEARFULL. También hay que equilibrar número de OSDs frente a capacidad por OSD: más capacidad por disco es más densidad, pero también más datos que reconstruir cuando ese disco muere. Y si aceleras los OSDs con un disco rápido para DB/WAL, cuida la ratio: un solo NVMe sirviendo la DB de diez OSDs se convierte en el cuello de botella de los diez.

RAID: no. Warning literal de la documentación: “Avoid RAID controllers. Use host bus adapter (HBA) instead”. Ceph ya hace la redundancia a nivel de objeto y necesita ver el disco físico tal cual, con su SMART y su comportamiento real de latencia. Una controladora RAID por encima le esconde todo eso y le añade una caché que puede mentirle sobre las escrituras. Lo mismo aplica a ZFS, como viste en el capítulo 8. Y se recomiendan SSD con Power-Loss-Protection; el SSD de consumo está explícitamente desaconsejado.

Instalación: pveceph install y pveceph init

El despliegue son dos comandos, pero se ejecutan en sitios distintos y eso importa. pveceph install instala los paquetes y se ejecuta en cada nodo que vaya a participar. pveceph init escribe la configuración inicial y se ejecuta una sola vez, en un nodo, porque el resultado se replica solo por pmxcfs.

# En CADA nodo del cluster
pveceph install

# Variante explícita: versión y repositorio concretos
pveceph install --version tentacle --repository no-subscription

Opciones exactas de pveceph install:

OpciónValoresDefault
--versionsquid o tentacletentacle en PVE 9.2
--repositoryenterprise, manual, no-subscription, testenterprise
--allow-experimental0 o 10. “Use with care”

El comando “sets up an apt package repository in /etc/apt/sources.list.d/ceph.sources. El valor manual de --repository no configura ningún repositorio: lo dejas tú a mano. En PVE 9.2, al instalar una release experimental, pveceph avisa si está seleccionado el repo enterprise y propone cambiar al de test.

Las releases disponibles y su EOL estimado:

ReleaseEOL estimadoenterpriseno-subscriptiontest
ceph-tentacle (v20.2)2027-11recomendadodisponibledisponible
ceph-squid (v19.2)2026-09disponibledisponibledisponible

El fichero que genera tiene formato deb822, como todos los repos de PVE 9: Types: deb, URIs: http://download.proxmox.com/debian/ceph-tentacle, Suites: trixie, el Components correspondiente al repositorio elegido y Signed-By: /usr/share/keyrings/proxmox-archive-keyring.gpg.

Con los paquetes en los tres nodos, inicializas el cluster desde uno solo:

# Mínimo: solo red pública
pveceph init --network 10.10.10.0/24

# Recomendado: red pública y red de cluster separadas
pveceph init --network 10.10.10.0/24 --cluster-network 10.55.10.0/24 \
             --size 3 --min_size 2

Opciones exactas de pveceph init:

OpciónDefaultQué hace
--networkRed para todo el tráfico Ceph. Requerida
--cluster-networkRed separada para heartbeat, replicación y recovery. Requiere --network
--size3Réplicas objetivo por objeto (1-7)
--min_size2Réplicas mínimas disponibles para permitir I/O (1-7)
--pg_bits6Deprecado en versiones recientes de Ceph
--disable_cephx0Desactiva la autenticación cephx

Advertencia sobre --disable_cephx: el warning oficial dice “cephx is a security feature protecting against man-in-the-middle attacks. Only consider disabling cephx if your network is private!”. En una red de storage aislada puede tener sentido para arañar rendimiento; en cualquier otro escenario, déjalo activo.

pveceph init crea /etc/pve/ceph.conf (dentro de pmxcfs, por tanto replicado a todos los nodos automáticamente) y un enlace simbólico /etc/ceph/ceph.conf que apunta ahí, para que las herramientas nativas de Ceph lo encuentren donde esperan. El comando es idempotente: si ya existe una sección [global] en ceph.conf, se preservan el fsid, la configuración de auth y los defaults de pool, y la mayoría de parámetros se ignoran silenciosamente. Es decir, volver a ejecutarlo no reconfigura un cluster existente — si te equivocaste de red, tendrás que corregirla explícitamente.

Si prefieres el asistente web, está en Nodo → Ceph y hace los mismos pasos: elegir versión (“Prefer the one from your other nodes, or the newest if this is the first node”), instalar paquetes, y configurar Public Network, Cluster Network, número de réplicas, réplicas mínimas y el primer nodo monitor.

Monitores y managers: cuántos y dónde

pveceph mon create
pveceph mon destroy <id>

pveceph mgr create
pveceph mgr destroy <id>

Reglas verificadas para los monitores: “For high availability, you need at least 3 monitors”, nota literal “At least three Monitors are needed for quorum”, y “You won’t need more than 3 monitors, as long as your cluster is small to medium-sized”.

Es exactamente la misma aritmética de quorum que corosync: número impar, mayoría estricta. Con tres MON sobrevives a la caída de uno. Con dos MON, la caída de cualquiera de los dos deja el cluster sin quorum de monitores y todo el I/O se detiene — es peor que tener uno solo.

Para los managers: “Multiple Managers can be installed, but only one Manager is active at any given time” y “It is recommended to install the Ceph Manager on the monitor nodes”. Los MGR adicionales quedan en standby y se promocionan si el activo cae. Ponerlos junto a los MON simplifica la topología: los tres nodos “de control” son los mismos. En la GUI, todo esto está en Nodo → Ceph → Monitor.

OSDs: creación, DB/WAL separados y varios OSD por NVMe

Antes de crear un OSD, el disco tiene que estar limpio. Si trae restos de una tabla de particiones, de un LVM viejo o de un OSD anterior, pveceph se negará:

ceph-volume lvm zap /dev/sdX --destroy

Creación:

# OSD simple: todo (datos, DB y WAL) en el mismo disco
pveceph osd create /dev/sdX

# DB y WAL en dispositivos rápidos separados
pveceph osd create /dev/sdX -db_dev /dev/nvme0n1 -wal_dev /dev/nvme1n1

# Varios OSD sobre un mismo NVMe rápido
pveceph osd create /dev/nvme0n1 --osds-per-device 2

Opciones exactas de pveceph osd create:

OpciónDescripción
--crush-device-classFija la device class del OSD en CRUSH (nvme, ssd, hdd)
--db_dev / --db_dev_sizeDispositivo y tamaño en GiB para block.db. Mínimo 1 GiB
--wal_dev / --wal_dev_sizeDispositivo y tamaño en GiB para block.wal. Mínimo 0,5 GiB
--encryptedDefault 0. Cifra el OSD
--osds-per-deviceServicios OSD por dispositivo físico. “Only useful for fast NVMe devices”. Mutuamente excluyente con db_dev y wal_dev

Tres cosas que conviene tener claras antes de tocar esto:

Uno. “The WAL is placed with the DB, if not specified separately.” Si solo pasas -db_dev, el WAL se va con la DB a ese mismo dispositivo. Es lo habitual y es lo correcto.

Dos. Si no indicas tamaños, el orden de resolución es: bluestore_block_db_size / bluestore_block_wal_size de la base de datos de configuración (sección osd, luego global), luego del fichero (osd, luego global), y como último recurso el fallback de 10% del tamaño del OSD para la DB y 1% para el WAL.

Tres. --osds-per-device existe porque un solo proceso ceph-osd no siempre satura un NVMe empresarial moderno: partir el disco en dos OSDs paraleliza el trabajo. Pero solo tiene sentido con NVMe rápidos, y no se puede combinar con DB o WAL externos — el disco ya es el dispositivo rápido.

Verifica el resultado con la vista por árbol, que es la que usarás también en el mantenimiento:

ceph osd df tree

Destruir y reemplazar un OSD sin perder datos

Sacar un disco de Ceph es un procedimiento, no un botón. Si te saltas pasos, dejas el pool degraded o, peor, con PGs incompletos. El procedimiento oficial son cinco pasos:

# 1. Comprobar que hay espacio para absorber los datos del OSD que sale.
#    Ningun OSD debe estar cerca del nearfull_ratio (default 85%).
ceph osd df tree

# 2. Marcar el OSD como 'out': deja de recibir datos y el cluster empieza
#    a mover sus PGs al resto.
ceph osd out <id>

# 3. Esperar al rebalance: el OSD debe llegar a 0 PGs.
ceph -s

# 4. Comprobar que se puede parar sin romper disponibilidad y pararlo.
ceph osd ok-to-stop <id>
pveceph stop --service osd.<id>

# 5. Destruirlo.
pveceph osd destroy <id> --cleanup

El paso 1 no es burocracia: si sacas un OSD de un cluster que ya está al 80%, los datos que salían de ese disco se reparten en los demás y puedes cruzar el umbral full (0.95 por defecto en Ceph), momento en el que el cluster deja de aceptar escrituras y todas las VMs se quedan colgadas. El nearfull_ratio por defecto del 85% es el valor que cita explícitamente la documentación de Proxmox VE en este procedimiento. Y el paso 4 es la red de seguridad: ceph osd ok-to-stop <id> responde si parar ese daemon concreto dejaría algún PG por debajo de min_size; si dice que no, no lo pares.

El ciclo completo de reemplazo de un disco:

stateDiagram-v2
    [*] --> InUp
    InUp: in + up - OSD sano
    InUp --> OutUp: ceph osd out
    OutUp: out + up - backfill hasta 0 PGs
    OutUp --> OkToStop: ceph osd ok-to-stop
    OkToStop --> Stopped: pveceph stop --service osd.ID
    Stopped: out + down
    Stopped --> Destroyed: pveceph osd destroy ID --cleanup
    Destroyed --> Zap: disco nuevo + ceph-volume lvm zap --destroy
    Zap --> Recovery: pveceph osd create
    Recovery: rebalance de vuelta
    Recovery --> Healthy: HEALTH_OK
    Healthy --> [*]

El procedimiento de reemplazo formal son también cinco pasos: conseguir un disco del mismo tipo y tamaño, destruir el OSD, desconectar el viejo y conectar el nuevo, volver a crear el OSD, y esperar al rebalance automático hasta HEALTH_OK. Al final, si quedaron crashes registrados de cuando el disco falló:

ceph crash ls
ceph crash info <crash_id>
ceph crash archive-all

archive-all reconoce los crashes y limpia el RECENT_CRASH de la salud del cluster: no arregla nada, solo dice “ya lo he visto”.

Dónde vive la configuración: ceph.conf mínimo y la base de datos de los MON

Este punto confunde a quien viene de Ceph clásico. En Proxmox VE:

“In Proxmox VE, a minimal ceph.conf file is used to hold bootstrap settings. Most of the configuration is held in the central configuration database maintained by the MON services.”

O sea: /etc/pve/ceph.conf solo tiene lo imprescindible para que un daemon arranque y encuentre a los monitores. Todo lo demás vive en la MON DB y se toca con ceph config:

ComandoQué hace
ceph config dumpMuestra todas las opciones configuradas
ceph config get <who> <name>Muestra opciones de una entidad
ceph config set <who> <name> <value>Fija una opción
ceph config rm <who> <name>Borra una opción
ceph config set osd osd_memory_target 8G
ceph config dump

Gotcha de precedencia, y es contraintuitivo: “If an option exists in a local configuration file, the configuration in the MON DB will be ignored because it has a lower precedence.” El fichero gana sobre la base de datos. Por eso el ceph.conf de Proxmox VE es deliberadamente mínimo: cualquier opción que escribas ahí a mano deja de poder cambiarse con ceph config set, y te quedas con un ajuste “fantasma” que no aparece en ceph config dump pero sí manda. Si algún día un ceph config set no surte efecto, lo primero que hay que mirar es si esa clave está escrita en /etc/pve/ceph.conf.

Pools replicados: size, min_size y placement groups

Un pool es la unidad lógica de almacenamiento donde viven los objetos. Los defaults que aplica Proxmox VE al crear uno son explícitos: “When no options are given, we set a default of 128 PGs, a size of 3 replicas and a min_size of 2 replicas, to ensure no data loss occurs if any OSD fails”.

  • size es cuántas copias de cada objeto quieres. Con 3, cada bloque vive en tres OSDs de tres nodos distintos.
  • min_size es cuántas copias tienen que estar disponibles para que el pool acepte I/O. Con 2, puedes perder un nodo entero y seguir escribiendo; al perder el segundo, el pool se bloquea en lugar de seguir escribiendo sobre una copia solitaria.

Warning literal: “Do not set a min_size of 1. A replicated pool with min_size of 1 allows I/O on an object when it has only 1 replica, which could lead to data loss, incomplete PGs or unfound objects.”

Que el pool se bloquee con min_size=2 no es un fallo: es la garantía de que no vas a escribir datos que solo existen en un disco que puede morir en el segundo siguiente. Bajarlo a 1 “para que siga funcionando” durante una incidencia es la forma más rápida de convertir una degradación en una pérdida.

Opciones exactas de pveceph pool create:

OpciónDefaultDescripción
--size3 (1-7)Número de réplicas por objeto
--min_size2 (1-7)Réplicas mínimas para aceptar I/O
--pg_num128 (1-32768)Número de placement groups
--pg_num_minMínimo de PGs; el autoscaler no fusiona por debajo
--pg_autoscale_modewarnoff, on o warn
--crush_ruleRegla CRUSH a aplicar
--applicationrbdcephfs, rbd o rgw
--add_storagesfalse en replicados, true en ECCrea la entrada en storage.cfg
--target_sizeTamaño estimado del pool, para el autoscaler
--target_size_ratioRatio estimado. Tiene precedencia sobre target_size
--erasure-codingk=<int>,m=<int>[,device-class=][,failure-domain=][,profile=]
pveceph pool create vm-pool --add_storages
pveceph pool destroy vm-pool -remove_storages

Note literal: “Pool deletion runs in the background and can take some time.” No te asustes si ceph df sigue mostrando el espacio ocupado un rato después.

Los placement groups son el nivel intermedio entre objetos y OSDs: Ceph no mapea objeto a OSD directamente, sino objeto a PG y PG a un conjunto de OSDs. Pocos PGs implica distribución desigual del dato; demasiados PGs implica consumo de CPU y memoria en cada OSD. De ahí que exista un autoscaler.

El PG autoscaler y sus avisos

ceph mgr module enable pg_autoscaler
ceph osd pool set <pool> pg_autoscale_mode on
ceph osd pool autoscale-status
ModoComportamiento
warnEmite un aviso de salud si el pg_num sugerido difiere demasiado del actual. Default en Proxmox VE
onAjusta el pg_num automáticamente
offNi ajusta ni avisa

El default warn es deliberadamente conservador, y la razón está en este warning:

“By default, the autoscaler considers tuning the PG count of a pool if it is off by a factor of 3. This will lead to a considerable shift in data placement and might introduce a high load on the cluster.”

Es decir, cuando el autoscaler decide actuar, mueve datos en serio. En modo on puede lanzarse a rebalancear en horario productivo; en modo warn te avisa y decides tú cuándo. Gotcha con device classes: hay además una condición que lo rompe en silencio.

“When using the PG autoscaler, all pools in the cluster are required to use CRUSH rules of the same kind, either all specifying a device class, or none. Otherwise the autoscaler will skip the affected pools and their pg_num will not be adjusted.”

Si creas un pool nuevo con una regla CRUSH que fija class nvme y dejas los pools antiguos con la regla por defecto sin clase, el autoscaler deja de ajustar esos pools sin decir nada evidente. La verificación es directa: ceph osd pool autoscale-status y comprueba que todos los pools aparecen con recomendación.

Erasure coding, data-pool y FastEC en Tentacle

La replicación con size=3 cuesta un 200% de sobrecarga: para almacenar 1 TB útil necesitas 3 TB brutos. El erasure coding parte cada objeto en k fragmentos de datos y calcula m fragmentos de codificación; puedes perder hasta m OSDs sin perder el objeto, y el total de fragmentos es k + m.

pveceph pool create archivo --erasure-coding k=2,m=1
pveceph pool create archivo --erasure-coding profile=<nombre-de-perfil>

Ese comando crea dos pools: archivo-data (erasure coded, donde van los bloques) y archivo-metadata (replicado, porque el omap de RBD no puede vivir en un pool EC). Al declarar el storage a mano hay que indicar el data-pool:

pvesm add rbd <nombre-storage> --pool archivo-metadata --data-pool archivo-data

Valores de min_size por defecto en EC: k si m = 1, k + 1 si m > 1. La documentación de Ceph recomienda ser más conservador y usar k + 2. Los dos ejemplos oficiales: con k=2, m=1 el size resultante es 3 y el min_size 2, y sobrevive a un OSD caído; con k=2, m=2 el size es 4 y el min_size 3, y también sobrevive a un OSD caído.

Note literal: “The optional parameters --size, --min_size and --crush_rule will be used for the replicated metadata pool, but not for the erasure coded data pool. If you need to change the min_size on the data pool, you can do it later. The size and crush_rule parameters cannot be changed on erasure coded pools.”

Ese último punto es determinante para la planificación: en un pool EC, size y crush_rule son inmutables. Si te equivocas con k y m, la salida es crear otro pool y mover los datos.

FastEC: allow_ec_optimizations

Históricamente, el EC ha sido malo para discos de VM porque el patrón dominante ahí es I/O aleatorio pequeño, y cada escritura parcial obligaba a leer-modificar-escribir la franja completa. Ceph Tentacle introduce una ruta de I/O nueva para EC con lecturas y escrituras parciales, que mejora sustancialmente ese patrón. Se activa con el flag allow_ec_optimizations, y el MON verifica cuatro requisitos:

  1. El pool debe ser erasure coded.
  2. El cluster debe estar en require_osd_release tentacle o posterior.
  3. El perfil EC debe usar una combinación plugin + technique compatible: solo valen isa con reed_sol_van y jerasure con reed_sol_van. Quedan fuera isa con cauchy, el resto de techniques de jerasure, y los plugins lrc, shec y clay con cualquier technique.
  4. El stripe_unit del pool debe ser múltiplo de 4096 bytes (el default ya lo es).
ceph config get mon osd_pool_default_erasure_code_profile
ceph osd dump | grep require_osd_release
ceph osd require-osd-release tentacle          # solo si aun no lo esta

ceph osd pool set archivo-data allow_ec_optimizations 1
ceph osd pool get archivo-data allow_ec_optimizations

Important literal: allow_ec_optimizations is a one-way switch. Once enabled on a pool, the Ceph monitor refuses to clear the flag again, so rolling back requires draining and recreating the pool.”

Advertencia: es un interruptor de un solo sentido. Y al activarlo sobre un pool que ya tiene datos hay dos efectos inmediatos. Uno, primary re-election: FastEC marca los shards 1..k-1 como no primarios, así que los PGs cuyo primario estuviera en ellos vuelven a hacer peering, con una breve pausa de I/O por PG. Dos, ese re-peering cancela cualquier scrub en vuelo y esos PGs habrá que volver a escrubearlos.

La decisión entre replicación y EC, resumida:

flowchart TD
    START["Que guarda este pool"] --> Q1{"Discos de VM o CT<br/>con I O aleatorio"}
    Q1 -->|Si| REP["Pool replicado size 3 min_size 2"]
    Q1 -->|No| Q2{"Archivo o capacidad pura"}
    Q2 -->|No| REP
    Q2 -->|Si| EC["Pool erasure coded k y m"]
    REP --> ADD["pveceph pool create --add_storages"]
    EC --> META["pool-metadata replicado para el omap de RBD<br/>+ pool-data con los bloques"]
    META --> STOR["pvesm add rbd --pool metadata --data-pool data"]
    EC --> FAST{"Tentacle y perfil compatible"}
    FAST -->|Si| OPT["allow_ec_optimizations 1 - irreversible"]
    FAST -->|No| NOOPT["EC clasico sin optimizaciones"]

CRUSH, device classes y reglas por tipo de disco

CRUSH es el algoritmo que decide en qué OSDs cae cada PG. No hay tabla de mapeo centralizada: cliente y OSD calculan la ubicación con la misma función a partir del cluster map. Por eso Ceph escala sin cuello de botella de metadatos para RBD.

Las device classes son etiquetas automáticas que Ceph asigna a cada OSD (nvme, ssd, hdd) según el tipo de disco. Sirven para escribir reglas que solo usan un tipo:

# Ver el arbol CRUSH incluyendo los roots sombra por clase
ceph osd crush tree --show-shadow

# Crear una regla replicada que solo usa OSDs NVMe
ceph osd crush rule create-replicated solo-nvme default host nvme

# Aplicar la regla a un pool
ceph osd pool set vm-pool crush_rule solo-nvme
ParámetroSignificado
<rule-name>Nombre de la regla, visible en GUI y CLI
<root>Root CRUSH al que pertenece. Normalmente default
<failure-domain>Dominio de fallo para distribuir las copias. Normalmente host
<class>Tipo de backing store: nvme, ssd o hdd

El failure-domain es la pieza que garantiza que las tres réplicas de un objeto no caigan en tres discos del mismo servidor. Con host, cada réplica va a un nodo distinto: por eso hacen falta al menos tres nodos para size=3.

La salida de ceph osd crush tree --show-shadow muestra los roots sombra que Ceph mantiene por clase:

ID  CLASS WEIGHT  TYPE NAME
-16  nvme 2.18307 root default~nvme
-13  nvme 0.72769     host sumi1~nvme
 12  nvme 0.72769         osd.12

Tip literal: “If the pool already contains objects, these must be moved accordingly. Depending on your setup, this may introduce a big performance impact on your cluster. As an alternative, you can create a new pool and move disks separately.”

Cambiar la crush_rule de un pool con datos dispara un movimiento masivo. En un cluster en producción es preferible crear un pool nuevo con la regla correcta y mover los discos de VM uno a uno con qm disk move, controlando el ritmo.

Y recuerda el gotcha de la sección anterior: si mezclas pools con regla que especifica clase y pools sin ella, el autoscaler se salta los afectados.

CephFS para ISOs, plantillas y backups

RBD es almacenamiento en bloque: sirve para discos de VM y para rootfs de contenedores, con formato raw, pero no sirve para ISOs ni para backups. Para eso necesitas un sistema de ficheros POSIX compartido, y ese es CephFS.

Los prerrequisitos son tener los paquetes Ceph instalados, los MON y OSD montados, y al menos un MDS:

pveceph mds create
pveceph mds create --hotstandby 1
pveceph mds destroy NAME

Con los ajustes por defecto solo hay un MDS activo; los demás quedan en standby y se promocionan si el activo cae. La opción hotstandby (equivalente a mds standby replay = true en la sección del MDS de /etc/pve/ceph.conf) mantiene el standby “caliente” haciendo polling del journal del activo, lo que acelera el failover. Nota literal: “This active polling will have an additional performance impact on your system and the active MDS.” Varios MDS activos son posibles desde Luminous, pero “normally only useful if you have a high amount of clients running in parallel”.

Con el MDS arriba, creas el sistema de ficheros:

pveceph fs create --pg_num 128 --add-storage
pveceph fs create --name cephfs2 --pg_num 128 --add-storage 1
OpciónDefaultDescripción
--namecephfsNombre del filesystem
--pg_num128 (8-32768)PGs del pool de datos. El de metadatos usa un cuarto: 32
--add-storage0Añade la entrada correspondiente a storage.cfg

Es decir, pveceph fs create --pg_num 128 crea cephfs_data con 128 PGs y cephfs_metadata con 32.

El storage resultante soporta contenido vztmpl, iso, backup y snippets, es shared, no admite clones, y sus snapshots tienen la advertencia oficial de que “while no known bugs exist, snapshots are not yet guaranteed to be stable, as they lack sufficient testing”.

Propiedades del plugin cephfs:

PropiedadDefaultPara qué
fs-nameNombre del Ceph FS
monhostDirecciones de los MON. Solo para cluster externo
path/mnt/pve/<STORAGE_ID>/Mountpoint local
usernameadminCeph user id. Solo cluster externo
subdir/Subdirectorio de CephFS a montar
fuse0Acceder vía FUSE en vez del cliente de kernel

Destruir un CephFS correctamente

Warning literal: “Destroying a CephFS will render all of its data unusable. This cannot be undone!”

El orden importa; saltarse un paso deja MDS huérfanos o montajes colgados:

  1. Desconecta todos los clientes que no sean Proxmox VE (desmonta dentro de los guests).
  2. Deshabilita todas las entradas de storage CephFS en Proxmox VE.
  3. Quita de los guests los recursos que estén ahí (ISOs montadas, por ejemplo).
  4. Desmonta en todos los nodos: umount /mnt/pve/<STORAGE-NAME>
  5. Para y destruye todos los MDS de ese FS, empezando por los standby.
  6. Destruye el filesystem.
umount /mnt/pve/cephfs                       # en todos los nodos

pveceph stop --service mds.pve3              # repetir por cada MDS,
pveceph mds destroy pve3                     # standby primero y activo al final

pveceph fs destroy cephfs --remove-storages --remove-pools

Usar RBD como storage de VMs y contenedores

Con un pool creado con --add_storages, Proxmox VE ya escribe la entrada en /etc/pve/storage.cfg y, como ese fichero vive en pmxcfs, aparece en todos los nodos a la vez. Es el mismo modelo de plugins que recorriste en el capítulo 7.

Propiedades del plugin rbd:

PropiedadDescripción
monhostLista de IPs de los MON. Opcional: solo hace falta si Ceph no corre en el cluster Proxmox VE
poolNombre del pool Ceph
data-poolPool de datos. Solo para erasure coding
usernameRBD user ID. Solo para clusteres externos. Sin el prefijo client.
krbdFuerza el acceso vía módulo de kernel krbd. Default 0
keyringContenido del keyring, para clusteres externos
namespaceNamespace RBD

Limitaciones: contenido images y rootdir, formato raw únicamente. No admite ISOs ni backups. Gotcha de krbd: la opción existe para VMs, pero la nota oficial es tajante: “Containers will use krbd independent of the option value.” Los contenedores LXC siempre pasan por el módulo de kernel, tenga la opción el valor que tenga. Si depuras una diferencia de comportamiento entre una VM y un CT sobre el mismo pool, esta es a menudo la causa.

Cluster Ceph externo

Si el Ceph no es el del propio cluster, hay que copiar credenciales a mano y los nombres de fichero son estrictos:

# RBD
scp <servidor-ceph-externo>:/etc/ceph/ceph.client.admin.keyring /root/rbd.keyring
pvesm add rbd ceph-externo --monhost "10.1.1.20 10.1.1.21 10.1.1.22" \
    --content images --keyring /root/rbd.keyring

# CephFS: en el cluster Ceph, extraer SOLO la clave
ceph auth get-key client.userid > cephfs.secret
scp <servidor-ceph-externo>:/etc/ceph/cephfs.secret /root/cephfs.secret
pvesm add cephfs cephfs-externo --monhost "10.1.1.20 10.1.1.21 10.1.1.22" \
    --content backup --keyring /root/cephfs.secret

El keyring RBD acaba en /etc/pve/priv/ceph/<STORAGE_ID>.keyring, donde <STORAGE_ID> es exactamente la expresión que sigue a rbd: en /etc/pve/storage.cfg. Si el nombre no coincide, la autenticación falla sin más pista que un error genérico.

El de CephFS acaba en /etc/pve/priv/ceph/<STORAGE_ID>.secret, y aquí está la diferencia que más tiempo hace perder: “The secret is only the key itself, as opposed to the rbd backend which also contains a [client.userid] section.” El fichero de CephFS es solo la clave, sin cabecera de sección. Si copias el keyring completo, no monta.

Rutas relevantes, todas replicadas por pmxcfs salvo las locales:

RutaContenido
/etc/pve/ceph.confConfiguración Ceph mínima de bootstrap. Replicada
/etc/ceph/ceph.confSymlink a la anterior
/etc/pve/storage.cfgDefinición de todos los storages
/etc/pve/priv/ceph/<STORAGE_ID>.keyringKeyring RBD para cluster externo
/etc/pve/priv/ceph/<STORAGE_ID>.secretSecret CephFS. Solo la clave
/etc/pve/priv/ceph/<STORAGE_ID>.confConfig de cliente Ceph por storage. Opcional
/etc/apt/sources.list.d/ceph.sourcesRepositorio creado por pveceph install
/var/log/ceph/Logs de los daemons Ceph

Mantenimiento: scrub, trim y apagado ordenado

Scrub y deep scrub

“Ceph ensures data integrity by scrubbing placement groups… There are two forms of Scrubbing, daily cheap metadata checks and weekly deep data checks. The weekly deep scrub reads the objects and uses checksums to ensure data integrity.”

El scrub diario compara metadatos entre réplicas; el deep scrub semanal lee los objetos completos y valida sus checksums, que es lo que detecta el bit rot antes de que te lo encuentres al restaurar. Los intervalos se ajustan con las opciones osd_scrub_* y osd_deep_scrub_interval vía ceph config set.

Trim y discard

“It is good practice to run fstrim (discard) regularly on VMs and containers. This releases data blocks that the filesystem isn’t using anymore. It reduces data usage and resource load. Most modern operating systems issue such discard commands to their disks regularly. You only need to ensure that the Virtual Machines enable the disk discard option.”

Sin discard=on en el disco de la VM, borrar un fichero de 50 GB dentro del guest no libera ni un byte en el pool Ceph. En contenedores el comando es directo: pct fstrim <vmid>.

Apagado ordenado del cluster completo

Cuando hay que apagar todo — corte de luz programado, mudanza de rack — la secuencia importa:

# 1. Parar todos los clientes: VMs, contenedores, clientes CephFS, RADOS GW
# 2. Verificar que el cluster esta sano antes de tocar nada
ceph -s
# 3. Evitar que Ceph intente recuperar mientras apagas nodos
ceph osd set noout
# 4. Apagar primero los nodos SIN monitor, despues los nodos con MON
# 5. Encender primero los nodos con MON
# 6. Cuando todo este arriba y en HEALTH_OK:
ceph osd unset noout

noout es la clave: sin él, en cuanto un nodo lleve unos diez minutos apagado sus OSDs pasan a out y el cluster empieza a replicar sus datos a los nodos que quedan, justo cuando los estás apagando también. En la GUI el mismo flag está en Ceph → OSD → Manage Global Flags. Gotcha: olvidar el paso 6 es la causa número uno del HEALTH_WARN con OSDMAP_FLAGS que aparece días después de un mantenimiento.

Cambiar las redes de Ceph

Es posible sin downtime si la red vieja y la nueva pueden coexistir durante la transición. Nota literal: “A word of caution! It is critical that the change of the used networks by Ceph is being done carefully. Otherwise it could lead to a broken Ceph cluster with downtime to get it back into a working state! We recommend doing a trial run of the procedure in a (virtual) test cluster before changing the production infrastructure.” Al reiniciar OSDs tras el cambio, espera a HEALTH_OK y a que los OSDs estén escuchando en la red nueva antes de pasar al siguiente host.

Leer ceph -s y el catálogo de health checks

Los comandos que vas a usar todos los días:

ceph -s                    # equivalente: ceph --status
watch ceph --status        # observar continuamente
ceph --watch               # imprime el estado y va anadiendo eventos
ceph health detail         # el porque de un HEALTH_WARN
ceph osd df tree           # ocupacion por OSD y por nodo
ceph osd pool autoscale-status
ceph crash ls
journalctl --since "2 days ago"

Los tres estados globales son HEALTH_OK, HEALTH_WARN y HEALTH_ERR. Una salida típica de ceph -s con problemas:

  cluster:
    id:     <fsid>
    health: HEALTH_WARN
            1 osds down
            Degraded data redundancy: 1234/9876 objects degraded (12.497%)

  services:
    mon: 3 daemons, quorum pve1,pve2,pve3 (age 3d)
    mgr: pve1(active, since 3d), standbys: pve2
    mds: 1/1 daemons up, 1 standby
    osd: 6 osds: 5 up (since 2m), 6 in (since 3d)

  data:
    pools:   3 pools, 161 pgs
    objects: 3.29k objects, 12 GiB
    usage:   38 GiB used, 2.7 TiB / 2.8 TiB avail
    pgs:     140 active+clean
             21  active+undersized+degraded

Cómo se lee, línea por línea:

mon: 3 daemons, quorum pve1,pve2,pve3 — la lista tras quorum son los monitores que están dentro. Si falta un nombre que tú sabes que existe, ese MON está caído. Con tres definidos y solo dos en quorum, todavía funciona; con uno, el cluster se detiene.

mgr: pve1(active, since 3d), standbys: pve2 — uno activo, el resto en espera. Si no aparece ningún activo, has perdido el autoscaler y las métricas.

osd: 6 osds: 5 up (since 2m), 6 in (since 3d) — son dos ejes independientes. up/down indica si el daemon responde. in/out indica si participa en la distribución de datos. Aquí hay 6 OSDs declarados, 5 respondiendo y 6 todavía asignados: uno acaba de caer y aún no ha sido expulsado. Un OSD down pasa a out automáticamente unos 10 minutos después — literal: “A faulty OSD will be reported as down and mostly (auto) out 10 minutes later”. Esos diez minutos son la ventana en la que puedes arreglar un problema transitorio sin desencadenar un rebalance completo.

pgs: — el único estado sano es active+clean. El resto:

Estado de PGQué significa
degradedFaltan réplicas de algunos objetos
undersizedEl PG tiene menos OSDs de los que su regla pide
peeringLos OSDs están acordando el estado. Transitorio
backfilling / recoveringReconstruyendo datos. Transitorio
incomplete / down / staleGrave: hay datos inaccesibles

Los health checks que más vas a ver:

CódigoSignificado
OSD_DOWNUno o más OSDs marcados down: crash del daemon, host caído o red
OSD_NEARFULLOSDs por encima del umbral nearfull. Aviso temprano de llenado
OSD_BACKFILLFULLOSDs por encima del umbral backfillfull: impide rebalancear hacia ellos
OSD_FULLOSDs por encima del umbral full: el cluster deja de aceptar escrituras
OSDMAP_FLAGSHay flags activos (noout, noup, full, pauserd, pausewr). Típico noout olvidado
PG_AVAILABILITYHay datos que no se pueden leer ni escribir
PG_DEGRADEDRedundancia reducida: faltan réplicas o fragmentos EC
PG_NOT_SCRUBBED / PG_NOT_DEEP_SCRUBBEDPGs sin scrub o deep scrub reciente
POOL_NEAR_FULLPool cerca de su cuota o de llenarse
POOL_TOO_FEW_PGS / POOL_TOO_MANY_PGSRecuento de PGs subóptimo. Relacionado con el autoscaler
POOL_APP_NOT_ENABLEDPool sin etiqueta de aplicación
MON_DOWNUno o más monitores caídos
MON_CLOCK_SKEWRelojes de los MON desincronizados: revisar chrony/NTP
MON_DISK_LOW / MON_DISK_CRITEspacio libre del MON por debajo del 30% / del 5%
MGR_MODULE_ERRORMódulo del manager con error
SLOW_OPSPeticiones a OSD o MON tardando demasiado. Síntoma de disco o red enferma
RECENT_CRASHDaemons con crash reciente sin reconocer

El nearfull_ratio por defecto es 0,85 (85%), valor que la documentación de Proxmox VE cita explícitamente en el procedimiento de destrucción de OSDs. Los otros dos umbrales históricos de Ceph son backfillfull_ratio 0,90 y full_ratio 0,95; conviene confirmarlos en tu cluster con ceph osd dump | grep ratio antes de dar por buenos esos números. Se ajustan con ceph osd set-nearfull-ratio, ceph osd set-backfillfull-ratio y ceph osd set-full-ratio.

Las causas comunes que documenta Proxmox VE son tres, y en este orden: problemas de red (congestión, switch defectuoso, interfaz caída, firewall bloqueando), discos o conexiones defectuosos o sin rendimiento de I/O bajo carga (HDDs, hardware de consumo, controladoras RAID desaconsejadas), y no cumplir las recomendaciones de hardware. Verifica siempre la alcanzabilidad de todos los nodos en las tres redes: corosync, pública de Ceph y de cluster de Ceph.

Errores comunes y diagnóstico

SíntomaCausa probableDiagnóstico y solución
El cluster Proxmox VE pierde quorum durante un recovery de CephCorosync comparte NIC con el tráfico de CephSeparar corosync a una NIC dedicada de 1 Gbps. Revisar Retransmit List en el log de corosync
HEALTH_WARN ... noout flag(s) set días después de un mantenimientoSe olvidó quitar el flagceph osd unset noout
OSD down que no vuelve tras reiniciar el nodoEl LV del OSD no se activó al arrancarceph-volume lvm activate --all en el nodo afectado. Si no basta, reiniciar el nodo de forma segura y, como último recurso, recrear o reemplazar el OSD
HEALTH_WARN mons are allowing insecure global_id reclaimClientes antiguos tras un upgradeActualizar clientes y luego ceph config set mon auth_allow_insecure_global_id_reclaim false
pveceph install instala una versión distinta a la del resto del clusterSe instaló sin fijar versión en un cluster que ya tenía CephEl asistente web fija la release que ya corre el cluster. Por CLI, usar --version explícito
El pool se queda bloqueado sin aceptar escriturasSe cruzó el umbral full, o hay menos réplicas disponibles que min_sizeceph osd df tree y ceph -s. Liberar espacio o recuperar el OSD caído. No bajar min_size a 1
ceph config set no surte efectoLa misma opción está escrita en /etc/pve/ceph.conf, y el fichero tiene precedencia sobre la MON DBQuitar la opción del fichero y volver a fijarla con ceph config set
El autoscaler no ajusta el pg_num de algunos poolsMezcla de pools con y sin device class en su regla CRUSHceph osd pool autoscale-status. Unificar el criterio: o todas las reglas con clase, o ninguna
CephFS de cluster externo no montaEl fichero de secret tiene formato de keyringDebe ser /etc/pve/priv/ceph/<STORAGE_ID>.secret y contener solo la clave, sin la sección [client.userid]
RBD de cluster externo no autenticaNombre de fichero incorrecto/etc/pve/priv/ceph/<STORAGE_ID>.keyring, con <STORAGE_ID> idéntico al de storage.cfg
pveceph osd create falla sobre un disco que ya se usóRestos de tabla de particiones, LVM o un OSD previoceph-volume lvm zap /dev/sdX --destroy
No puedes subir ISOs al storage CephEl plugin rbd solo admite images y rootdirCrear un CephFS con pveceph fs create --add-storage y subir ahí
Borrar ficheros dentro de una VM no libera espacio en el poolFalta discard=on en el disco de la VMqm set <vmid> --scsi0 <storage>:<volumen>,discard=on y fstrim -av dentro del guest
Un OSD siempre es el más lleno y dispara OSD_NEARFULLDiscos de tamaños desiguales en el mismo nodoIgualar tamaños. Ceph rinde mejor con discos del mismo tamaño y en igual número por nodo
MON_CLOCK_SKEW intermitenteRelojes desincronizados entre nodosRevisar el servicio de tiempo en los tres nodos. Ceph es sensible al desvío entre monitores
Un pool EC no deja cambiar size ni la regla CRUSHEs una limitación del propio ECsize y crush_rule no se pueden cambiar en pools erasure coded. Crear otro pool y mover los datos

Lo que queda operativo

Con lo de este capítulo tienes un cluster hiperconvergido completo: tres nodos con MON y MGR en quorum, OSDs distribuidos sobre discos crudos detrás de HBA, redes de Ceph separadas de corosync, un pool RBD replicado con size=3 y min_size=2 dado de alta como storage compartido de VMs y contenedores, y un CephFS para ISOs, plantillas y snippets. Ese storage compartido es exactamente lo que necesitaba la HA del capítulo 11 para reiniciar VMs en otro nodo y para que la migración en vivo sea casi instantánea, porque ya no hay que copiar discos.

También tienes el vocabulario para diagnosticar: sabes distinguir up/down de in/out, sabes que un PG que no está active+clean te está contando algo, y sabes que un OSD_FULL no es un aviso sino una parada. Lo que sigue, en el capítulo 15, es integrar esas señales con el sistema de notificaciones del cluster para que no dependas de mirar ceph -s a mano.

Lo que Ceph no es, y conviene decirlo claro: no es un backup. La replicación protege contra el fallo de un disco o de un nodo, no contra un rm -rf dentro de una VM, un ransomware ni un borrado accidental de un pool. Los tres OSDs que guardan tu objeto se sincronizan al instante, incluidos los errores. Eso lo resuelve el capítulo 13, donde montarás vzdump, Proxmox Backup Server con deduplicación y verificación, y la estrategia 3-2-1 que convierte este cluster en algo realmente recuperable.