Whitepaper técnico — PodHeitor CloudStack para Bacula

Backup VM-level con CBT block-level (QEMU dirty bitmaps), replicación continua DR, cross-restore a Proxmox/Hyper-V/VMware y conversión de formato en streaming — capacidades que el plugin CloudStack de Bacula Enterprise no cubre.

Documento técnico complementario a la página del plugin PodHeitor CloudStack.

1. El problema: el plugin CloudStack de Bacula Enterprise es API-only

El Bacula Enterprise CloudStack plugin opera estrictamente sobre la API de CloudStack: snapshot de volumen, descarga vía API, restore vía API. Tiene tres límites duros:

  • Sin CBT real. El incremental de BEE es diff de snapshot a nivel API — granularidad de volumen, no de bloque. Para una VM de 200 GB con 500 MB modificados, BEE igual transfiere la diferencia completa de snapshot, no los bloques sucios.
  • Sin replicación continua. BEE no tiene modo DR push. Replicación a sitio secundario requiere una segunda solución (CloudStack Snapshot Schedule + copia manual).
  • Sin cross-restore. El backup CloudStack de BEE solo restaura a CloudStack. Migrar a Proxmox/Hyper-V/VMware exige conversión manual con qemu-img + reconstrucción de config.

El PodHeitor CloudStack Plugin elimina los tres cuellos con acceso directo KVM/libvirt vía NBD, dirty bitmap nativo de QEMU y pipeline de conversión en streaming.

2. Modelo arquitectónico — 100% Rust cdylib

v2.0.0+ es arquitectura 100% Rust. El .so FD-side es un cdylib puro (build desde ../PodHeitor Rust cdylib/crates/plugin-cloudstack/) que dlopen-ea en bacula-fd. Ningún source AGPLv3 de Bacula es vinculado estáticamente. El shim C++ legacy fue removido — todas las responsabilidades (identidad de plugin, validación de parámetros, driver PTCOMM, virtual-file buffering, restore replay) están reimplementadas en el framework Rust metaplugin-rs.

┌──────────────────────────────────────────────────────────┐
│  Bacula File Daemon (FD)                                 │
│  ┌────────────────────────────┐                          │
│  │  podheitor-cloudstack-fd.so│──PTCOMM──▶┌────────────┐ │
│  │  (Rust cdylib)             │◀─────────│  Rust      │ │
│  │                            │          │  Backend   │ │
│  └────────────────────────────┘          └─────┬──────┘ │
│                                                │        │
│  ┌──────────────────────────────────────────────┴─────┐ │
│  │   CloudStack API (HMAC-SHA1) + SSH/NBD data plane  │ │
│  └────────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────┘

El backend (~12.000 LOC Rust) es spawneado como subproceso por job — preservando el boundary PTCOMM de crash-isolation. El cdylib es mínimo: identidad de plugin + driver PTCOMM + virtual-file buffering. Toda la lógica de backup, restore, replicación y conversión vive en el backend.

3. Three-Layer Change Detection (CBT)

El incremental real de PodHeitor no es diff de snapshot — es un pipeline de tres capas que cubre el camino feliz y los casos patológicos:

Capa Mecanismo Función
L1 QEMU QMP dirty bitmap Solo bloques modificados desde el último backup entran al pipeline
L2 xxHash64 block hash Elimina falsos-positivos de resets sucios de bitmap (reboot duro de KVM, host crash)
L3 SIMD zero-block detection Elimina regiones esparsas/ceradas — beneficio de thin provisioning

Resultado típico: reducción de ventana de backup > 90% vs Full en incrementales sucesivos.

4. Modos de operación

Mode Propósito
(unset) Backup Bacula normal (Full o Incremental)
bitmap_push DR continuo — envía deltas de dirty-bitmap a dr_host
seed Sync full inicial antes de cambiar a bitmap_push
receiver Daemon DR-side — acepta bitmap pushes recibidos
daemon Sender de replicación long-running (out-of-band de los jobs Bacula)
failover_pre / failover_exec Promueve réplica DR a primary
failback_pre / failback_exec Re-sync primary tras failover y swap back
reprotect Re-establece replicación en dirección inversa
replication_status Query de salud sender/receiver

5. Cross-restore — conversión en streaming

El plugin restaura una VM CloudStack a hipervisor distinto del origen. Se selecciona con el parámetro cross_restore:

Target Conversión de disco Adaptación de guest
proxmox qcow2 → qcow2 (passthrough) o raw Generación de qm config; ajuste de driver virtio
hyperv qcow2 → vhdx (streaming vía qemu-img) VMCX XML; integration services
vmware qcow2 → vmdk (streaming) VMX file; VMware Tools handoff

