Ceph hiperconvergido en Proxmox VE
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:
| Daemon | Proceso | Función | ¿Obligatorio? |
|---|---|---|---|
| Ceph Monitor | ceph-mon | Mantiene la copia maestra del cluster map: quién existe, quién está vivo, cómo se distribuyen los datos | Sí, y en número impar |
| Ceph Manager | ceph-mgr | Interfaz de monitorización y módulos como el PG-autoscaling, el device health monitoring y la telemetría | Sí, requerido desde Luminous |
| Ceph Metadata Server | ceph-mds | Metadatos del sistema de ficheros POSIX | Solo si usas CephFS |
| Ceph OSD | ceph-osd | Almacena los objetos. Uno por disco físico | Sí, 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.
| Red | Qué transporta | Obligatoria |
|---|---|---|
| Public Network | Tráfico de storage entre clientes (VMs con RBD, montajes CephFS) y los servicios Ceph, y entre los propios servicios | Sí |
| Cluster Network | Replicación entre OSDs, heartbeat y recovery | No, 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ón | Valores | Default |
|---|---|---|
--version | squid o tentacle | tentacle en PVE 9.2 |
--repository | enterprise, manual, no-subscription, test | enterprise |
--allow-experimental | 0 o 1 | 0. “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:
| Release | EOL estimado | enterprise | no-subscription | test |
|---|---|---|---|---|
ceph-tentacle (v20.2) | 2027-11 | recomendado | disponible | disponible |
ceph-squid (v19.2) | 2026-09 | disponible | disponible | disponible |
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ón | Default | Qué hace |
|---|---|---|
--network | — | Red para todo el tráfico Ceph. Requerida |
--cluster-network | — | Red separada para heartbeat, replicación y recovery. Requiere --network |
--size | 3 | Réplicas objetivo por objeto (1-7) |
--min_size | 2 | Réplicas mínimas disponibles para permitir I/O (1-7) |
--pg_bits | 6 | Deprecado en versiones recientes de Ceph |
--disable_cephx | 0 | Desactiva 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ón | Descripción |
|---|---|
--crush-device-class | Fija la device class del OSD en CRUSH (nvme, ssd, hdd) |
--db_dev / --db_dev_size | Dispositivo y tamaño en GiB para block.db. Mínimo 1 GiB |
--wal_dev / --wal_dev_size | Dispositivo y tamaño en GiB para block.wal. Mínimo 0,5 GiB |
--encrypted | Default 0. Cifra el OSD |
--osds-per-device | Servicios 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.conffile 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:
| Comando | Qué hace |
|---|---|
ceph config dump | Muestra 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”.
sizees cuántas copias de cada objeto quieres. Con 3, cada bloque vive en tres OSDs de tres nodos distintos.min_sizees 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ón | Default | Descripción |
|---|---|---|
--size | 3 (1-7) | Número de réplicas por objeto |
--min_size | 2 (1-7) | Réplicas mínimas para aceptar I/O |
--pg_num | 128 (1-32768) | Número de placement groups |
--pg_num_min | — | Mínimo de PGs; el autoscaler no fusiona por debajo |
--pg_autoscale_mode | warn | off, on o warn |
--crush_rule | — | Regla CRUSH a aplicar |
--application | rbd | cephfs, rbd o rgw |
--add_storages | false en replicados, true en EC | Crea la entrada en storage.cfg |
--target_size | — | Tamaño estimado del pool, para el autoscaler |
--target_size_ratio | — | Ratio estimado. Tiene precedencia sobre target_size |
--erasure-coding | — | k=<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 dfsigue 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
| Modo | Comportamiento |
|---|---|
warn | Emite un aviso de salud si el pg_num sugerido difiere demasiado del actual. Default en Proxmox VE |
on | Ajusta el pg_num automáticamente |
off | Ni 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_sizeand--crush_rulewill 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:
- El pool debe ser erasure coded.
- El cluster debe estar en
require_osd_release tentacleo posterior. - El perfil EC debe usar una combinación plugin + technique compatible: solo valen
isaconreed_sol_vanyjerasureconreed_sol_van. Quedan fueraisaconcauchy, el resto de techniques dejerasure, y los pluginslrc,shecyclaycon cualquier technique. - El
stripe_unitdel 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_optimizationsis 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ámetro | Significado |
|---|---|
<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ón | Default | Descripción |
|---|---|---|
--name | cephfs | Nombre del filesystem |
--pg_num | 128 (8-32768) | PGs del pool de datos. El de metadatos usa un cuarto: 32 |
--add-storage | 0 | Añ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:
| Propiedad | Default | Para qué |
|---|---|---|
fs-name | — | Nombre del Ceph FS |
monhost | — | Direcciones de los MON. Solo para cluster externo |
path | /mnt/pve/<STORAGE_ID>/ | Mountpoint local |
username | admin | Ceph user id. Solo cluster externo |
subdir | / | Subdirectorio de CephFS a montar |
fuse | 0 | Acceder 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:
- Desconecta todos los clientes que no sean Proxmox VE (desmonta dentro de los guests).
- Deshabilita todas las entradas de storage CephFS en Proxmox VE.
- Quita de los guests los recursos que estén ahí (ISOs montadas, por ejemplo).
- Desmonta en todos los nodos:
umount /mnt/pve/<STORAGE-NAME> - Para y destruye todos los MDS de ese FS, empezando por los standby.
- 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:
| Propiedad | Descripción |
|---|---|
monhost | Lista de IPs de los MON. Opcional: solo hace falta si Ceph no corre en el cluster Proxmox VE |
pool | Nombre del pool Ceph |
data-pool | Pool de datos. Solo para erasure coding |
username | RBD user ID. Solo para clusteres externos. Sin el prefijo client. |
krbd | Fuerza el acceso vía módulo de kernel krbd. Default 0 |
keyring | Contenido del keyring, para clusteres externos |
namespace | Namespace 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:
| Ruta | Contenido |
|---|---|
/etc/pve/ceph.conf | Configuración Ceph mínima de bootstrap. Replicada |
/etc/ceph/ceph.conf | Symlink a la anterior |
/etc/pve/storage.cfg | Definición de todos los storages |
/etc/pve/priv/ceph/<STORAGE_ID>.keyring | Keyring RBD para cluster externo |
/etc/pve/priv/ceph/<STORAGE_ID>.secret | Secret CephFS. Solo la clave |
/etc/pve/priv/ceph/<STORAGE_ID>.conf | Config de cliente Ceph por storage. Opcional |
/etc/apt/sources.list.d/ceph.sources | Repositorio 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 PG | Qué significa |
|---|---|
degraded | Faltan réplicas de algunos objetos |
undersized | El PG tiene menos OSDs de los que su regla pide |
peering | Los OSDs están acordando el estado. Transitorio |
backfilling / recovering | Reconstruyendo datos. Transitorio |
incomplete / down / stale | Grave: hay datos inaccesibles |
Los health checks que más vas a ver:
| Código | Significado |
|---|---|
OSD_DOWN | Uno o más OSDs marcados down: crash del daemon, host caído o red |
OSD_NEARFULL | OSDs por encima del umbral nearfull. Aviso temprano de llenado |
OSD_BACKFILLFULL | OSDs por encima del umbral backfillfull: impide rebalancear hacia ellos |
OSD_FULL | OSDs por encima del umbral full: el cluster deja de aceptar escrituras |
OSDMAP_FLAGS | Hay flags activos (noout, noup, full, pauserd, pausewr). Típico noout olvidado |
PG_AVAILABILITY | Hay datos que no se pueden leer ni escribir |
PG_DEGRADED | Redundancia reducida: faltan réplicas o fragmentos EC |
PG_NOT_SCRUBBED / PG_NOT_DEEP_SCRUBBED | PGs sin scrub o deep scrub reciente |
POOL_NEAR_FULL | Pool cerca de su cuota o de llenarse |
POOL_TOO_FEW_PGS / POOL_TOO_MANY_PGS | Recuento de PGs subóptimo. Relacionado con el autoscaler |
POOL_APP_NOT_ENABLED | Pool sin etiqueta de aplicación |
MON_DOWN | Uno o más monitores caídos |
MON_CLOCK_SKEW | Relojes de los MON desincronizados: revisar chrony/NTP |
MON_DISK_LOW / MON_DISK_CRIT | Espacio libre del MON por debajo del 30% / del 5% |
MGR_MODULE_ERROR | Módulo del manager con error |
SLOW_OPS | Peticiones a OSD o MON tardando demasiado. Síntoma de disco o red enferma |
RECENT_CRASH | Daemons 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íntoma | Causa probable | Diagnóstico y solución |
|---|---|---|
| El cluster Proxmox VE pierde quorum durante un recovery de Ceph | Corosync comparte NIC con el tráfico de Ceph | Separar 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 mantenimiento | Se olvidó quitar el flag | ceph osd unset noout |
OSD down que no vuelve tras reiniciar el nodo | El LV del OSD no se activó al arrancar | ceph-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 reclaim | Clientes antiguos tras un upgrade | Actualizar 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 cluster | Se instaló sin fijar versión en un cluster que ya tenía Ceph | El asistente web fija la release que ya corre el cluster. Por CLI, usar --version explícito |
| El pool se queda bloqueado sin aceptar escrituras | Se cruzó el umbral full, o hay menos réplicas disponibles que min_size | ceph 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 efecto | La misma opción está escrita en /etc/pve/ceph.conf, y el fichero tiene precedencia sobre la MON DB | Quitar la opción del fichero y volver a fijarla con ceph config set |
El autoscaler no ajusta el pg_num de algunos pools | Mezcla de pools con y sin device class en su regla CRUSH | ceph osd pool autoscale-status. Unificar el criterio: o todas las reglas con clase, o ninguna |
| CephFS de cluster externo no monta | El fichero de secret tiene formato de keyring | Debe ser /etc/pve/priv/ceph/<STORAGE_ID>.secret y contener solo la clave, sin la sección [client.userid] |
| RBD de cluster externo no autentica | Nombre 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 previo | ceph-volume lvm zap /dev/sdX --destroy |
| No puedes subir ISOs al storage Ceph | El plugin rbd solo admite images y rootdir | Crear un CephFS con pveceph fs create --add-storage y subir ahí |
| Borrar ficheros dentro de una VM no libera espacio en el pool | Falta discard=on en el disco de la VM | qm set <vmid> --scsi0 <storage>:<volumen>,discard=on y fstrim -av dentro del guest |
Un OSD siempre es el más lleno y dispara OSD_NEARFULL | Discos de tamaños desiguales en el mismo nodo | Igualar tamaños. Ceph rinde mejor con discos del mismo tamaño y en igual número por nodo |
MON_CLOCK_SKEW intermitente | Relojes desincronizados entre nodos | Revisar 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 CRUSH | Es una limitación del propio EC | size 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.