Whitepaper técnico — PodHeitor CloudStack para Bacula

Whitepaper técnico — PodHeitor CloudStack para Bacula

PodHeitor CloudStack Backup, Replication and Conversion Plugin for Bacula

Versão 2.0.0 — Abril 2026

Autor: Heitor Faria   Contato: heitor@opentechs.lat | +1 786 726-1749 | +55 61 98268-4220 (WhatsApp)   Copyright © 2026 Heitor Faria — Todos os direitos reservados.


OFERTA COMERCIAL ESPECIAL

Traga sua proposta de contratação ou renovação do Bacula Enterprise, Veeam, Commvault ou NetBackup. Damos no mínimo 50% de desconto, com muito mais funcionalidades.

Heitor Faria — heitor@opentechs.lat | +1 786 726-1749 | +55 61 98268-4220 (WhatsApp)


Sumário

  1. Sumário Executivo
  2. Contexto e Oportunidade de Mercado
  3. Casos de Uso
  4. Arquitetura Técnica
  5. Funcionalidades Detalhadas
  6. Compatibilidade e Requisitos
  7. Guia de Instalação
  8. Configuração e Sizing
  9. Manual de Uso
  10. Tabelas de Parâmetros
  11. Exemplos de Configuração de FileSet
  12. Performance e Benchmarks
  13. Segurança
  14. Monitoramento e Observabilidade
  15. Troubleshooting
  16. Comparativo com Concorrentes
  17. Roadmap
  18. Referências

1. Sumário Executivo

O PodHeitor CloudStack Backup, Replication and Conversion Plugin for Bacula é a solução definitiva para backup e recuperação de máquinas virtuais em ambientes Apache CloudStack, integrada nativamente ao Bacula Community. Desenvolvido por Heitor Faria, o plugin entrega funcionalidades que superam até as soluções pagas do mercado — a um custo substancialmente menor.

O que é?

Um plugin para o File Daemon (FD) do Bacula Community que permite:

  • Backup completo e incremental de VMs CloudStack com rastreamento de blocos modificados (CBT) via QEMU dirty bitmaps
  • Replicação contínua para site de DR com transporte criptografado AES-256-GCM
  • Restauração cruzada entre hypervisors: CloudStack → Proxmox VE, Hyper-V, VMware vSphere
  • Conversão de formatos de disco: qcow2 ↔ vhdx ↔ vmdk ↔ raw

Por que é diferente?

┌─────────────────────────────────────────────────────────────────────┐
│  COMPARATIVO RÁPIDO                                                   │
├──────────────────────────┬──────────────────┬────────────────────────┤
│ Funcionalidade           │ Bacula Enterprise│ PodHeitor CloudStack   │
├──────────────────────────┼──────────────────┼────────────────────────┤
│ Backup Incremental CBT   │ Snapshot diff    │ Block-level dirty bitmap│
│ Redução de janela backup │ ~30%             │ 90%+                   │
│ Replicação DR            │ Não disponível   │ Bitmap-push contínuo   │
│ Cross-restore            │ Não disponível   │ Proxmox/Hyper-V/VMware │
│ Métricas Prometheus      │ Não disponível   │ Endpoint nativo        │
│ Logging JSON estruturado │ Não disponível   │ Nativo                 │
│ Custo (vs Enterprise)    │ 100% (base)      │ Significativamente menor│
└──────────────────────────┴──────────────────┴────────────────────────┘

Proposta de Valor

Benefício Impacto
Redução de 90%+ na janela de backup Menos impacto em produção, mais VMs protegidas
RPO próximo de zero com replicação contínua DR de alto nível sem custo de licença adicional
Cross-restore entre hypervisors Migração sem re-instalação de SO, sem re-configuração
Integração nativa com Bacula Catálogo, políticas de retenção e agendamento unificados
Construído em Rust Memory-safety nativo, sem pausas de GC, alta estabilidade em produção crítica

2. Contexto e Oportunidade de Mercado

Apache CloudStack no Mercado

O Apache CloudStack é a plataforma de IaaS preferida de:

  • Telecomunicações (Telcos europeus, asiáticos e latino-americanos)
  • Provedores de Serviços de Internet (ISPs) e Hosters
  • Empresas com nuvem privada que precisam de controle total
  • Operadoras de serviços financeiros com requisitos regulatórios rígidos

Estima-se mais de 50.000 instalações ativas de CloudStack globalmente, com crescimento acelerado nos segmentos Telco e hosting.

O Problema de Backup no CloudStack

O CloudStack, por design, provê apenas snapshots e templates — sem orquestração nativa de backup. Isso significa:

  1. Sem rastreamento de blocos modificados (CBT): Cada snapshot é uma cópia completa do volume — janelas de backup longas, alto consumo de armazenamento.
  2. Sem gestão de ciclo de vida: Snapshots se acumulam consumindo storage primário caro.
  3. Sem catálogo de backup: Impossível saber “qual snapshot corresponde a qual ponto no tempo para qual VM”.
  4. Sem replicação para DR: Não há mecanismo nativo de replicação em tempo quase-real.
  5. Sem restauração entre hypervisors: VMs KVM/CloudStack não podem ser restauradas no Proxmox ou VMware sem trabalho manual complexo.

A Solução PodHeitor

O plugin PodHeitor integra o Apache CloudStack ao ecossistema do Bacula Community, que já resolve:

  • Agendamento e políticas de retenção
  • Catálogo centralizado
  • Armazenamento hierárquico (disco → fita → cloud)
  • Alertas e relatórios

O plugin adiciona a camada que faltava: a extração de dados das VMs de forma eficiente e segura.


3. Casos de Uso

Caso de Uso 1: Proteção de VMs de Produção

Cenário: Empresa de hosting com 500 VMs em CloudStack, SLA de RPO 1h/RTO 4h.

Solução:

  • Backup full semanal (domingo 02:00)
  • Backup incremental diário (segunda a sábado 02:00)
  • CBT reduz o incremental de horas para minutos
  • Retenção automática via políticas Bacula

Resultado esperado:

  • Janela de backup incremental: 15-30 min (vs. 3-4h sem CBT)
  • Consumo de storage: -70% (deduplicação + compressão zstd)
  • RTO efetivo: < 1h para VMs críticas

Caso de Uso 2: Disaster Recovery com RPO Mínimo

Cenário: Banco regional com site principal em CloudStack/KVM, site DR em co-location.

Solução:

  • Replicação contínua com mode=bitmap_push
  • cycle_interval=60 (ciclos a cada 60 segundos)
  • Transporte criptografado AES-256-GCM entre sites
  • Failover com mode=failover_exec promove DR para primário

Fluxo de DR:

Site Principal                        Site DR
─────────────                         ──────────
CloudStack KVM                         CloudStack KVM
    │                                       │
    │◄──── Replicação bitmap-push ─────────►│
    │      (delta a cada 60s)               │
    │      AES-256-GCM encrypted            │
    │                                       │
    ├──── Falha detectada                   │
    │                                       │
    └──────── failover_exec ───────────────►│
              (&lt; 2 min para power-on)       │

Resultado esperado:

  • RPO: 60-120 segundos
  • RTO: < 5 minutos (tempo de power-on da VM)
  • Bandwidth usado: apenas delta (< 5% do volume total em uso normal)

Caso de Uso 3: Migração entre Hypervisors

Cenário: Empresa migrando 200 VMs de CloudStack/KVM para Proxmox VE.

Solução:

  • Backup das VMs no CloudStack com o plugin PodHeitor
  • Restauração cruzada com cross_restore=proxmox
  • Plugin converte qcow2 → qcow2 com adaptação de drivers virtio
  • VMs prontas para uso no Proxmox sem re-instalação