La conversión es streaming: ningún archivo intermedio se materializa. El pipeline es NBD read → qemu-img convert (stdin) → SSH/SMB push (stdout). Para una VM de 100 GB yendo CloudStack→Hyper-V, eso evita 100 GB de I/O temporal en el FD host.

6. Data plane — tres modos NBD

El parámetro nbd_access_mode selecciona el camino de lectura de bytes desde el hipervisor KVM:

Modo Comportamiento Cuándo usar
ssh_tunnel (default) SSH al host KVM, abre túnel a puerto NBD local, cliente NBD conecta vía túnel Default seguro — no exige abrir 10809 en firewall
direct Cliente NBD conecta directo a kvm-host:10809 Cuando la red de backup está segregada y el firewall lo permite
api_only Fallback API-only (descarga de snapshot vía CloudStack) Cuando SSH al host KVM falla — log warning

Aritmética típica: direct entrega 3–5 GB/s en LAN 10 GbE; ssh_tunnel ~1.5–2.5 GB/s (limitado por overhead de cifrado); api_only raramente pasa de 200 MB/s.

7. Replicación continua DR (bitmap-push)

El modo bitmap_push convierte el plugin en un agente de replicación out-of-band: ciclos de cycle_interval segundos (default 300) leen el dirty bitmap actual, calculan delta vs último ciclo, envían a dr_host:dr_port sobre transporte AES-256-GCM con PSK derivado.

  • PSK ≥ 32 caracteres obligatorio.
  • Retry con backoff exponencial: retry_count=3, retry_delay_ms=5000, jitter retry_jitter_ms=1000.
  • Resiliencia: si el receiver cae, el sender mantiene el bitmap acumulado; la reconexión retoma del último ciclo confirmado.
  • Ahorro de banda: 95%+ vs copia full (delta-only push).

El flujo de failover automatiza la promoción: failover_pre drena pendientes, failover_exec presenta los disks de la réplica a una nueva VM CloudStack en el DR site. failback_pre/failback_exec + reprotect cierran el loop.

8. Performance

Métrica Valor típico
Throughput de Full backup 1.5–5 GB/s (depende de modo NBD, red, disco)
Reducción de ventana Incremental 90%+ vs Full (dirty bitmap + hash dedup)
Ahorro de banda en replicación 95%+ (delta-only push)
Compresión zstd (level 3) 50–60%
Memoria por disk backup concurrente ~17 MB (NBD buffers + zstd context + hash working set)
Hash lookup O(1) — array flat memory-mapped, OS page cache

9. Hash DB memory-mapped

El hash DB de PodHeitor es un array flat memory-mapped indexado por xxHash64. A diferencia de DBs tradicionales (LMDB, RocksDB), no hay latencia SSD en el camino caliente — el page cache del kernel mantiene el working set residente. Resultado:

  • Lookup O(1) sin syscall (mmap-only).
  • SSD-latency-independent: corra en HDD si quiere.
  • Working set escala con bloques únicos, no con volumen total.

10. Anti-patterns documentados

  • No deshabilite quiesce en workloads DB. Sin qemu-guest-agent freeze/thaw, los snapshots de DB son crash-consistent — válidos pero no application-consistent. Para Postgres/MySQL/MSSQL mantenga quiesce=true.
  • No use verify_ssl=false en producción. Importe la CA del CloudStack management al trust store del FD host. verify_ssl=false existe para PoC/lab.
  • No corra replicación bitmap_push sobre WAN sin cap. El ciclo default de 300s + delta puede saturar 100 Mbps en VMs write-heavy. Configure bandwidth_limit o aumente cycle_interval.

11. License posture

El plugin se distribuye bajo LicenseRef-PodHeitor-Proprietary. No vincula estáticamente ningún source AGPLv3 de Bacula. El binding es exclusivamente vía extern "C" independiente.

¿Listo para evaluar?

Trial gratuito de 30 días para workloads CloudStack calificadas (KVM, validado en CloudStack 4.16/4.19/4.20). Garantizamos al menos 50% de descuento vs Bacula Enterprise, Veeam, Commvault o NetBackup, con más funcionalidades incluidas — y cross-restore que ninguno de los tres ofrece.

Heitor Faria — Fundador, PodHeitor International
[email protected]
☎ +1 (789) 726-1749 · +55 (61) 98268-4220 (WhatsApp)
🔗 Página del plugin PodHeitor CloudStack

Disponível em: pt-brPortuguês (Portugués, Brasil)enEnglish (Inglés)esEspañol

Deja una respuesta