Virtualización

Un solo Proxmox Backup Server para varios clústeres: namespaces sin perder el orden

Por Equipo Cloud Privado · · 14 min de lectura
Imagen de portada del artículo «Un solo Proxmox Backup Server para varios clústeres: namespaces sin perder el orden»

Un vistazo en 33 segundos

  • Un mismo datastore de Proxmox Backup Server puede recibir copias de varios clústeres de Proxmox VE a la vez.
  • Los namespaces separan esas copias por origen sin partir el almacén de chunks: la deduplicación sigue siendo una sola.
  • Admiten anidamiento hasta 8 niveles, contando la raíz como primero, y permisos propios en cada nivel.
  • La retención se define por namespace; la recolección de basura, no: esa es del datastore entero.
  • El namespace se fija en el storage de PVE, no en el trabajo de copia: para escribir en dos namespaces desde un mismo clúster hacen falta dos storages.
  • Consolidar concentra el dominio de fallo. Cuatro clústeres colgando de un datastore es una decisión de arquitectura, no un detalle de configuración.

Llega el momento en que la infraestructura ya no es «el clúster». Son tres clústeres de Proxmox VE, un par de nodos sueltos en delegaciones y algo en una sede pequeña que nadie sabe muy bien de quién depende. Toca montar las copias, y la primera idea que se le ocurre a cualquiera es la misma: un datastore de Proxmox Backup Server para cada origen. Se entiende de un vistazo, cada entorno tiene su sitio y nadie pisa a nadie.

El problema es lo que te llevas por delante sin enterarte. Un datastore de PBS es, entre otras cosas, un dominio de deduplicación: los bloques repetidos se guardan una sola vez dentro de él, y solo dentro de él. Cuatro datastores son cuatro almacenes de bloques que no se hablan. Si tus tres clústeres corren las mismas plantillas de Debian, los mismos kernels y las mismas capas de aplicación —que es lo habitual—, estás guardando esos gigabytes idénticos cuatro veces.

Los namespaces existen justo para no tener que elegir entre orden y deduplicación. Y como todo en arquitectura, tienen su letra pequeña.

Primero, qué es un datastore de PBS

Un datastore no es una carpeta con los ficheros de cada máquina dentro. Es la unidad donde conviven tres cosas: los snapshots, sus índices y el almacén de bloques.

PBS trocea lo que respalda en chunks y los identifica por su contenido con SHA-256, así que dos bloques idénticos producen el mismo identificador y se guardan una sola vez. Los índices de cada snapshot son listas de referencias a esos bloques. Sobre el disco se ve así:

<raíz-del-datastore>/
├── .chunks/
├── vm/
├── ct/
└── host/

De ahí sale una propiedad que confunde a mucha gente cuando llega de otras herramientas: los datos viajan de forma incremental, pero cada snapshot representa una copia completa. No hay cadenas de full más incrementales que restaurar en orden ni una copia semanal que arrastre a las seis siguientes. Cada snapshot referencia todos los bloques que necesita, estén guardados desde hoy o desde hace ocho meses.

Y aquí está el detalle que decide la arquitectura: esa reutilización de bloques ocurre dentro del datastore. Nunca entre datastores distintos. Si el ahorro de espacio de PBS te sorprendió la primera vez que lo mediste, partirlo en cuatro es la forma más rápida de perderlo. Sobre por qué deduplicar arriba (en PBS, por contenido) suele rendir mejor que deduplicar abajo (en el sistema de ficheros) ya escribimos en ZFS: deduplicación frente a compresión, y la conclusión no cambia aquí.

Cuánto se pierde partiendo el datastore

Pon números encima. Un parque cualquiera de tamaño medio:

Clúster Producción
 ├── 25 VM Debian
 └── 10 VM Ubuntu

Clúster Desarrollo
 ├── 15 VM Debian
 └── 5 VM Ubuntu

Clúster Preproducción
 └── 12 VM Debian

Nodo PVE suelto (delegación)
 └── 4 VM Debian

Son 71 máquinas de las que 56 comparten distribución. Kernel, librerías del sistema, paquetes base, binarios de la aplicación, el mismo agente de monitorización en todas: bloques idénticos, byte a byte, repetidos decenas de veces.