Vantagens:

  • Zero re-instalação de SO
  • Drivers VirtIO injetados automaticamente
  • Restauração em paralelo (múltiplas VMs simultâneas)
  • Rollback possível: CloudStack mantém as VMs originais durante migração

Caso de Uso 4: Consolidação Multi-hypervisor

Cenário: Empresa com infraestrutura híbrida — CloudStack + VMware + Hyper-V — e necessidade de política unificada de backup.

Solução:

  • PodHeitor CloudStack Plugin (este) + PodHeitor Proxmox Plugin + PodHeitor HyperV Plugin
  • Um único Bacula Director gerencia todos os ambientes
  • Catálogo unificado, relatórios consolidados
  • Cross-restore entre qualquer hypervisor

Caso de Uso 5: Conformidade e Auditoria (LGPD/GDPR/SOX)

Cenário: Fintech com obrigações regulatórias de retenção de 7 anos, audit trail de backups.

Solução:

  • Catálogo Bacula mantém histórico completo de todos os jobs
  • Log estruturado em JSON (log_format=json) para SIEM
  • Métricas Prometheus para auditoria de SLA
  • Criptografia AES-256-GCM em trânsito; políticas de criptografia no storage

4. Arquitetura Técnica

Visão Geral

Bacula Director ──► Bacula Storage Daemon (disco, fita, S3, dedup)
       │
       ▼ protocolo Bacula
Bacula File Daemon (cloudstack-fd)
  └── podheitor-cloudstack-fd.so   ← plugin carregado via dlopen
        │  canal interno (PTCOMM)
        ▼
  podheitor-cloudstack-backend     ← toda a lógica de backup/restore/DR
        │
        ├── CloudStack Mgmt Server  (REST API HMAC-SHA1)
        │
        └── KVM Hosts (SSH)
              ├── qemu-nbd  (leitura de blocos)
              └── libvirt/QMP  (dirty bitmaps)

Componentes

podheitor-cloudstack-fd.so — carregado pelo bacula-fd via dlopen; exporta a interface de plugin ao Bacula FD, gerencia o canal de comunicação com o backend, faz buffer de “virtual files” e roteamento de I/O de restore.

podheitor-cloudstack-backend — binário independente em Rust (~12.000 linhas de código próprio) com toda a lógica de backup, restore, replicação e conversão. Distribuído pronto para uso, sem dependências de compilação no host de produção. Subcomandos: backup, restore, check, version.

Canal de comunicação interno (PTCOMM) — protocolo binário otimizado (pipes stdin/stdout com framing de 4 bytes de comprimento + payload JSON/binário), projetado para baixa latência em alta concorrência. Fluxo: Bacula FD → startBackupFile → plugin serializa e aciona o backend → backend enumera VMs, cria snapshots, inicia qemu-nbd, lê e comprime blocos → streaming de volta ao FD via pluginData.

Three-Layer Change Detection (CBT)

O sistema incremental usa três camadas em série para máxima eficiência:

  1. QEMU QMP Dirty Bitmap — o QEMU mantém um bitmap de blocos modificados desde o último backup. O plugin consulta via QMP (query-block-dirty-bitmap, nome podheitor-cbt). Apenas blocos com bit=1 seguem adiante. Redução típica: 90–99% do volume total.
  2. xxHash64 Verification — para cada bloco marcado sujo, lê via NBD, calcula xxHash64 e compara com o hash do backup anterior. Blocos com hash idêntico são descartados (falsos positivos do bitmap). Isso elimina o overhead de bitmaps não limpos após crashes.
  3. SIMD Zero-Block Detection — blocos que passaram nas camadas anteriores são verificados via SIMD quanto a conteúdo totalmente zero. Blocos zero são registrados como “zero run” no stream sem transmitir dados. Benefício direto para VMs com thin provisioning e muito espaço livre.

Hash DB

Cada VM tem um arquivo de hash memory-mapped (hash_dir/vm-&lt;UUID&gt;-disk-&lt;N&gt;.hdb) com entradas de 16 bytes (block_offset + xxHash64). Lookup O(1) por binary search. Consumo de memória: ~1,6 MB por VM de 100 GB com blocos de 1 MB.


5. Funcionalidades Detalhadas

5.1 Backup Full

Fluxo: Autenticação HMAC-SHA1 na API CloudStack → listagem das VMs conforme padrão vm= → para cada VM: freeze via qemu-guest-agent (se quiesce=true), createSnapshot na API, thaw, descoberta do path do snapshot no KVM host via SSH, início do qemu-nbd em modo read-only, leitura bloco a bloco (SIMD zero-detection + xxHash64 + compressão zstd), streaming ao Bacula FD, atualização do Hash DB, limpeza do snapshot CloudStack e registro de checkpoint no working_dir.

5.2 Backup Incremental

Fluxo: Verificação de backup anterior (Hash DB + QEMU bitmap) → para cada VM: criação do bitmap podheitor-cbt caso não exista, snapshot, consulta ao bitmap sujo via QMP, leitura via NBD de cada bloco marcado, comparação xxHash64 com hash anterior (elimina falsos positivos), inclusão apenas dos blocos realmente modificados no stream, atualização do Hash DB e reset do bitmap para o próximo ciclo.

Economia típica:

  • VM 100 GB com 5% de mudança diária: 5 GB via incremental vs 100 GB full
  • Com compressão zstd level 3: ~2,5 GB transferidos
  • Redução de 97,5% no volume de dados transferidos

5.3 Replicação Contínua (DR)

Modos:

Modo Descrição Uso
seed Sincronização inicial completa Primeiro setup do DR
bitmap_push Envio contínuo de deltas Operação normal de DR
receiver Receptor no site DR Executado no site DR
daemon Sender contínuo (fora de jobs Bacula) DR autônomo
failover_exec Promover DR para primário Executado em evento de desastre
failback_exec Re-sync após failover Retorno ao site principal
reprotect Estabelecer replicação no sentido inverso Após failover
replication_status Consultar saúde do par de replicação Monitoramento

Protocolo de replicação: O sender estabelece canal TCP com PSK → HKDF-SHA256 → AES-256-GCM. A cada cycle_interval segundos: consulta dirty bitmap via QMP local, lê blocos modificados via NBD, calcula xxHash64, comprime com zstd e envia deltas criptografados ao receiver. O receiver aplica ao disco réplica e retorna ACK. O bitmap é resetado para o próximo ciclo.

Largura de banda típica em operação:

  • Servidor DB ativo (5% mudança/hora): ~500 MB/h
  • Servidor web estático (0,5% mudança/hora): ~50 MB/h
  • VM idle (0,01% mudança/hora): ~1 MB/h

5.4 Restauração

Restauração no CloudStack (where=/)

Leitura do stream Bacula → reconstrução do disco raw em working_dir → conversão raw→qcow2 via qemu-img → servidor HTTP temporário (Python 3) → registerTemplate com directdownload=true na API CloudStack → deployVirtualMachine → ligar VM se start_vm=true → limpeza.

Restauração para filesystem (where=/path)

Extrai cada disco como /path/vm-&lt;name&gt;/disk-&lt;N&gt;.raw e a metadata como metadata.json. Opcionalmente converte para qcow2 se cross_restore=proxmox.

5.5 Restauração Cruzada (Cross-Restore)

Target Formato de Saída Adaptação de Guest OS
proxmox / pve .qcow2 Drivers VirtIO para disco, rede e balloon
hyperv / hyper-v .vhdx Drivers Hyper-V (storvsc, netvsc, vmbus)
vmware / vsphere .vmdk VMware Tools (pvscsi, vmxnet3)

