Este tutorial detalha como transformar um servidor TrueNAS em um target de backup via NFS para o VMware ESXi, automatizando a proteção de máquinas virtuais (VMs) e criando um sistema de restauração interativo com isolamento de rede.
NÍVEL TÉCNICO E AMBIENTE: Este guia não é de nível iniciante. Ele foi desenvolvido para implementação em ambientes reais de infraestrutura, embora possa ser validado em laboratório. Pressupõe-se que você tenha domínio de CLI (Linux), entenda a hierarquia de diretórios do VMware ESXi e saiba navegar na interface do TrueNAS. O foco aqui é automação robusta e disponibilidade.
Para garantir o sucesso da implementação e a integridade dos seus dados, atente-se aos seguintes pontos:
Adaptação de Variáveis: Quase todas as linhas de código deste tutorial contêm variáveis que devem ser editadas de acordo com a sua infraestrutura. IPs, nomes de Datastores (ex: [DS] ou DATASTORE_PROD) e caminhos de rede precisam refletir a sua realidade. Não realize cópias cegas de comandos.
A Lei dos Caminhos Absolutos: O ESXi não processa caminhos relativos no Cron ou em scripts de boot. Utilize sempre o caminho completo iniciado em /vmfs/volumes/.
Dica: Navegue até o diretório desejado e utilize o comando pwd para extrair o caminho absoluto exato.
Guia de Sobrevivência do Editor VI: No terminal do ESXi, o vi é a ferramenta padrão:
Para editar: Aperte a tecla 'i' (Insert).
Para salvar e sair: Aperte 'ESC', digite ':wq' e dê Enter.
Para sair sem salvar: Aperte 'ESC', digite ':q!' e dê Enter.
Nomenclatura (Case Sensitive): O sistema diferencia maiúsculas de minúsculas e é sensível a espaços em branco. Mantenha nomes de VMs e arquivos sem espaços (ex: SRV-DEBIAN-PROD) para evitar quebras nos scripts de awk e sed.
Persistência de Configuração: No ESXi, alterações em diretórios como /etc/ e no Cron são voláteis e serão perdidas no próximo reboot. É obrigatório executar o comando /sbin/auto-backup.sh ao finalizar as edições para persistir os dados no bootbank.
Cálculo de Janela de Backup: Em uma rede de 1Gbps, a taxa real de escrita no TrueNAS oscilará entre 60 a 90MB/s. Dimensione sua janela de backup considerando o tamanho total das VMs e o throughput da sua rede.
Para que o VMware ESXi consiga gravar backups no TrueNAS sem erros de "Permission Denied", siga estas etapas rigorosamente:
Acesse a interface do TrueNAS e vá em Storage > Pools.
Clique nos três pontos (ou "Add Dataset") no seu Pool principal (ex: STORAGE01).
Expanda as opções avançadas.
Name: Backup_ESXi
Quota: Configure o espaço destinado a este compartilhamento caso não vá utilizar o Pool inteiro. No meu ambiente, coloquei 5TiB.
Share Type: Selecione Generic (ou Unix). É a última opção no final da página.
Deixe as demais opções como padrão e clique em Submit.
O ESXi acessa o NFS como usuário root. Se o TrueNAS não permitir que um usuário externo assuma a identidade de root, o backup falhará.
No Dataset criado, clique nos 3 pontinhos, vá em Permissions (ou Edit ACL).
Certifique-se de que o Owner seja root e o Group seja wheel ou root.
Marque as permissões de Read, Write e Execute para User e Group.
Clique em Save.
Antes de compartilhar, o serviço precisa estar rodando corretamente:
Vá em Services > NFS (ícone do lápis).
Localize NFS e clique no ícone de lápis (Configurar).
Enable NFSv4: Mantenha desativado. Isso é recomendado para a configuração que vamos fazer pois o ESXi 6.x/7.x prefere NFSv3 para script ghettoVCB.
Inicie o serviço ligando o botão Running e marque Start Automatically.
Aqui é onde configuramos a segurança e o acesso de escrita para o ESXi.
Vá em Shares > Unix Shares (NFS) e clique em Add.
Paths: Selecione o caminho do seu dataset (ex: /mnt/POOL/Backup_ESXi).
Description: Backup para o Host <HOSTNAME_ESXI>.
Clique em Advanced Options (essencial):
Maproot User: Selecione root. (Isso diz ao TrueNAS: "Trate qualquer requisição do cliente como se fosse o usuário root local").
Maproot Group: Selecione wheel ou root.
Authorized Hosts: Digite o IP do seu ESXi (ex: 192.168.1.100). Isso garante que apenas o seu servidor de virtualização veja esses dados.
Clique em Save
Após configurar o TrueNAS, volte ao terminal do ESXi para testar se o caminho está visível antes de montar:
Comando para listar exportações do TrueNAS:
esxcli network ip connection list | grep 2049
Saída esperada:
[root@OMEGAITHYP01:~] esxcli network ip connection list | grep 2049
tcp 0 0 10.24.255.10:727 10.24.20.11:2049 ESTABLISHED 2128940 newreno
[root@OMEGAITHYP01:~]
Observação: O erro mais comum é esquecer o Maproot User. Sem ele, o ESXi monta o datastore como 'Read-Only', bloqueando a gravação do backup.
Após preparar o compartilhamento no TrueNAS, siga estes passos na interface web do seu ESXi para montar o Datastore de backup:
Faça login no VMware Host Client (https://[IP-DO-ESXI]/ui).
No menu lateral esquerdo (Navigator), clique em Storage (Armazenamento).
Na aba superior, clique no botão New datastore (Novo armazenamento).
O assistente irá abrir uma janela pop-up. Siga estas seleções:
Select creation type: Selecione a opção Mount NFS datastore e clique em Next.
Provide NFS mount details: Preencha os campos conforme configurado no seu TrueNAS:
Name: NFS_BACKUP (Este é o nome que aparecerá no inventário do ESXi).
NFS Server: Digite o endereço IP do seu servidor TrueNAS.
NFS share: Digite o caminho completo do dataset (Exemplo: /mnt/STORAGE16TB/Backup_ESXi).
NFS version: Selecione NFS 3 (O ghettoVCB e o ESXi 6.x/7.x têm melhor compatibilidade e performance com a versão 3 para backups).
Clique em Next.
Na tela de Ready to complete, revise os caminhos e o IP do servidor.
Clique em Finish.
Após clicar em finalizar, o novo Datastore NFS_BACKUP deverá aparecer na lista de dispositivos.
Verifique se a coluna Capacity (Capacidade) reflete o tamanho real disponível no seu pool do TrueNAS.
Clique no datastore e depois em Datastore browser.
Tente criar uma pasta de teste chamada conexao_ok. Se a pasta for criada, as permissões de Maproot que configuramos no TrueNAS estão funcionando perfeitamente.
"Se ao tentar montar o Datastore você receber um erro de 'Operation failed', verifique três pontos: primeiro, se o serviço NFS está ativo no TrueNAS; segundo, se o firewall do ESXi está permitindo o tráfego de saída do cliente NFS (Networking > Firewall rules > NFS Client)." Certifique-se também que há conectividade entre o ESXi e o TrueNAS, e que o Firewall da rede não está bloqueando nada.
O ghettoVCB é um script que utiliza as APIs nativas do VMware para criar snapshots, copiar os arquivos para o storage externo (TrueNAS) e depois remover o snapshot, tudo isso com a VM ligada.
Vamos precisar do nome do seu Datastore par inserir nos scripts. No terminal do ESXi, seus discos ficam em /vmfs/volumes/. Para saber o caminho exato do seu SSD, digite ls /vmfs/volumes/. Você pode usar o nome amigável (ex: DATASTORE_SSD) nos scripts.
Acesse o repositório oficial do ghettoVCB no GitHub.
No seu ESXi, crie a pasta de scripts dentro do seu Datastore persistente (não use pastas do sistema como /tmp, pois elas somem no reboot):
mkdir -p /vmfs/volumes/SEU_DATASTORE/scripts/
Faça o upload dos arquivos ghettoVCB.sh e ghettoVCB.conf via Datastore Browser na Web.
Dê permissão de execução:
chmod +x /vmfs/volumes/SEU_DATASTORE/scripts/ghettoVCB.sh
Edite o arquivo de configuração para refletir o seu ambiente de laboratório. Abaixo estão as variáveis críticas que ajustamos:
VM_BACKUP_VOLUME=/vmfs/volumes/NFS_BACKUP (Define o destino dos backups no TrueNAS).
DISK_BACKUP_FORMAT=thin (Essencial para economizar espaço; ele não copia os blocos vazios do disco virtual).
VM_BACKUP_ROTATION_COUNT=3 (Mantém apenas os últimos 3 backups de cada VM, deletando o mais antigo automaticamente).
ENABLE_HARD_CONF_CHECK=0 (Permite que o backup continue mesmo se houver pequenos avisos de configuração).
VM_SNAPSHOT_MEMORY=0 e VM_SNAPSHOT_QUIESCE=0 (Aumenta a velocidade e reduz o risco de "congelamento" da VM durante o snapshot).
Se for 1 (Ligado): O VMware despeja todo o conteúdo da RAM (ex: 4GB ou 8GB) para um arquivo no disco antes de iniciar o backup. Isso permite que, no restore, a VM volte exatamente no estado em que estava, com as janelas e processos abertos.
Por que usamos 0 (Desligado)? Despejar a RAM no disco demora muito, consome muito espaço no Datastore e, se a VM tiver muita escrita em memória, pode causar um "stun" (travamento momentâneo) perceptível na rede. Para backup de servidor (Domain Controller, Firewall, Web Server), o que importa é o disco, não o estado da RAM naquele segundo.
O ghettoVCB precisa de um arquivo de texto simples contendo exatamente os nomes das VMs que aparecem no seu inventário do ESXi (Case Sensitive).
Para ver todas as VMs registradas no seu host, use o comando:
vim-cmd vmsvc/getallvms
Para testar o backup com apenas uma VM específica (ex: seu Debian01), basta criar um arquivo temporário:
echo "Debian01" > /vmfs/volumes/[ID]/scripts/teste_vms
Importante: Antes de automatizar, teste com uma única VM para validar a gravação:
/vmfs/volumes/[SEU_DATASTORE]/scripts/ghettoVCB.sh -f /vmfs/volumes/[SEU_DATASTORE]/scripts/teste_vms -g /vmfs/volumes/[SEU_DATASTORE]/scripts/ghettoVCB.conf
Acompanhe a taxa de transferência.
Após confirmação que o Backup está funcionando corretamente, vamos automatizar a inserção das VMs no arquivo de inventário, ou seja, para que não seja necessário inserir manualmente no arquivo, usamos um "one-liner" que limpa o cabeçalho e extrai apenas a segunda coluna (os nomes):
vim-cmd vmsvc/getallvms | awk '{print $2}' | grep -v "Name" > /vmfs/volumes/[ID]/scripts/lista_vms
Comando para efetuar o backup já com a lista de inventário completa:
/vmfs/volumes/[ID]/scripts/ghettoVCB.sh -f /vmfs/volumes/[ID]/scripts/lista_vms -g /vmfs/volumes/[ID]/scripts/ghettoVCB.conf
-f: Aponta para o arquivo lista_vms que criamos no passo anterior.
-g: Aponta para o arquivo de configuração global que acabamos de editar.
-d: (Opcional) Nível de debug. Use -d info se precisar entender por que uma VM específica falhou.
Observação: Antes de colocar no Cron, valide se o script está lendo a lista de VMs corretamente e conseguindo gravar no TrueNAS. "Muitos tutoriais mandam rodar o backup direto no Cron. Não faça isso. Rode manualmente a primeira vez e acompanhe o log no TrueNAS. Monitore o espaço no Datastore de origem, pois o snapshot temporário consome espaço enquanto o backup está rodando."
Diferente de um simples cp, este script oferece menu de seleção, exibe progresso via vmkfstools -i e isola a rede da VM restaurada (startConnected = FALSE) para evitar conflitos de IP com a produção.
Script de Restore:
#!/bin/sh
#CRIADO POR: FELIPE DE OLIVEIRA ALMEIDA
#E-MAIL: felipe-ti@outlook.com
#DATA: 29/03/26
#VERSÃO: 2
#POR FAVOR, MANTENHA NO SCRIPT OS DADOS DO AUTOR.
# Configurações de Caminho
NFS_PATH="/vmfs/volumes/NFS_BACKUP"
RESTORE_LOG="/vmfs/volumes/NFS_BACKUP/restore_history.log"
TIMESTAMP=$(date +%Y%m%d_%H%M)
echo "--- 1. SELECIONE A VM NO TRUENAS ---"
i=1
for vm in $(ls ${NFS_PATH} | grep -vE ".log|scripts|teste.txt"); do
echo "$i) $vm"
eval "vm_$i=$vm"
i=$((i+1))
done
printf "Número da VM: "
read vm_num
eval "SELECTED_VM=\$vm_$vm_num"
[ -z "$SELECTED_VM" ] && exit 1
echo "--- 2. SELECIONE A VERSÃO ---"
j=1
for folder in $(ls ${NFS_PATH}/${SELECTED_VM}); do
echo "$j) $folder"
eval "folder_$j=$folder"
j=$((j+1))
done
printf "Número da versão: "
read folder_num
eval "SELECTED_FOLDER=\$folder_$folder_num"
[ -z "$SELECTED_FOLDER" ] && exit 1
echo "--- 3. SELECIONE O DATASTORE DE DESTINO ---"
k=1
IFS=$'\n'
for ds in $(df -h | grep "/vmfs/volumes/" | grep -vE "NFS_BACKUP|tmp"); do
FREE_SPACE=$(echo $ds | awk '{print $4}')
DS_PATH=$(echo $ds | awk '{print $6}')
echo "$k) $(basename $DS_PATH) [Livre: $FREE_SPACE]"
eval "ds_path_$k=$DS_PATH"
k=$((k+1))
done
printf "Número do Datastore: "
read ds_num
eval "DEST_DATASTORE=\$ds_path_$ds_num"
# Definições de nomes
NEW_VM_NAME="restored_${SELECTED_VM}_${TIMESTAMP}"
DEST_PATH="${DEST_DATASTORE}/${NEW_VM_NAME}"
echo "-----------------------------------------------"
echo "Destino: ${DEST_PATH}"
mkdir -p "${DEST_PATH}"
# 1. Copia arquivos pequenos primeiro
cp "${NFS_PATH}/${SELECTED_VM}/${SELECTED_FOLDER}/${SELECTED_VM}.vmx" "${DEST_PATH}/${NEW_VM_NAME}.vmx"
cp "${NFS_PATH}/${SELECTED_VM}/${SELECTED_FOLDER}/${SELECTED_VM}.nvram" "${DEST_PATH}/${NEW_VM_NAME}.nvram"
# 2. Copia o DISCO com BARRA DE PORCENTAGEM (vmkfstools)
echo "Copiando Disco Virtual (VMDK) - Aguarde a porcentagem:"
vmkfstools -i "${NFS_PATH}/${SELECTED_VM}/${SELECTED_FOLDER}/${SELECTED_VM}.vmdk" "${DEST_PATH}/${NEW_VM_NAME}.vmdk" -d thin
if [ $? -eq 0 ]; then
echo "Ajustando VMX e Isolando Redes..."
# AJUSTE QUE VOCÊ FEZ MANUALMENTE: Corrige referências internas
sed -i "s/${SELECTED_VM}.vmdk/${NEW_VM_NAME}.vmdk/g" "${DEST_PATH}/${NEW_VM_NAME}.vmx"
sed -i "s/${SELECTED_VM}.nvram/${NEW_VM_NAME}.nvram/g" "${DEST_PATH}/${NEW_VM_NAME}.vmx"
sed -i "s/displayName = \".*\"/displayName = \"${NEW_VM_NAME}\"/g" "${DEST_PATH}/${NEW_VM_NAME}.vmx"
# ISOLAMENTO: Desabilita as 4 placas de rede (startConnected = FALSE)
for eth in 0 1 2 3; do
# Se a linha existir, altera. Se não existir, adiciona.
if grep -q "ethernet${eth}.present = \"TRUE\"" "${DEST_PATH}/${NEW_VM_NAME}.vmx"; then
sed -i "s/ethernet${eth}.startConnected = \"TRUE\"/ethernet${eth}.startConnected = \"FALSE\"/g" "${DEST_PATH}/${NEW_VM_NAME}.vmx"
# Garante que a linha exista
grep -q "ethernet${eth}.startConnected" "${DEST_PATH}/${NEW_VM_NAME}.vmx" || echo "ethernet${eth}.startConnected = \"FALSE\"" >> "${DEST_PATH}/${NEW_VM_NAME}.vmx"
fi
done
# UUID: Responde "I Copied It" automaticamente
echo 'uuid.action = "create"' >> "${DEST_PATH}/${NEW_VM_NAME}.vmx"
# 3. Registro e Power On
echo "Registrando e Ligando VM no inventário..."
VM_ID=$(vim-cmd solo/registervm "${DEST_PATH}/${NEW_VM_NAME}.vmx")
vim-cmd vmsvc/power.on ${VM_ID}
STATUS="SUCESSO"
echo "-----------------------------------------------"
echo "VM registrada com ID: ${VM_ID} e iniciada com rede OFF."
else
STATUS="ERRO"
echo "Falha crítica na cópia do disco via vmkfstools."
fi
# 4. Log
echo "$(date +%F\ %H:%M:%S) | ${STATUS} | VM: ${NEW_VM_NAME} | DS: ${DEST_DATASTORE}" >> ${RESTORE_LOG}
Destaques do Script de Restore:
Seleção por Menu: Lista VMs e Datas disponíveis no TrueNAS.
Destino Dinâmico: Lista Datastores locais e o espaço livre antes de iniciar.
Cópia Otimizada: Usa vmkfstools -i para exibir a porcentagem de conclusão e manter o provisionamento Thin.
Isolamento de Rede: Desabilita automaticamente todas as interfaces de rede (startConnected = FALSE) no arquivo .vmx.
UUID Automático: Insere uuid.action = "create" para que a VM ligue sem perguntas no console.
Observação: Este não é o script de Restore do projeto. Este foi desenvolvido por Felipe de Oliveira Almeida. Caso prefira, pode utilizar o script de restore do link de download que já te passei.
Para evitar backups manuais ou esquecer VMs novas, criamos um script que varre o host e ignora o próprio storage de backup (TrueNAS) para evitar loops.
(Consideramos que o disco de backup da VM do TrueNAS não fica neste servidor. O ideal é que você utilize um host separado só para o TrueNAS, mas como aqui é laboratório, seguimos com um disco à parte do servidor).
Script: /vmfs/volumes/[DATASTORE]/scripts/update_vm_list.sh
#!/bin/sh
VM_LIST="/vmfs/volumes/[DATASTORE]/scripts/lista_vms"
# Lista nomes, remove cabeçalho e ignora a VM do TrueNAS
vim-cmd vmsvc/getallvms | awk '{print $2}' | grep -vE "Name|TrueNAS" | sed '/^$/d' > ${VM_LIST}
Destaques do Script Update de Inventário:
# 1. Lista as VMs registradas
# 2. Filtra a segunda coluna (nomes)
# 3. Remove o cabeçalho "Name" e a VM do TrueNAS para não fazer backup de si mesma
# 4. Remove linhas vazias e salva no arquivo
Ação: Lembre-se de dar permissão de execução: chmod +x /vmfs/volumes/[DATASTORE]/scripts/update_vm_list.sh
Como o ESXi reseta o arquivo de agendamentos no reboot, precisamos garantir que tanto a atualização da lista quanto o backup sejam reinjetados no sistema toda vez que o host ligar.
Edite o arquivo de inicialização: vi /etc/rc.local.d/local.sh
Adicione estas linhas antes do exit 0:
#!/bin/sh
# local configuration options
# Note: modify at your own risk! If you do/use anything in this
# script that is not part of a stable API (relying on files to be in
# specific places, specific tools, specific output, etc) there is a
# possibility you will end up with a broken system after patching or
# upgrading. Changes are not supported unless under direction of
# VMware support.
# Note: This script will not be run when UEFI secure boot is enabled.
# Aguarda o storage NFS montar
sleep 60
# Reinicia o Cron para garantir limpeza
/bin/kill $(cat /var/run/crond.pid)
# TAREFA 1: Atualizar a lista de VMs a cada 6 horas (00h, 06h, 12h, 18h)
/bin/echo "0 */6 * * * /vmfs/volumes/63297b02-eb8ef3c8/scripts/update_vm_list.sh" >> /var/spool/cron/crontabs/root
# TAREFA 2: Rodar o backup às 02:00 AM
/bin/echo "0 2 * * * /vmfs/volumes/63297b02-eb8ef3c8/scripts/ghettoVCB.sh -f /vmfs/volumes/63297b02-eb8ef3c8/scripts/lista_vms -g /vmfs/volumes/63297b02-eb8ef3c8/scripts/ghettoVCB.conf > /vmfs/volumes/NFS_BACKUP/ghettoVCB-full-backup.log 2>&1" >> /var/spool/cron/crontabs/root
# Reinicia o serviço de Cron
/usr/lib/vmware/busybox/bin/busybox crond
# Cria o alias para o comando restore
alias restore='/vmfs/volumes/63297b02-eb8ef3c8/scripts/restore_vm_interativo_v2.sh'
exit 0
IMPORTANTE: Salve o estado do sistema para não perder nada no próximo reboot: /sbin/auto-backup.sh
"Agendamos o update_vm_list.sh para rodar de 6 em 6 horas para garantir que, se você criar ou deletar uma VM durante o dia, a lista que o backup usará às 02:00 AM esteja sempre correta. Isso evita que o backup tente copiar uma VM que não existe mais ou esqueça de proteger uma nova."
+--------------+----------------------------------------------------------+
| FERRAMENTA | FUNÇÃO NO PROJETO |
+--------------+----------------------------------------------------------+
| NFS | Protocolo de comunicação entre ESXi e TrueNAS. |
+--------------+----------------------------------------------------------+
| ghettoVCB | Engine de backup baseada em snapshots (quente). |
+--------------+----------------------------------------------------------+
| vmkfstools | Manipulação e clonagem otimizada de discos virtuais. |
+--------------+----------------------------------------------------------+
| sed / awk | Automatização de edição do .vmx e extração de inventário.|
+--------------+----------------------------------------------------------+
| vim-cmd | Interface de linha de comando para gestão de VMs no ESXi.|
+--------------+----------------------------------------------------------+