Con cuatro datastores separados guardas ese material común cuatro veces. Con uno solo, una. Cuánto ahorras exactamente depende de lo parecidas que sean de verdad tus cargas, y conviene decirlo sin adornos: el ahorro grande está en el sistema operativo y en las plantillas, no en los datos. Bases de datos activas, ficheros ya comprimidos, volúmenes cifrados dentro del invitado o VMs que no se parecen en nada comparten mucho menos de lo que uno espera. Si tu parque son treinta máquinas nacidas de la misma plantilla, como pasa en cuanto aprovisionas con Terraform u OpenTofu, consolidar se nota mucho. Si son diez servidores de datos que no tienen nada que ver entre sí, se nota poco.

Namespaces: la jerarquía que faltaba

Un namespace es una separación lógica dentro del datastore. Piensa en subdirectorios con permisos, no en almacenes independientes: el árbol de copias se organiza, el almacén de bloques sigue siendo uno.

datastore: empresa

├── produccion
│   ├── vm/100
│   ├── vm/101
│   └── vm/102

├── desarrollo
│   ├── vm/100
│   └── vm/103

├── preproduccion
│   └── vm/100

└── delegacion-madrid
    └── vm/200

Fíjate en las tres vm/100. Sin namespaces eso es una colisión que te obliga a renumerar máquinas o a montar datastores aparte; con ellos, cada una vive en su rama y nadie discute. Es la razón por la que el propio Proxmox recomienda namespaces en cuanto un datastore recibe copias de varias instancias de PVE.

La documentación permite anidarlos hasta 8 niveles de profundidad, contando el namespace raíz como el primero, y cada nivel admite copias de máquinas virtuales, contenedores y hosts además de otros namespaces. Da para estructuras muy detalladas:

infraestructura
├── cluster-pve-01
├── cluster-pve-02
├── cluster-pve-03
├── nodo-edge-01
└── nodo-edge-02

O para separar por emplazamiento y luego por entorno:

empresa
└── madrid
    ├── produccion
    └── desarrollo

Que quepan ocho niveles no significa que quieras ocho. En un parque que gestiona un mismo equipo, dos niveles se leen de un vistazo a las tres de la mañana y cinco no. La jerarquía es para orientarte, no para modelar el organigrama.

Varios clústeres de Proxmox VE escribiendo en un mismo datastore de Proxmox Backup Server Cuatro orígenes distintos, tres clústeres de Proxmox VE y un nodo suelto de delegación, envían sus copias al mismo datastore, llamado empresa. Dentro del datastore cada origen escribe en su propio namespace: produccion, desarrollo, preproduccion y delegacion. Los namespaces separan la vista y los permisos, pero todos apoyan sobre el mismo almacén de chunks, así que un bloque idéntico se guarda una sola vez para todo el datastore. Como cada namespace es una rama distinta, tres máquinas con el identificador 100 en clústeres distintos conviven sin conflicto. Producción PVE · 35 VM Desarrollo PVE · 20 VM Preproducción PVE · 12 VM Delegación 1 nodo · 4 VM datastore: empresa produccion vm/100 · vm/101 desarrollo vm/100 · vm/103 preproduccion vm/100 delegacion vm/200 Almacén de chunks compartido .chunks/ · SHA-256 · un bloque idéntico se guarda una sola vez Tres vm/100 en ramas distintas: cero conflictos de identificador, una sola deduplicación.
Varios clústeres de Proxmox VE escribiendo en un mismo datastore de Proxmox Backup Server Cuatro orígenes distintos, tres clústeres de Proxmox VE y un nodo suelto de delegación, envían sus copias al mismo datastore, llamado empresa. Dentro del datastore cada origen escribe en su propio namespace: produccion, desarrollo, preproduccion y delegacion. Los namespaces separan la vista y los permisos, pero todos apoyan sobre el mismo almacén de chunks, así que un bloque idéntico se guarda una sola vez para todo el datastore. Como cada namespace es una rama distinta, tres máquinas con el identificador 100 en clústeres distintos conviven sin conflicto. Producción PVE · 35 VM Desarrollo PVE · 20 VM Preprod. PVE · 12 VM Delegación 1 nodo · 4 VM datastore: empresa produccion vm/100 · vm/101 desarrollo vm/100 · vm/103 preproduccion vm/100 delegacion vm/200 Almacén de chunks uno solo para todo el datastore Tres vm/100 sin conflicto, una sola deduplicación.
Los namespaces organizan la vista; el almacén de chunks sigue siendo uno solo para todo el datastore. Ahí está el ahorro.