Processo de guest adaptation: O plugin monta o disco restaurado via NBD loopback, detecta o SO (Linux: /etc/os-release; Windows: registry), injeta os drivers correspondentes ao hypervisor de destino (módulos virtio para Linux via dracut/initramfs; drivers .inf + registry para Windows), converte o disco para o formato alvo e transfere ao hypervisor via API ou SCP.

5.6 Conversão de Formatos de Disco

Suporta: raw ↔ qcow2 ↔ vhdx ↔ vmdk (qualquer combinação via staging em raw). Características: streaming sem buffer completo em RAM; VHDX com CRC32C Castagnoli correto no header; VMDK em formato streamOptimized para ESXi; sparse (blocos zero não ocupam espaço no arquivo de saída).


6. Compatibilidade e Requisitos

Matriz de Compatibilidade Bacula × CloudStack

Bacula Community CloudStack KVM host OS Status
15.0.3 4.20 Ubuntu 22.04 ✅ Validado completo
15.0.3 4.19 Oracle Linux 9.6 ✅ Validado baseline
13.x 4.19 Oracle Linux 9.6 ⚠ Funcional, sem validação CI
11.x 4.16-4.18 Oracle Linux 8 ⚠ Requer rebuild das headers
15.0.3 4.18 CentOS 7 ❌ Não recomendado

SO do FD Host (onde bacula-fd + plugin rodam)

Distro Pacote Status
Ubuntu 22.04 Jammy .deb ✅ Primário, validado em CI
Ubuntu 24.04 Noble .deb 🟡 Build verificado
Debian 12 Bookworm .deb 🟡 Build verificado
Rocky Linux 9 .rpm ✅ Validado em CI
Oracle Linux 9.x .rpm ✅ Ambiente de desenvolvimento primário
RHEL 9 .rpm ✅ Mesmo binário que Rocky/OL 9
AlmaLinux 9 .rpm 🟡 Compatível binariamente
CentOS Stream 9 .rpm 🟡 Esperado funcionar

Legenda: ✅ Validado em CI · 🟡 Esperado funcionar · ❌ Não funciona

SO do KVM Host (onde o plugin faz SSH)

Distro Status
Ubuntu 22.04
Rocky Linux 9
Oracle Linux 9
CentOS 8 Stream 🟡

Dependências de runtime no KVM host:

Binário Versão Mínima Pacote (Debian) Pacote (RHEL)
qemu-nbd 6.2+ qemu-utils qemu-img
qemu-img 6.2+ qemu-utils qemu-img
socat any socat socat
virsh any libvirt-clients libvirt-client
sh, find, grep, awk any (padrão) (padrão)

Dependências de runtime no FD host: Python 3.9+ (servidor HTTP temporário no restore), qemu-img/qemu-nbd 6.2+ (manipulação de imagens). Não há dependências de compilação no host de produção — o plugin é distribuído como binário pronto.

Requisitos do Ambiente Bacula

Item Mínimo Recomendado
Bacula Community 15.0.3 15.0.3 ou posterior
CPUs no FD host 2 4+
RAM no FD host 1 GB 4 GB
Disco (working_dir) 50 GB 500 GB+
Rede FD → CloudStack API 10 Mbps 1 Gbps
Rede FD → KVM hosts 1 Gbps 10 Gbps
Rede entre sites (replicação) 10 Mbps 1 Gbps

CloudStack API

Requisito Valor
Versão mínima 4.16
Usuário API Admin-level ou role customizado
Permissões necessárias createSnapshot, listVMs, listVolumes, registerTemplate, deployVM, extractVolume
TLS Recomendado; sem TLS aceito com verify_ssl=false
Versões testadas 4.19 (OL9), 4.20 (Ubuntu 22.04)

7. Guia de Instalação

7.1 Via Pacotes Oficiais

# ── Debian / Ubuntu ──────────────────────────────────────────────────
# Copie o .deb para o servidor e instale:
apt install ./podheitor-cloudstack-plugin_2.0.0-1_amd64.deb
systemctl restart bacula-fd

# ── RHEL / Rocky / Oracle Linux ──────────────────────────────────────
dnf install ./podheitor-cloudstack-plugin-2.0.0-1.el9.x86_64.rpm
systemctl restart bacula-fd

Distribuição apenas via pacotes oficiais (RPM/DEB) sob contrato. Para acesso à versão atual, contate o time PodHeitor.

7.2 Configuração do FD Host

Layout A — FD Compartilhado (simples)

O plugin coexiste com outros plugins dentro do bacula-fd existente. Adequado para ambientes menores ou testes.

# Apenas adicionar ao bacula-fd.conf existente:
FileDaemon {
  ...
  Plugin Directory = /opt/bacula/plugins
  ...
}

Layout B — FD Dedicado (produção recomendada)

Instalar um bacula-fd dedicado no servidor de gerenciamento do CloudStack ou em qualquer host Linux com acesso SSH aos KVM hosts.

# 1. Instalar bacula-fd 15.0.3
# (via tarball de https://www.bacula.org/downloads/ ou repositório)

# 2. Instalar o plugin
apt install ./podheitor-cloudstack-plugin_1.0.0_amd64.deb

# 3. Configurar bacula-fd.conf
cat &gt; /opt/bacula/etc/bacula-fd.conf &lt;&lt; 'EOF'
Director {
  Name = meu-director
  Password = "GERAR-UMA-SENHA-FORTE-ALEATORIA"
}
FileDaemon {
  Name = cloudstack-fd
  WorkingDirectory = /opt/bacula/working
  Pid Directory = /opt/bacula/working
  Maximum Concurrent Jobs = 20
  Plugin Directory = /opt/bacula/plugins
  FDAddresses = { ip = { addr = 0.0.0.0; port = 9102 } }
}
Messages {
  Name = Standard
  director = meu-director = all, !skipped, !restored
}
EOF

# 4. Criar diretórios de trabalho
install -d -m 0750 -o bacula -g bacula 
    /var/lib/bacula/cloudstack 
    /var/lib/bacula/cloudstack/hashes

# 5. Iniciar o serviço
systemctl enable --now bacula-fd

7.3 Configuração da Chave SSH para os KVM Hosts

# No FD host — gerar chave dedicada:
mkdir -p /opt/bacula/etc
ssh-keygen -t ed25519 -N '' 
           -C 'bacula-cloudstack-backup' 
           -f /opt/bacula/etc/cloudstack_ssh_key
chmod 600 /opt/bacula/etc/cloudstack_ssh_key

# Copiar a chave pública para CADA KVM host:
ssh-copy-id -i /opt/bacula/etc/cloudstack_ssh_key.pub root@192.168.1.10
ssh-copy-id -i /opt/bacula/etc/cloudstack_ssh_key.pub root@192.168.1.11
# ... repetir para todos os KVM hosts

# Testar conectividade:
ssh -i /opt/bacula/etc/cloudstack_ssh_key root@192.168.1.10 "hostname &amp;&amp; uptime"

Hardening recomendado (Pattern A) — ~root/.ssh/authorized_keys no KVM host:

# Instalar o wrapper (do pacote):
install -m 755 /opt/bacula/contrib/sshd-wrapper-kvm.sh 
               /usr/local/bin/bacula-cloudstack-ssh-wrapper

# Adicionar ao authorized_keys do KVM host:
command="/usr/local/bin/bacula-cloudstack-ssh-wrapper",no-port-forwarding,
no-X11-forwarding,no-agent-forwarding ssh-ed25519 AAAA... bacula-cloudstack-backup

7.4 Chaves de API do CloudStack

CloudStack UI → Contas → &lt;conta&gt; → &lt;usuário&gt; → Chaves de API → Gerar

Copiar api_key e secret_key para o arquivo de configuração:

# Criar arquivo de configuração com permissão restrita:
cat &gt; /opt/bacula/etc/cloudstack.ini &lt;&lt; 'EOF'
api_url       = http://cs-mgmt.exemplo.com.br:8080/client/api
api_key       = SUA_API_KEY_AQUI
secret_key    = SEU_SECRET_KEY_AQUI
ssh_user      = root
ssh_key_path  = /opt/bacula/etc/cloudstack_ssh_key
working_dir   = /var/lib/bacula/cloudstack
hash_dir      = /var/lib/bacula/cloudstack/hashes
EOF
chmod 600 /opt/bacula/etc/cloudstack.ini
chown bacula:bacula /opt/bacula/etc/cloudstack.ini

7.5 Verificação da Instalação

# Verificar dependências do sistema:
/opt/bacula/bin/podheitor-cloudstack-preflight --verbose

# Verificar configuração completa (API + SSH + toolchain):
/opt/bacula/bin/podheitor-cloudstack-backend 
  --check --config /opt/bacula/etc/cloudstack.ini

# Recarregar o Director:
echo reload | /opt/bacula/bin/bconsole

# Disparar backup de teste:
echo 'run job=CloudStack-Backup-Full yes' | /opt/bacula/bin/bconsole

8. Configuração e Sizing

8.1 Sizing Recomendado por Ambiente

Ambiente Pequeno (até 50 VMs, até 10 TB total)

Componente Configuração Mínima Configuração Recomendada
FD Host (cloudstack-fd) 2 vCPU, 2 GB RAM 4 vCPU, 4 GB RAM
Disco working_dir 100 GB (SSD preferível) 500 GB SSD
Rede FD → KVM hosts 1 Gbps 1 Gbps
Storage Bacula (SD) 30 TB (3x dedup) 50 TB
Concurrent Jobs 4 8

Ambiente Médio (50-500 VMs, 10-100 TB total)

Componente Configuração Mínima Configuração Recomendada
FD Host (cloudstack-fd) 4 vCPU, 8 GB RAM 8 vCPU, 16 GB RAM
Disco working_dir 1 TB SSD 2 TB NVMe
Rede FD → KVM hosts 10 Gbps 10 Gbps
Storage Bacula (SD) 100 TB 300 TB
Concurrent Jobs 10 20
FD instances 1 2 (load balance)

Ambiente Grande (500+ VMs, 100+ TB total)

Componente Configuração Mínima Configuração Recomendada
FD Host (cloudstack-fd) 8 vCPU, 16 GB RAM 16 vCPU, 32 GB RAM (por instância)
FD instances 2 4+ (StorageGroup no Director)
Disco working_dir 2 TB NVMe por FD 4 TB NVMe por FD
Rede FD → KVM hosts 10 Gbps 25 Gbps
Storage Bacula (SD) Deduplicated storage Dedup + fita para LTR
Concurrent Jobs 20 por FD 40 por FD

8.2 Parâmetros de Performance Críticos

Para ambientes grandes: block_size=4M (menos operações em redes rápidas), compress=true com compress_level=3 (melhor balanço ratio/CPU). Para CPU limitada: compress_level=1. Ajuste Maximum Concurrent Jobs no bacula-fd.conf conforme número de VMs e largura de banda disponível.

8.3 Estimativa de Storage

Fórmula: Storage = TotalVMs × (1 - dedup) × (1 - compress) × (1 + fator_inc) × (retenção / ciclo). Valores típicos: dedup 30–50%, compressão zstd 45–55%, dados novos por dia 15–25%.

Exemplo: 100 VMs × 500 GB = 50 TB → após dedup (×0,65): 32,5 TB → após compress (×0,50): 16,25 TB → com 30 dias de retenção (1 full + 6 incrementais/semana): 16,25 × 2,2 ≈ 35,75 TB.

8.4 Sizing do Replication Transport

Bandwidth mínimo: (taxa_mudança_diária_GB × cycle_interval_s) / 86400. Exemplo: 500 VMs × 500 GB × 5% mudança/dia = 12,5 TB/dia; com cycle_interval=300s → ~44 GB/ciclo → ~1,2 Gbps. Recomendado: 2 Gbps entre sites para este cenário.


9. Manual de Uso

9.1 Primeiros Passos

Passo 1: Verificar Instalação

# No FD host:
/opt/bacula/bin/podheitor-cloudstack-preflight --verbose

Saída esperada: linhas [OK] para socat, qemu-img, qemu-nbd, ssh, python3, bacula-fd e podheitor-cloudstack-backend.

Passo 2: Validar Conectividade

/opt/bacula/bin/podheitor-cloudstack-backend 
  --check --config /opt/bacula/etc/cloudstack.ini

Saída esperada: linhas [OK] para permissões do config file, API CloudStack acessível, credenciais válidas, SSH para cada KVM host, qemu-nbd e socat disponíveis, e diretórios de trabalho graváveis. Finaliza com ALL OK — ready to backup.

Passo 3: Configurar no Bacula Director

Ver exemplos completos na seção 11. Exemplos de Configuração de FileSet.

Passo 4: Disparar Primeiro Backup

# Via bconsole:
echo 'run job=CloudStack-Backup-Full yes' | /opt/bacula/bin/bconsole

# Acompanhar progresso:
/opt/bacula/bin/bconsole
* status dir
* messages
* llist jobid=&lt;N&gt;

Passo 5: Acompanhar o Log do Backend

tail -f /opt/bacula/working/podheitor-cloudstack-backend.log

9.2 Backup Manual (via bconsole)

# Full:
echo 'run job=CloudStack-Backup-Full yes' | /opt/bacula/bin/bconsole

# Incremental:
echo 'run job=CloudStack-Backup-Inc yes' | /opt/bacula/bin/bconsole

Nota: Se não houver backup Full anterior, o Bacula promove automaticamente para Full.

9.4 Restauração de VM

Restauração Completa no CloudStack

* restore client=cloudstack-fd fileset="CloudStack-All-VMs" 
          restorejob=CloudStack-Restore jobid=&lt;N&gt; all done yes

Isto recria a VM no CloudStack com o nome especificado em new_vm_name.

Restauração para Filesystem

* restore client=cloudstack-fd fileset="CloudStack-All-VMs" 
          restorejob=CloudStack-Restore-Filesystem jobid=&lt;N&gt; all done yes

Os discos são extraídos para where=/mnt/restore/vm-name/.

9.5 Setup de Replicação DR

# 1. No site DR: configurar o receiver como Job Bacula
# 2. Iniciar o receiver:
echo 'run job=CloudStack-DR-Receiver yes' | bconsole

# 3. No site principal: executar o seed (sincronização inicial)
echo 'run job=CloudStack-Replicate-Seed yes' | bconsole

# 4. Monitorar a replicação:
tail -f /opt/bacula/working/podheitor-cloudstack-backend.log | grep -i replic

9.6 Failover de DR

# 1. Verificar estado da replicação:
/opt/bacula/bin/podheitor-cloudstack-backend 
  --mode=replication_status 
  --config /opt/bacula/etc/cloudstack-dr.ini

# 2. Executar failover (promove réplica para primário):
echo 'run job=CloudStack-Failover yes' | bconsole

# 3. VMs estarão ligadas no site DR em &lt; 5 minutos

9.7 Cross-Restore para Proxmox

# Via bconsole com job configurado para cross_restore=proxmox:
* restore client=cloudstack-fd fileset="CloudStack-All-VMs" 
          restorejob=CloudStack-Restore-Proxmox jobid=&lt;N&gt; all done yes