Crear uno desde la línea de comandos del PBS es inmediato:

proxmox-backup-manager namespace create produccion
proxmox-backup-manager namespace create desarrollo

Conectar cada clúster con su namespace

En el lado de Proxmox VE, el namespace forma parte de la definición del almacenamiento. Añades el mismo PBS y el mismo datastore en cada clúster, cambiando solo esa línea:

pvesm add pbs backup-pbs \
    --server pbs.example.net \
    --datastore empresa \
    --namespace produccion \
    --username backup@pbs!cluster-prod \
    --password '<TOKEN>' \
    --fingerprint '<FINGERPRINT>'

Y en el clúster de desarrollo, lo mismo con otro destino y otro token:

pvesm add pbs backup-pbs \
    --server pbs.example.net \
    --datastore empresa \
    --namespace desarrollo \
    --username backup@pbs!cluster-dev \
    --password '<TOKEN>' \
    --fingerprint '<FINGERPRINT>'

En /etc/pve/storage.cfg queda como una propiedad más del storage:

pbs: backup-pbs
        server pbs.example.net
        datastore empresa
        namespace produccion
        content backup
        username backup@pbs!cluster-prod
        fingerprint 09:54:ef:..snip..:4e:3c:b2

Desde la interfaz es el campo Namespace del diálogo de añadir almacenamiento PBS, disponible desde Proxmox VE 7.2-4. Si no lo ves, mira la versión antes de dudar de la documentación.

Un detalle que ahorra un rato de pelea: el namespace se define en el almacenamiento, no en el trabajo de copia. No puedes montar un job que respalde a produccion y otro que respalde a test apuntando al mismo storage, porque el destino ya está decidido antes de llegar al job. Cuando un mismo clúster tiene que escribir en dos namespaces —lo típico, separar las VMs de producción de las de laboratorio dentro del mismo clúster—, defines dos storages PBS distintos contra el mismo servidor y el mismo datastore, cada uno con su namespace, y asignas cada trabajo al suyo. Funciona bien, pero hay que saberlo de antemano para no diseñar la nomenclatura al revés.

Un token por clúster, no uno para todos

Aprovecha que estás repartiendo orígenes para repartir también credenciales. La tentación de reutilizar un token con permisos sobre todo el datastore «total, es la misma empresa» sale cara el día que un nodo comprometido resulta tener llave de las copias de los demás.

PBS aplica permisos a nivel de namespace: Datastore.Backup sobre /datastore/empresa/produccion deja escribir ahí y solo ahí, y para ver un datastore basta con tener algún privilegio en alguno de sus namespaces. Un token por clúster, acotado a su rama, convierte «me han entrado en un hipervisor» en un incidente feo pero acotado, en vez de en la pérdida de todo el historial de copias. Es la misma lógica de compartimentar que se aplica al acceso de los propios nodos, llevada al servidor de copias, y encaja con cómo planteamos la seguridad de la plataforma en general.

Y si en el mismo movimiento activas el cifrado del lado cliente —la misma idea que el cifrado en reposo con LUKS o ZFS, pero aplicada antes de que el dato salga del hipervisor—, el datastore compartido guarda datos que no puede leer. No viene activado por defecto: es una decisión tuya, con la responsabilidad de custodiar la clave que conlleva. Sin esa clave no hay restauración, ni para ti ni para nadie.

Retención distinta sin datastores distintos

Compartir almacén no obliga a compartir política. Los trabajos de prune de PBS aceptan un namespace con el parámetro ns y una profundidad máxima con max-depth, así que cada rama conserva lo suyo.

Producción, con historial largo:

proxmox-backup-manager prune-job create prod-prune \
    --store empresa \
    --ns produccion \
    --keep-daily 14 \
    --keep-weekly 8 \
    --keep-monthly 12 \
    --schedule "daily"

Desarrollo, donde nadie va a pedir la copia de hace cinco meses:

proxmox-backup-manager prune-job create dev-prune \
    --store empresa \
    --ns desarrollo \
    --keep-last 2 \
    --keep-daily 3 \
    --schedule "daily"

Ojo con un solape clásico: la retención puede definirse en dos sitios. En el storage de PVE (la opción prune-backups, que actúa al terminar la copia) y en el prune job del PBS. Si configuras las dos, mandan las dos, y el resultado efectivo es la más agresiva. No es un error grave, pero sí es de esos que se descubren tarde y mal, cuando falta una copia que alguien juraba tener. Elige un sitio, documéntalo y deja el otro en keep-all.

Prune borra snapshots; la GC libera espacio

Aquí es donde la arquitectura compartida enseña su mecánica, y conviene entenderla antes de montar nada.

El prune elimina snapshots según las reglas de retención, y punto: quita entradas del índice. El espacio no aparece ahí. Un bloque no puede desaparecer del disco mientras algún otro snapshot lo siga necesitando, y en un datastore compartido «algún otro» puede estar en un namespace que no has tocado.

De eso se encarga la recolección de basura (GC), que trabaja en dos fases. Primero marca: recorre todos los ficheros de índice del datastore y va actualizando el atime de cada chunk referenciado. Después barre: los bloques cuyo atime sea anterior a un corte de 24 horas y 5 minutos antes del inicio de la recolección se consideran huérfanos y se borran.

Dos consecuencias prácticas, y las dos importan más cuanto más consolidas:

  • La GC es del datastore, no del namespace. No existe «recolectar solo desarrollo». Un bloque que produción sigue usando sobrevive aunque el snapshot de desarrollo que también lo referenciaba se haya podado esta mañana, que es exactamente lo que quieres. A cambio, la fase de marcado recorre los índices de todos los namespaces, así que la ventana de mantenimiento crece con el conjunto, no con la parte.
  • El espacio no se libera cuando podas, sino cuando recolectas. Si alguien mira el disco justo después de un prune agresivo y no ve bajar la ocupación, no está roto. Falta la GC, y aún así solo caerá lo que ya no referencia nadie.
Prune por namespace y recolección de basura por datastore en Proxmox Backup Server Arriba, dos namespaces del mismo datastore con políticas de retención distintas: produccion conserva catorce diarios y ocho semanales, así que mantiene cuatro de sus seis snapshots, mientras desarrollo, con keep-last 2 y tres diarios, se queda con uno. Podar solo elimina snapshots, no libera espacio en disco. Abajo, la recolección de basura actúa sobre el datastore entero y no sobre un namespace concreto: marca actualizando el tiempo de acceso de todo bloque referenciado y después barre los que llevan más de veinticuatro horas y cinco minutos sin marcar. Un bloque que produccion sigue usando sobrevive aunque el snapshot de desarrollo que también lo referenciaba se haya podado; solo desaparece el bloque que ya no referencia nadie. prune · se define namespace a namespace produccion keep-daily 14 · keep-weekly 8 4 snapshots se quedan · 2 se podan hoy desarrollo keep-last 2 · keep-daily 3 1 se queda · 5 se podan hoy podar quita snapshots, no bloques garbage collection · del datastore entero chunk compartido produccion lo sigue referenciando sobrevive al prune de desarrollo chunk huérfano ya no lo referencia ningún snapshot del datastore: se barre marca: refresca el atime de lo referenciado · barre: lo anterior al corte de 24 h 5 min
Prune por namespace y recolección de basura por datastore en Proxmox Backup Server Arriba, dos namespaces del mismo datastore con políticas de retención distintas: produccion conserva catorce diarios y ocho semanales, así que mantiene cuatro de sus seis snapshots, mientras desarrollo, con keep-last 2 y tres diarios, se queda con uno. Podar solo elimina snapshots, no libera espacio en disco. Abajo, la recolección de basura actúa sobre el datastore entero y no sobre un namespace concreto: marca actualizando el tiempo de acceso de todo bloque referenciado y después barre los que llevan más de veinticuatro horas y cinco minutos sin marcar. Un bloque que produccion sigue usando sobrevive aunque el snapshot de desarrollo que también lo referenciaba se haya podado; solo desaparece el bloque que ya no referencia nadie. prune · namespace a namespace produccion keep-daily 14 · keep-weekly 8 4 se quedan · 2 se podan desarrollo keep-last 2 · keep-daily 3 1 se queda · 5 se podan podar no libera bloques garbage collection · del datastore chunk compartido produccion lo referencia: queda chunk huérfano nadie lo referencia: se barre corte: atime anterior a 24 h 5 min
Cada namespace poda a su ritmo; el barrido es común. Un bloque solo desaparece cuando no lo referencia ningún snapshot del datastore.

Lo que ganas y lo que concentras

Un datastore por clústerDatastore compartido + namespaces
Vista organizada por origen
Dominio de deduplicaciónUno por clústerCompartido
Retención diferenciadaSí, por namespace
Permisos por entornoSí, por namespace
Recolección de basuraIndependienteDel datastore entero
SupervisiónVarios datastores que vigilarUno principal
Ventanas de GC y verificaciónRepartidasCompartidas y más largas
Dominio de falloSeparadoConcentrado

Las dos últimas filas son las que deciden, y ninguna de las dos aparece en los folletos.

Si cuatro clústeres escriben en el mismo datastore y ese almacenamiento se cae, se corrompe o se llena, los cuatro se quedan a la vez sin repositorio de copias. No es que pierdas los datos —para eso está la copia remota, luego volvemos—, es que pierdes la capacidad de restaurar en el peor momento posible, que es justo cuando suele hacer falta. Deduplicar mejor está muy bien; no es criterio suficiente para decidir la topología de tu plataforma de copias.

Hay escenarios donde separar sigue siendo lo correcto. Un entorno con una exigencia regulatoria concreta que pida aislamiento demostrable. Un clúster cuyas copias necesiten un almacenamiento de otra clase, más rápido o más barato según el caso. Una carga crítica que merezca su propio dominio de fallo aunque renuncies a parte del ahorro. O simplemente el tamaño: la documentación de PBS avisa de que un datastore aloja tantas copias como aguante el almacenamiento que hay debajo, y consolidar no elimina los requisitos de IOPS, memoria, CPU ni ventana de mantenimiento. Los suma.

La arquitectura sensata suele ser mixta

No hay que elegir entre un datastore para todo y uno por clúster. En la práctica, lo que mejor funciona en parques medianos es partir por criticidad, no por clúster:

PBS

├── datastore-general
│   ├── namespace: desarrollo
│   ├── namespace: testing
│   ├── namespace: servicios-internos
│   └── namespace: edge

└── datastore-critico
    └── namespace: produccion

Todo lo que se parece comparte deduplicación en el general, y lo que no puede permitirse compartir suerte con el resto vive aparte, con su propio almacenamiento y sus propias ventanas. Dos datastores en vez de cinco, y el que importa aislado.

Falta la última pieza, y es la que más gente se salta: un datastore de PBS no es una estrategia de protección de datos. Es un repositorio. PBS permite configurar servidores remotos y sync jobs que copian contenido de un PBS a otro, en modo pull o push, y esos trabajos también entienden de namespaces (ns, remote-ns, max-depth), así que puedes replicar solo la rama que te interesa. Combinado con el backend S3 y el sync en paralelo, la foto completa queda así:

Proxmox VE Cluster 1 ─┐
Proxmox VE Cluster 2 ─┼──> PBS principal ───> PBS remoto / S3
Proxmox VE Cluster 3 ─┤        │
Nodo suelto ──────────┘        ├─ namespaces
                               ├─ deduplicación
                               ├─ prune
                               ├─ verify
                               └─ garbage collection