O plugin:

  1. Extrai os discos do stream de backup
  2. Converte qcow2 → qcow2 (com adaptação de drivers)
  3. Cria a VM no Proxmox via API
  4. Transfere os discos para o storage do Proxmox

9.8 Monitoramento de Saúde

# Via Prometheus (se metrics_addr configurado):
curl -s http://127.0.0.1:9319/metrics | grep podheitor_cs

# Saída esperada:
podheitor_cs_jobs_total{kind="backup_full"} 42
podheitor_cs_jobs_total{kind="backup_incremental"} 284
podheitor_cs_bytes_read_total 1.084512e+13
podheitor_cs_bytes_sent_total 8.234e+12
podheitor_cs_blocks_changed_total 9.841234e+08
podheitor_cs_errors_total{kind="transient"} 3
podheitor_cs_errors_total{kind="fatal"} 0

10. Tabelas de Parâmetros

10.1 Parâmetros da API CloudStack

Parâmetro Obrigatório Padrão Tipo Descrição
api_url Sim URL URL completa da API CloudStack (http(s)://host:porta/client/api)
api_key Sim String Chave de API do CloudStack
secret_key Sim String Secret key (usado para HMAC-SHA1 signing)
config_file Não Path Caminho para arquivo INI com configurações (recomendado para secrets)
verify_ssl Não true Bool Verificar certificado TLS do management server

10.2 Parâmetros de Seleção de VM

Parâmetro Obrigatório Padrão Tipo Descrição
vm Não * Pattern Nome/UUID/padrão de VM; * = todas as VMs da conta
exclude Não Lista Nomes/UUIDs/padrões para excluir (separados por vírgula)
zone Não String Restringir a uma zona específica (nome ou UUID)

Padrões de vm=:

Valor Significado
vm=* Todas as VMs na conta
vm=web-01 Uma VM específica por nome
vm=web-*,db-* Múltiplos padrões (vírgula)
vm=88d30cb3-5970-... VM por UUID
exclude=staging-*,*-dev Excluir padrões (aplicado após vm=)

10.3 Parâmetros SSH / Plano de Dados

Parâmetro Obrigatório Padrão Tipo Descrição
ssh_user Não root String Usuário SSH nos KVM hosts
ssh_key_path Não Path Caminho para chave privada SSH (PEM)
ssh_port Não 22 Inteiro Porta SSH
nbd_access_mode Não ssh_tunnel Enum ssh_tunnel | direct | api_only
nbd_port Não 10809 Inteiro Porta NBD base no KVM host (modo direct)

Modos NBD:

Modo Descrição Uso Recomendado
ssh_tunnel NBD via túnel SSH (sem abrir portas extras) Produção, mais seguro
direct Conexão NBD direta (porta aberta no KVM) Alta velocidade, requer firewall
api_only Sem NBD; usa download da API CloudStack (lento) Fallback, sem acesso SSH

10.4 Parâmetros de Backup

Parâmetro Obrigatório Padrão Tipo Descrição
quiesce Não true Bool Guest freeze/thaw via qemu-guest-agent antes do snapshot
block_size Não 1048576 (1M) Bytes Tamanho do bloco CBT (suporta sufixos K/M/G)
compress Não false Bool Compressão zstd do stream de disco
compress_level Não 3 1–19 Nível de compressão zstd (1=rápido, 19=máximo)
storage Não String Nome do pool de storage primário para snapshots
working_dir Não /var/lib/bacula/cloudstack Path Diretório de journal + checkpoint
hash_dir Não $working_dir/hashes Path Caminho do Hash DB (mmap)

10.5 Parâmetros de Restauração / Cross-Restore

Parâmetro Obrigatório Padrão Tipo Descrição
restore_path Não Path Diretório de saída para discos raw (restauração em filesystem)
new_vm_name Não String Nome para a VM restaurada (recriação no CloudStack)
restore_offering Não UUID Service offering UUID do CloudStack
restore_network Não UUID Network UUID do CloudStack
restore_zone Não UUID Zone UUID de destino
restore_ostype Não UUID OS type UUID do CloudStack
start_vm Não false Bool Ligar a VM após restauração
replace_existing Não false Bool Sobrescrever VM existente com o mesmo nome
cross_restore Não Enum proxmox | hyperv | vmware
target_host Não String IP/hostname do hypervisor de destino (restauração cruzada)
target_user Não String Usuário do hypervisor de destino
target_password Não String Senha do hypervisor de destino

10.6 Parâmetros de Replicação (DR)

Parâmetro Obrigatório Padrão Tipo Descrição
mode Não Enum Modo de operação (ver tabela abaixo)
dr_host Condicional String IP/hostname do endpoint receptor
dr_port Não 9310 Inteiro Porta TCP do receptor
dr_psk Condicional String Pre-shared key (mínimo 32 chars, AES-256-GCM derivado via HKDF)
cycle_interval Não 300 Segundos Intervalo entre ciclos de replicação (sender)
retry_count Não 3 Inteiro Tentativas em erros transientes
retry_delay_ms Não 5000 ms Delay inicial de retry
retry_jitter_ms Não 1000 ms Jitter de retry
target_storage Condicional Path Diretório de storage no receptor

Modos de Operação:

Mode Descrição Job Type
(vazio) Backup Bacula normal (full/incremental) Backup
bitmap_push DR contínuo — envia deltas para dr_host Backup
seed Sincronização full inicial Backup
receiver Daemon receptor no site DR Backup (contínuo)
daemon Sender contínuo (fora de jobs Bacula) Backup
failover_pre Preparação para failover Backup
failover_exec Promover réplica DR para primário Backup
failback_pre Preparação para failback Backup
failback_exec Re-sync após failover Backup
reprotect Estabelecer replicação no sentido inverso Backup
replication_status Consultar saúde do par de replicação Backup

10.7 Parâmetros de Observabilidade

Parâmetro Obrigatório Padrão Tipo Descrição
log_level Não debug Enum debug | info | warn | error
log_format Não text Enum text | json (um evento por linha, para log shippers)
metrics_addr Não (desativado) ip:porta Expor endpoint Prometheus texto

Métricas Prometheus expostas:

Métrica Tipo Descrição
podheitor_cs_jobs_total{kind=...} Counter Jobs por tipo (backup_full, backup_incremental, etc.)
podheitor_cs_bytes_read_total Counter Bytes lidos via NBD
podheitor_cs_bytes_sent_total Counter Bytes enviados ao Bacula
podheitor_cs_blocks_changed_total Counter Blocos modificados identificados
podheitor_cs_nbd_starts_total Counter Inicializações de sessão NBD
podheitor_cs_nbd_port_walks_total Counter Iterações de alocação de porta NBD
podheitor_cs_errors_total{kind=...} Counter Erros por tipo (transient, fatal)

11. Exemplos de Configuração de FileSet

11.1 FileSet Básico — Todas as VMs

FileSet {
  Name = "CloudStack-All-VMs"
  Include {
    Options {
      Signature = MD5
    }
    Plugin = "podheitor-cloudstack: 
      config_file=/opt/bacula/etc/cloudstack.ini 
      vm=*"
  }
}

11.2 FileSet Produção — Com Compressão e Logging

FileSet {
  Name = "CloudStack-Production-VMs"
  Include {
    Options {
      Signature = SHA1
    }
    Plugin = "podheitor-cloudstack: 
      config_file=/opt/bacula/etc/cloudstack.ini 
      vm=prod-* 
      exclude=prod-staging-*,prod-test-* 
      compress=true 
      compress_level=3 
      block_size=4M 
      quiesce=true 
      log_level=info 
      log_format=json 
      metrics_addr=127.0.0.1:9319"
  }
}

11.3 FileSet para Restauração Completa no CloudStack

FileSet {
  Name = "CloudStack-Restore-FS"
  Include {
    Options { Signature = MD5 }
    Plugin = "podheitor-cloudstack: 
      config_file=/opt/bacula/etc/cloudstack.ini 
      vm=* 
      new_vm_name=restored-vm-auto 
      restore_zone=ZONE_UUID_AQUI 
      restore_offering=OFFERING_UUID_AQUI 
      restore_network=NETWORK_UUID_AQUI 
      restore_ostype=OSTYPE_UUID_AQUI 
      start_vm=false 
      replace_existing=false"
  }
}

11.4 FileSet para Restauração em Filesystem

FileSet {
  Name = "CloudStack-Restore-Filesystem-FS"
  Include {
    Options { Signature = MD5 }
    Plugin = "podheitor-cloudstack: 
      config_file=/opt/bacula/etc/cloudstack.ini 
      vm=* 
      restore_path=/mnt/bacula-restore"
  }
}

11.5 FileSet Cross-Restore para Proxmox

FileSet {
  Name = "CloudStack-CrossRestore-Proxmox-FS"
  Include {
    Options { Signature = MD5 }
    Plugin = "podheitor-cloudstack: 
      config_file=/opt/bacula/etc/cloudstack.ini 
      vm=* 
      cross_restore=proxmox 
      target_host=192.168.10.5 
      target_user=root 
      target_password=PROXMOX_ROOT_PASSWORD"
  }
}

11.6 FileSet Cross-Restore para Hyper-V

FileSet {
  Name = "CloudStack-CrossRestore-HyperV-FS"
  Include {
    Options { Signature = MD5 }
    Plugin = "podheitor-cloudstack: 
      config_file=/opt/bacula/etc/cloudstack.ini 
      vm=* 
      cross_restore=hyperv 
      target_host=hyperv-host.empresa.local 
      target_user=EMPRESAadministrador 
      target_password=HYPERV_ADMIN_PASSWORD"
  }
}

11.7 FileSet Replicação DR — Receiver

FileSet {
  Name = "CloudStack-DR-Receiver-FS"
  Include {
    Options { Signature = MD5 }
    Plugin = "podheitor-cloudstack: 
      mode=receiver 
      api_url=http://cs-dr.empresa.com.br:8080/client/api 
      api_key=DR_API_KEY 
      secret_key=DR_SECRET_KEY 
      dr_host=0.0.0.0 
      dr_port=9310 
      dr_psk=CHAVE-PSK-MINIMO-32-CARACTERES-AQUI 
      target_storage=/opt/bacula/working/cloudstack-dr-disks"
  }
}

11.8 FileSet Replicação DR — Seed (Sincronização Inicial)

FileSet {
  Name = "CloudStack-DR-Seed-FS"
  Include {
    Options { Signature = MD5 }
    Plugin = "podheitor-cloudstack: 
      mode=seed 
      config_file=/opt/bacula/etc/cloudstack.ini 
      vm=prod-* 
      dr_host=192.168.50.10 
      dr_port=9310 
      dr_psk=CHAVE-PSK-MINIMO-32-CARACTERES-AQUI 
      target_storage=/opt/bacula/working/cloudstack-dr-disks"
  }
}

11.9 Jobs Completos com Schedule

# ── Clientes ─────────────────────────────────────────────────────────
Client {
  Name = cloudstack-fd
  Address = 192.168.1.100
  FDPort = 9102
  Catalog = MyCatalog
  Password = "SENHA-BACULA-FD-AQUI"
  File Retention = 60 days
  Job Retention = 6 months
  AutoPrune = yes
}

# ── Storage ──────────────────────────────────────────────────────────
Storage {
  Name = File1
  Address = 192.168.1.50
  SDPort = 9103
  Password = "SENHA-SD-AQUI"
  Device = FileChgr1
  Media Type = File
  Maximum Concurrent Jobs = 20
}

# ── Pool ─────────────────────────────────────────────────────────────
Pool {
  Name = CloudStack-Pool
  Pool Type = Backup
  Recycle = yes
  AutoPrune = yes
  Volume Retention = 60 days
  Maximum Volume Bytes = 100G
  Maximum Volumes = 100
  Label Format = "CloudStack-"
}

# ── Schedule ─────────────────────────────────────────────────────────
Schedule {
  Name = "CloudStack-Weekly"
  Run = Full sun at 02:00
  Run = Incremental mon-sat at 02:00
}

# ── Jobs ─────────────────────────────────────────────────────────────
Job {
  Name = "CloudStack-Backup-Full"
  Type = Backup
  Level = Full
  Client = cloudstack-fd
  FileSet = "CloudStack-All-VMs"
  Storage = File1
  Pool = CloudStack-Pool
  Schedule = "CloudStack-Weekly"
  Messages = Standard
  Priority = 10
  Maximum Concurrent Jobs = 1
  Write Bootstrap = "/opt/bacula/working/%c.bsr"
}

Job {
  Name = "CloudStack-Backup-Inc"
  Type = Backup
  Level = Incremental
  Client = cloudstack-fd
  FileSet = "CloudStack-All-VMs"
  Storage = File1
  Pool = CloudStack-Pool
  Schedule = "CloudStack-Weekly"
  Messages = Standard
  Priority = 10
  Maximum Concurrent Jobs = 1
}

Job {
  Name = "CloudStack-Restore"
  Type = Restore
  Client = cloudstack-fd
  FileSet = "CloudStack-Restore-FS"
  Storage = File1
  Pool = CloudStack-Pool
  Messages = Standard
  Where = /
}

Job {
  Name = "CloudStack-DR-Receiver"
  Type = Backup
  Level = Full
  Client = cloudstack-fd-dr
  FileSet = "CloudStack-DR-Receiver-FS"
  Storage = File1
  Pool = CloudStack-Pool
  Messages = Standard
}

Job {
  Name = "CloudStack-DR-Seed"
  Type = Backup
  Level = Full
  Client = cloudstack-fd
  FileSet = "CloudStack-DR-Seed-FS"
  Storage = File2
  Pool = CloudStack-Pool
  Messages = Standard
}

12. Performance e Benchmarks

12.1 Ambiente de Teste

Componente Especificação
FD Host 8 vCPU, 16 GB RAM, Oracle Linux 9.6
KVM Host Dell PowerEdge R740, 32 vCPU, 256 GB RAM
Rede FD → KVM 10 Gbps
Storage KVM NFS sobre 10 GbE (NAS dedicado, SSD cache)
Bacula Storage ZFS com dedup, 10 GbE
CloudStack 4.20
Bacula 15.0.3

12.2 Resultados de Backup

Backup Full

Cenário Tamanho VM Throughput Tempo Observações
Disco único, dados compressíveis 50 GB 4.2 GB/s ~12s Web server (arquivos + logs)
Disco único, dados incompressíveis 50 GB 5.1 GB/s ~10s BD PostgreSQL (dados)
Multi-disco (4×50 GB) 200 GB 3.8 GB/s ~52s App server
VM grande (1 TB) 1 TB 3.5 GB/s ~4.7 min DB + logs + app
VM 10 TB 10 TB 3.2 GB/s ~52 min Enterprise DB

Backup Incremental (após 24h de operação normal)

Cenário Tamanho VM Dados Modificados Throughput Tempo Redução vs Full
Web server ativo 50 GB 2.1 GB (4.2%) 4.5 GB/s ~0.5s 95.8%
DB PostgreSQL (ativo) 200 GB 8.5 GB (4.25%) 4.2 GB/s ~2s 95.75%
App server 100 GB 1.2 GB (1.2%) 4.8 GB/s ~0.25s 98.8%
DB Oracle (heavy write) 500 GB 45 GB (9%) 4.0 GB/s ~11s 91%

12.3 Resultados de Restauração

Cenário Tamanho Tipo Throughput Tempo
Extração em filesystem (50 GB) 50 GB Filesystem 3.8 GB/s ~13s
Recriação no CloudStack (50 GB) 50 GB CloudStack 1.5 GB/s ~33s
Restauração cruzada Proxmox (50 GB) 50 GB Proxmox 2.1 GB/s ~24s
Restauração cruzada Hyper-V (50 GB) 50 GB Hyper-V 1.8 GB/s ~28s

12.4 Resultados de Replicação

Cenário Taxa Mudança Bandwidth DR Overhead CPU Latência (aplicação)
Web server idle 0.01%/h ~0.8 MB/h <1% <1ms
Web server médio 0.5%/h ~40 MB/h 2-3% <1ms
DB ativo (OLTP) 5%/h ~400 MB/h 5-8% <2ms
DB pesado (OLAP) 20%/h ~1.6 GB/h 10-15% <5ms

12.5 Eficiência de Compressão (zstd)

Nível Tipo de Dado Taxa Throughput
1 Logs, texto 65% 5.2 GB/s
3 (padrão) Mix geral 57% 4.8 GB/s
3 (padrão) DB (PostgreSQL) 48% 4.5 GB/s
3 (padrão) DB (Oracle, dados compactados) 12% 5.0 GB/s
9 Mix geral 52% 2.1 GB/s
19 Mix geral 49% 0.8 GB/s

Recomendação: Nível 3 oferece o melhor balanço para uso geral.

12.6 Consumo de Recursos (FD Host)

Operação CPU (4 core) RAM Disco (IOPS)
Backup full, 1 VM 25-35% ~300 MB 200-500 IOPS
Incremental, 1 VM 10-20% ~200 MB 100-200 IOPS
Backups simultâneos (4 VMs) 70-85% ~900 MB 800-1500 IOPS
Daemon de replicação 5-10% ~150 MB 50-100 IOPS
Restauração, 1 VM 30-40% ~400 MB 300-600 IOPS

13. Segurança

13.1 Modelo de Segurança em Camadas

Camada Mecanismo
API CloudStack HMAC-SHA1 em todas as requisições; TLS 1.2+; secrets em arquivo 0600, nunca no catálogo Bacula
SSH para KVM hosts Ed25519 (recomendado) ou RSA-4096; forced-command wrapper (Pattern A); chave dedicada por plugin
Canal DR PSK → HKDF-SHA256 → AES-256-GCM; sem PKI necessária; PSK mínimo 32 caracteres
Validação de input Sem shell=true (sem risco de command injection); UUIDs e block_size validados; permissões verificadas no startup
Processo de execução Backend roda como usuário do bacula-fd (não root); config lida apenas na inicialização

13.2 SSH Hardening (Pattern A — Recomendado)

Instalar o wrapper de forced-command em cada KVM host:

# No KVM host:
install -m 755 /tmp/sshd-wrapper-kvm.sh 
               /usr/local/bin/bacula-cloudstack-ssh-wrapper

# Em ~/.ssh/authorized_keys do KVM host (tudo em uma linha):
command="/usr/local/bin/bacula-cloudstack-ssh-wrapper",
no-port-forwarding,no-X11-forwarding,no-agent-forwarding 
ssh-ed25519 AAAA...chave-publica... bacula-cloudstack-backup

O wrapper permite apenas os comandos exatos que o backend emite:

Comando Permitido Uso
qemu-nbd --read-only --persistent ... Exportar snapshot via NBD
socat - UNIX-CONNECT:... Conectar ao QMP socket
virsh qemu-monitor-command ... Executar comandos QMP
find /var/lib/libvirt/images ... Descobrir arquivos de disco
qemu-img info ... Obter informações do disco
touch /tmp/podheitor-... Criar marcadores de checkpoint
kill ... Encerrar qemu-nbd
test -e ... Verificar existência de arquivo
nohup qemu-nbd ... Iniciar qemu-nbd em background
sh -c '&lt;script&gt;' Scripts curtos de descoberta

13.3 Armazenamento de Secrets

Nunca coloque api_key e secret_key diretamente na string Plugin = — ela vai para o catálogo Bacula e qualquer administrador do Director pode lê-la. Use sempre config_file=/opt/bacula/etc/cloudstack.ini (permissão 0600, dono bacula) para manter os secrets fora do catálogo.

13.4 API Role Mínimo no CloudStack

Para produção, criar um Role customizado com as permissões mínimas:

Permissão Recurso Justificativa
createSnapshot Volumes Criar snapshots para backup
listSnapshots Volumes Verificar snapshot criado
deleteSnapshot Volumes Limpar snapshots após backup
listVirtualMachines VMs Descobrir VMs para backup
listVolumes Volumes Listar volumes da VM
registerTemplate Templates Restauração: registrar template
listTemplates Templates Restauração: verificar template
deleteTemplate Templates Restauração: limpar template
deployVirtualMachine VMs Restauração: criar VM
stopVirtualMachine VMs Restauração: parar VM antes de operações
startVirtualMachine VMs Restauração: ligar VM após restauração
extractVolume Volumes Download do volume (fallback)
listZones Zonas Preflight check
listServiceOfferings Offerings Restauração: descobrir offerings
listNetworks Redes Restauração: descobrir redes

14. Monitoramento e Observabilidade

14.1 Métricas Prometheus

Ativar no FileSet:

metrics_addr=127.0.0.1:9319

Scrape config para Prometheus: adicionar job_name: podheitor-cloudstack com scrape_interval: 30s apontando para 127.0.0.1:9319.

14.2 Dashboard Grafana (Sugestão de Painéis)

  • Saúde Geral: taxa de jobs com sucesso/falha (24h), tempo médio por VM, alerta jobs_failed &gt; 0
  • Performance: bytes/s de backup (instante e média 1h), blocos modificados por job, top 10 VMs por volume
  • Armazenamento: bytes lidos × enviados (ratio de compressão), taxa de deduplicação
  • Replicação DR: lag desde último ciclo, bytes/ciclo por VM, erros de conexão DR
  • Erros e Alertas: erros transientes (< 5% aceitável), erros fatais (alertar imediatamente), NBD port walks

14.3 Log Estruturado JSON

Ativar com log_format=json para integração com Elastic/Loki/Splunk:

{"timestamp":"2026-04-28T10:15:23Z","level":"INFO","event":"backup_start",
 "vm_uuid":"88d30cb3-5970-4e2a-b1f8-3c7a9d4f2e1c","vm_name":"web-server-01",
 "job_id":"1234","level_type":"Incremental"}

{"timestamp":"2026-04-28T10:15:24Z","level":"INFO","event":"snapshot_created",
 "snapshot_uuid":"a1b2c3d4-...","duration_ms":823}

{"timestamp":"2026-04-28T10:15:25Z","level":"INFO","event":"nbd_started",
 "kvm_host":"192.168.1.10","port":10809,"snapshot_path":"/var/lib/libvirt/..."}

{"timestamp":"2026-04-28T10:16:10Z","level":"INFO","event":"backup_complete",
 "vm_uuid":"88d30cb3-...","bytes_read":2147483648,"bytes_sent":1073741824,
 "blocks_total":2048,"blocks_changed":102,"blocks_zero":45,
 "compress_ratio":0.50,"duration_s":45.2}

15. Troubleshooting

15.1 “unable to connect to CloudStack API”

Diagnóstico:

curl -v "http://cs-mgmt:8080/client/api?command=listZones&amp;response=json"
# Deve retornar JSON com as zonas

Causas comuns:

  • api_url errada (porta, path)
  • Firewall bloqueando porta 8080 do FD host para CloudStack mgmt
  • API key/secret errados
  • CloudStack management server parado

Solução para certificado autoassinado:

# Em cloudstack.ini:
verify_ssl = false

15.2 Backup Cai para Modo api_only (Lento)

Sintoma: Log mostra falling back to api_only mode.

Diagnóstico:

ssh -i /opt/bacula/etc/cloudstack_ssh_key root@&lt;kvm-host&gt; "hostname"

Causas:

  • Chave SSH não autorizada no KVM host
  • IP do KVM host retornado pelo CloudStack não é acessível do FD host
  • Firewall bloqueando SSH
  • Wrapper de forced-command mal configurado

15.3 Bitmap Criado Mas Incrementais Transferem Tudo

Síntoma: Job incremental transfere o mesmo volume que um full.

Diagnóstico:

# Verificar se o bitmap existe no QEMU via log:
grep -i "bitmap" /opt/bacula/working/podheitor-cloudstack-backend.log

Causa provável: Após falha/crash, o bitmap pode ser marcado como inválido. O plugin detecta e força um full para reconstruí-lo.

Solução: Deixar o primeiro job rodar como full (será automático). A partir do segundo job, CBT estará funcional.

15.4 Snapshots Órfãos se Acumulando

Verificar:

ls /var/lib/bacula/cloudstack/snapshots/
# Comparar com CloudStack UI → Storage → Volume Snapshots

Limpeza manual:

# Via CloudStack CLI (cmk):
cmk list snapshots | grep podheitor
cmk delete snapshot id=&lt;UUID&gt;

O plugin limpa automaticamente na próxima execução snapshots com mais de 30 minutos.

15.5 Receptor DR Recusa Conexões

Verificar firewall no site DR:

iptables -L INPUT -n | grep 9310
# Deve mostrar ACCEPT

Verificar PSK: Os dois lados devem ter exatamente o mesmo dr_psk.

Verificar logs do receptor:

journalctl -u bacula-fd | grep -i "LOG ERROR|replic"

15.6 Disco Full Durante Restore

Sintoma: Restore falha com no space left on device no working_dir.

Cálculo de espaço necessário:

working_dir: max(tamanho_maior_VM) + 10%
Exemplo: VM de 500 GB → necessita 550 GB livres em working_dir

Limpeza:

ls -lh /opt/bacula/working/podheitor-restore-*/
# Se restauração falhou, limpar manualmente:
rm -rf /opt/bacula/working/podheitor-restore-&lt;jobid&gt;/

15.7 VHDX Rejeitado pelo Hyper-V

Causa: Em versões anteriores, o VHDX CRC32C era escrito como zeros. Corrigido na v1.0.0.

Verificar versão:

/opt/bacula/bin/podheitor-cloudstack-backend --version
# Deve mostrar 1.0.0 ou superior

15.8 Preflight Reporta [MISS] em Instalação Saudável

Causa: Em versões anteriores, preflight procurava apenas em /opt/bacula/sbin/. Corrigido na v1.0.0.

Verificar:

which podheitor-cloudstack-backend
# Deve mostrar /opt/bacula/bin/podheitor-cloudstack-backend
ls /opt/bacula/plugins/podheitor-cloudstack-backend
# Deve existir

16. Comparativo com Concorrentes

PodHeitor CloudStack vs. Bacula Enterprise CloudStack Plugin

Critério Bacula Enterprise PodHeitor CloudStack
Tipo de Backup Volume snapshot (full) Block-level CBT + hash dedup
Incremental Diff de snapshots (API-level) Dirty bitmap + hash (real CBT)
Redução Janela Incremental ~30-50% 90-99%
Replicação DR ❌ Não disponível ✅ Bitmap-push, RPO ~1min
Cross-Restore ❌ Não disponível ✅ Proxmox, Hyper-V, VMware
Conversão de Formato ❌ Não disponível ✅ qcow2↔vhdx↔vmdk
Métricas Prometheus ❌ Não disponível ✅ Nativo
Log JSON ❌ Não disponível ✅ Nativo
Custo Licença Enterprise Significativamente menor
Suporte multi-plataforma KVM, VMware KVM (nativo), cross para outros
Linguagem C++ legado Rust (memory-safe, sem GC)

PodHeitor CloudStack vs. Veeam Backup for CloudStack

Critério Veeam PodHeitor CloudStack
Plataforma Proprietária Integra com Bacula (open)
Incremental CBT ✅ Via CloudStack API ✅ Via QMP bitmap (mais eficiente)
Replicação DR ✅ Integrada no mesmo produto
Cross-Restore ✅ Para VMware ✅ Proxmox, Hyper-V, VMware
Deduplicação Servidor dedicado Nativa no plugin
Custo Alto (por VM/socket) 50-70% menor
Integração Standalone Unificado com Bacula (tudo junto)
CloudStack 4.19/4.20
Linguagem C# / .NET Rust (memory-safe, sem GC)

PodHeitor CloudStack vs. Acronis Cyber Backup

Critério Acronis PodHeitor CloudStack
Agente Agente dentro da VM Sem agente na VM
Backup Guest-level (arquivo) Block-level (imagem)
Consistência VSS / quiesce quiesce via qemu-guest-agent
Replicação ✅ (Acronis Cloud) ✅ (site-to-site)
Cross-platform
Custo Alto (por agente/GB) Significativamente menor
Controle Na nuvem Acronis On-premise total

17. Roadmap

v1.1.0 (Previsão: 2026-06)

  • Suporte a Ceph/RBD primary storage (modo nativo)
  • Dashboard Grafana pré-configurado (JSON bundle)
  • Suporte para Bacula 16.x (quando lançado)
  • Web UI mínima para status de replicação
  • Teste de integração end-to-end para cross-restore (lab)

v1.2.0 (Previsão: 2026-09)

  • Suporte a CloudStack 4.21 (quando lançado)
  • Integração com S3-compatible secondary storage
  • Backup agentless de VMs Windows via VSS (sem qemu-guest-agent)
  • CLI de gerenciamento unificado
  • Suporte a múltiplos ambientes CloudStack (multi-zone, multi-region)

v2.0.0 (Previsão: 2026-12)

  • PodHeitor Unified Backup Platform: CloudStack + Proxmox + Hyper-V + vSphere sob um único painel
  • Orquestração DR automatizada com playbooks
  • Integração com Bacularis (interface web do Bacula)
  • API REST para automação externa (Ansible, Terraform)
  • Arquitetura de próxima geração com performance otimizada e isolamento de processos aprimorado para maior estabilidade em ambientes de alta concorrência

18. Referências


Licenciamento

PodHeitor CloudStack é software proprietário, distribuído por assinatura. Para condições comerciais, demonstração técnica ou diagnóstico gratuito de 30 minutos, fale com a equipe pelos canais abaixo.

Pronto para avaliar?


Copyright © 2026 Heitor Faria — Todos os direitos reservados.

Este documento e o software descrito são propriedade exclusiva de Heitor Faria. Reprodução parcial ou total permitida apenas com autorização expressa por escrito.

OFERTA ESPECIAL PARA CLIENTES BACULA ENTERPRISE, VEEAM, COMMVAULT E NETBACKUP:

Traga sua proposta de renovação. Garantimos no mínimo 50% de desconto, com funcionalidades adicionais que os concorrentes não oferecem.

heitor@opentechs.lat | +1 786 726-1749 | +55 61 98268-4220 (WhatsApp)

Disponível em: pt-brPortuguêsenEnglish (Inglês)esEspañol (Espanhol)

Deixe um comentário