Cada pieza resuelve un problema distinto y ninguna sustituye a las demás. La deduplicación aprovecha el espacio, los namespaces ordenan y acotan permisos, la verificación detecta la corrupción silenciosa antes de que la descubras restaurando, y el sync a otro sitio es lo único que te salva de perder el emplazamiento entero. Eso último es la copia «fuera» de la regla 3-2-1, y no la cubre ningún namespace.

Cuándo consolidar y cuándo no

Un datastore compartido con namespaces encaja bien cuando los clústeres son de la misma organización, corren sistemas y plantillas parecidas, y pueden compartir razonablemente el mismo dominio de almacenamiento. Cuanto más se parezcan las cargas, más paga la consolidación.

Sigue mereciendo la pena separar cuando:

  • necesitas aislamiento físico o administrativo demostrable, no solo lógico;
  • un entorno pide un almacenamiento con otras características de rendimiento o coste;
  • alguna normativa te obliga a mantener determinados datos aparte;
  • un sistema crítico no debe depender de la disponibilidad del resto;
  • el volumen de una sola carga condicionaría las ventanas de GC y verificación de todos los demás.

La decisión correcta no es «un datastore por clúster» ni «todo en uno», sino repartir con criterio: los datastores delimitan almacenamiento, deduplicación y fallo; los namespaces ordenan orígenes y permisos; la retención se ajusta rama por rama. Y si al dibujarlo te sale un único punto del que cuelga absolutamente todo, ya sabes qué toca mirar: hacia dónde sale la segunda copia. Los objetivos de RTO y RPO que hayas firmado deberían decidir eso, no la comodidad de tener un solo panel que vigilar.

Si además gestionas los clústeres desde una capa común, con el Proxmox Datacenter Manager o con PegaProx, esa nomenclatura de namespaces te va a servir para algo más que ordenar copias: acaba siendo el vocabulario con el que el equipo nombra el parque entero. Elígela pensando en eso.

Preguntas frecuentes

¿PBS deduplica entre copias de clústeres distintos?

Sí, siempre que estén en el mismo datastore. Los bloques idénticos se guardan una vez para todo el datastore, y los namespaces no rompen esa reutilización: separan la vista y los permisos, no el almacén de chunks. Entre datastores diferentes no hay deduplicación posible.

¿Puedo poner una retención distinta en cada namespace?

Sí. Los prune jobs aceptan el parámetro ns y la profundidad max-depth, y admiten las reglas habituales keep-last, keep-daily, keep-weekly, keep-monthly y keep-yearly. Vigila no duplicar la política en el storage de PVE (prune-backups) y en el prune job del PBS a la vez.

¿Puedo elegir el namespace en cada trabajo de copia de Proxmox VE?

No. El namespace es una propiedad del almacenamiento, no del job. Si un mismo clúster necesita escribir en dos namespaces, define dos storages PBS contra el mismo servidor y datastore con namespaces distintos y asigna cada trabajo al que corresponda.

¿Es siempre mejor un único datastore?

No. Compartirlo mejora la deduplicación y simplifica la supervisión, pero concentra el dominio de fallo y alarga las ventanas de recolección de basura y verificación, que son del datastore entero. Separar sigue siendo razonable por aislamiento, rendimiento, coste o cumplimiento.

¿Por qué no baja el espacio después de podar?

Porque el prune solo elimina snapshots. El espacio lo libera la recolección de basura, que marca los bloques referenciados y barre los que llevan más de 24 horas y 5 minutos sin que nadie los toque. Y un bloque que otro namespace siga usando no se borra, que es precisamente lo que protege tus copias en un datastore compartido.

Cómo lo montamos nosotros

En las plataformas que gestionamos, la conversación sobre copias nunca empieza por el datastore. Empieza por cuánto puedes perder y cuánto puedes tardar en volver, y de ahí sale todo lo demás: cuántos dominios de fallo hace falta mantener separados, qué se replica fuera y con qué frecuencia, y quién tiene llave de qué.

Si estás en el punto de tener varios clústeres y copias repartidas sin un criterio claro, mira nuestra página de Proxmox Backup Server y la de continuidad y recuperación. Y si prefieres que lo revisemos contigo antes de mover nada, cuéntanos cómo está montado: lo miramos y te decimos qué consolidaríamos y qué no.

Fuentes