GrabDuck

Резервное копирование виртуальных машин ESXi с помощью скриптов ghettoVCB

:

В этой статье я пошагово опишу настройку автоматического резервного копирования и пример восстановления виртуальных машин, работающих на платформе ESX(i) с помощью свободных скриптов ghettoVCB. Акцентироваться буду на версии ESXi 5.x, но эти же средства работают и на версиях 3.5-6.x, правда для ранних версий настройки несколько отличаются. Бэкап будет производиться на NFS сервер. Отчёт о работе будет направлен в почту. Во время бэкапа делается снимок (snapshot) виртуальной машины (в том числе и работающей), сохраняются VMDK диски машины и снимок удаляется.
Проект ghettoVCB отлично документирован, но в процессе внедрения появились нюансы, которые и вылились в эту инструкцию. Надеюсь, статья будет полезна начинающим администраторам.
  1. Настройка резервного копирования
  2. Сохранение конфигурации сервера ESXi
  3. Восстановление машины из резервной копии
  4. Ссылки

Настройка резервного копирования


Первым делом приготовьте NFS сервер по вкусу, куда будут производится бэкапы. В моём случае это FreeNAS (Freebsd 9.3) и ZFS dataset с включённой дедубликацией и сжатием, что существенно экономит место. Настройка на ESXi сервере производится по SSH от пользователя root. Можно и под другим пользователем с административными правами, но тогда не получится запустить скрипты для проверки из консоли. Приступим.

1. Для настройки необходим доступ на сервер по SSH, включаем через vSphere client:

Configuration -> security profile -> properties -> SSH

2. Берём скрипты из github репозитория и помещаем содержимое на сервер. Обязательно ставим бит исполнения, иначе скрипты работать не будут:

# chmod u+x /ghettoVCB-master/ghettoVCB.sh
# chmod u+x /ghettoVCB-master/ghettoVCB-restore.sh

3. Бэкапить будем раз в неделю, с циклом 4 недели. Просроченные бэкапы будут удаляться. Прописываем соответствующий config-файл:

# cat /ghettoVCB-master/4week.conf
VM_BACKUP_VOLUME=/vmfs/volumes/backup
DISK_BACKUP_FORMAT=thin
#количество хранимых бэкапов
VM_BACKUP_ROTATION_COUNT=4
POWER_VM_DOWN_BEFORE_BACKUP=0
ENABLE_HARD_POWER_OFF=0
ITER_TO_WAIT_SHUTDOWN=3
POWER_DOWN_TIMEOUT=5
ENABLE_COMPRESSION=0
ALLOW_VMS_WITH_SNAPSHOTS_TO_BE_BACKEDUP=0
ENABLE_NON_PERSISTENT_NFS=1
UNMOUNT_NFS=1
# NFS сервер, куда будут лететь бэкапы
NFS_SERVER=10.1.3.101
NFS_MOUNT=/mnt/backup/vmware
NFS_LOCAL_NAME=backup
# папка на NFS сервере (для каждого ESXi своя)
NFS_VM_BACKUP_DIR=autobackup/vm01
SNAPSHOT_TIMEOUT=15
#настройки логирования в почту
EMAIL_LOG=1
EMAIL_SERVER=mail.core.local
EMAIL_SERVER_PORT=25
EMAIL_DELAY_INTERVAL=1
EMAIL_TO=admins@mail.local
EMAIL_FROM=ghettoVCB@vm01.core.local
WORKDIR_DEBUG=0
VM_SHUTDOWN_ORDER=
VM_STARTUP_ORDER=
Где ключевые параметры:
  • VM_BACKUP_VOLUME — путь на сервере ESXi, куда будет монтироваться nfs раздел;
  • DISK_BACKUP_FORMAT=thin — формат VMDK диска, который будет создан при бэкапе;
  • VM_BACKUP_ROTATION_COUNT — количество хранимых бэкапов;
  • POWER_VM_DOWN_BEFORE_BACKUP=0 — не выключаем машину перед бэкапом;
  • ENABLE_COMPRESSION=0 — не жмём данные, оставляем это на zfs;
  • ALLOW_VMS_WITH_SNAPSHOTS_TO_BE_BACKEDUP=0 – бэкап машин со снапшотами (последние версии скриптов это умеют, но нам не надо);
  • ENABLE_NON_PERSISTENT_NFS=1 — nfs диск будет подключатся только на время бэкапа;
  • UNMOUNT_NFS=1 — а после отключатся;
  • NFS_SERVER и NFS_MOUNT – координаты nfs диска;
  • NFS_LOCAL_NAME — имя, которое будет присвоено подключенному массиву (datastores identification);
  • NFS_VM_BACKUP_DIR — путь, куда будут складываться копии (относительно VM_BACKUP_VOLUME);
  • EMAIL_LOG=1 — включаем отправку отчёта по почте;
  • EMAIL_* — настройки параметров почты.

Если на сервере ESXi уже есть подключенный nfs диск с такими же координатами (сервер/путь), то диск не подключится.

Тело письма формируется во время работы скрипта, а затем отсылается утилитой nc. Это может вызвать отказ со стороны почтового сервера, с аргументом " Recipient address rejected: Improper use of SMTP command pipelining". Нужно исключить соответствующую проверку для серверов ESXi (у postfix-а это будет reject_unauth_pipelining).

4. Создаём список машин, которые необходимо бэкапить. Получить его можно с помощью команды esxcli vm process list. Каждая строчка списка — одна машина:

# cat /ghettoVCB-master/week.list
win7
win10
vCenterUpdate
Если нужно несколько планов бэкапов, с разной периодичностью и параметрами — создаём необходимое количество конфигураций.

5. Настраиваем cron на выполнение периодической задачи:

# cat /var/spool/cron/crontabs/root
#min hour day mon dow command
#……………………….

3    18   *   *   6     /ghettoVCB-master/ghettoVCB.sh -g /ghettoVCB-master/4week.conf -f /ghettoVCB-master/week.list > /var/log/ghettoVCB-backup-week-$((($(date +\%d)-1)/7+1)).log

Системное время идёт в UTC, потому необходимо делать поправку на текущий часовой пояс. В моём случае +7 часов — бэкап запустится в воскресенье в 1 час ночи. Логи писать обязательно (или переправлять в /dev/null), иначе при переполнении буфера, отведённого для пользователя, скрипт может зависнуть. Конструкция $((($(date +\%d)-1)/7+1)) выдаёт номер недели в месяце, таким образом не наплодим мусора.

6. Перезапускаем cron:

# kill $(cat /var/run/crond.pid)
# crond

7. Для отправки почты необходимо добавить разрешение на исходящий трафик в firewall сервера ESXi:

  • создаём файл настройки с содержимым:
    # cat /etc/vmware/firewall/email.xml
    <ConfigRoot>
      <service>
        <id>email</id>
        <rule id="0000">
          <direction>outbound</direction>
          <protocol>tcp</protocol>
          <porttype>dst</porttype>
          <port>25</port>
        </rule>
        <enabled>true</enabled>
        <required>false</required>
      </service>
    </ConfigRoot>
    

  • перечитываем правила файрвола проверяем:
    # esxcli network firewall refresh
    # esxcli network firewall ruleset list | grep email
    email                  true
    # nc mail.core.local 25
    220 mail.core.local SMTP Postfix
    quit
    221 2.0.0 Bye
    

Запустить тестовую проверку бэкапа машины с именем «vCenterUpdate» можно следующим образом:

# /ghettoVCB-master/ghettoVCB.sh -g /ghettoVCB-master/4week.conf -d dryrun -m vCenterUpdate
Вывод:
# /ghettoVCB-master/ghettoVCB.sh -g /ghettoVCB-master/4week.conf -d dryrun -m vCenterUpdate
Logging output to "/tmp/ghettoVCB-2015-08-18_07-15-08-23516502.log" ...
2015-08-18 07:15:09 -- info: ============================== ghettoVCB LOG START ==============================

2015-08-18 07:15:09 -- info: CONFIG - USING GLOBAL GHETTOVCB CONFIGURATION FILE = /ghettoVCB-master/4week.conf
2015-08-18 07:15:09 -- info: CONFIG - VERSION = 2015_05_06_1
2015-08-18 07:15:09 -- info: CONFIG - GHETTOVCB_PID = 23516502
2015-08-18 07:15:09 -- info: CONFIG - VM_BACKUP_VOLUME = /vmfs/volumes/backup/autobackup/vm01
2015-08-18 07:15:09 -- info: CONFIG - ENABLE_NON_PERSISTENT_NFS = 1
2015-08-18 07:15:09 -- info: CONFIG - UNMOUNT_NFS = 1
2015-08-18 07:15:09 -- info: CONFIG - NFS_SERVER = 10.1.3.101
2015-08-18 07:15:09 -- info: CONFIG - NFS_VERSION = nfs
2015-08-18 07:15:09 -- info: CONFIG - NFS_MOUNT = /mnt/backup/vmware
2015-08-18 07:15:09 -- info: CONFIG - VM_BACKUP_ROTATION_COUNT = 4
2015-08-18 07:15:09 -- info: CONFIG - VM_BACKUP_DIR_NAMING_CONVENTION = 2015-08-18_07-15-08
2015-08-18 07:15:09 -- info: CONFIG - DISK_BACKUP_FORMAT = thin
2015-08-18 07:15:09 -- info: CONFIG - POWER_VM_DOWN_BEFORE_BACKUP = 0
2015-08-18 07:15:09 -- info: CONFIG - ENABLE_HARD_POWER_OFF = 0
2015-08-18 07:15:09 -- info: CONFIG - ITER_TO_WAIT_SHUTDOWN = 3
2015-08-18 07:15:09 -- info: CONFIG - POWER_DOWN_TIMEOUT = 5
2015-08-18 07:15:09 -- info: CONFIG - SNAPSHOT_TIMEOUT = 15
2015-08-18 07:15:09 -- info: CONFIG - LOG_LEVEL = dryrun
2015-08-18 07:15:09 -- info: CONFIG - BACKUP_LOG_OUTPUT = /tmp/ghettoVCB-2015-08-18_07-15-08-23516502.log
2015-08-18 07:15:09 -- info: CONFIG - ENABLE_COMPRESSION = 0
2015-08-18 07:15:09 -- info: CONFIG - VM_SNAPSHOT_MEMORY = 0
2015-08-18 07:15:09 -- info: CONFIG - VM_SNAPSHOT_QUIESCE = 0
2015-08-18 07:15:09 -- info: CONFIG - ALLOW_VMS_WITH_SNAPSHOTS_TO_BE_BACKEDUP = 0
2015-08-18 07:15:09 -- info: CONFIG - VMDK_FILES_TO_BACKUP = all
2015-08-18 07:15:09 -- info: CONFIG - VM_SHUTDOWN_ORDER =
2015-08-18 07:15:09 -- info: CONFIG - VM_STARTUP_ORDER =
2015-08-18 07:15:09 -- info: CONFIG - RSYNC_LINK = 0
2015-08-18 07:15:09 -- info: CONFIG - EMAIL_LOG = 1
2015-08-18 07:15:09 -- info: CONFIG - EMAIL_SERVER = mail.core.local
2015-08-18 07:15:09 -- info: CONFIG - EMAIL_SERVER_PORT = 25
2015-08-18 07:15:09 -- info: CONFIG - EMAIL_DELAY_INTERVAL = 2
2015-08-18 07:15:09 -- info: CONFIG - EMAIL_FROM = ghettoVCB@vm02.core.local
2015-08-18 07:15:09 -- info: CONFIG - EMAIL_TO = admins@mail.local
2015-08-18 07:15:09 -- info: CONFIG - WORKDIR_DEBUG = 0
2015-08-18 07:15:09 -- info:
2015-08-18 07:15:10 -- dryrun: ###############################################
2015-08-18 07:15:10 -- dryrun: Virtual Machine: vCenterUpdate
2015-08-18 07:15:10 -- dryrun: VM_ID: 588
2015-08-18 07:15:10 -- dryrun: VMX_PATH: /vmfs/volumes/ds3524_ds/vCenterUpdate/vCenterUpdate.vmx
2015-08-18 07:15:10 -- dryrun: VMX_DIR: /vmfs/volumes/ds3524_ds/vCenterUpdate
2015-08-18 07:15:10 -- dryrun: VMX_CONF: vCenterUpdate/vCenterUpdate.vmx
2015-08-18 07:15:10 -- dryrun: VMFS_VOLUME: ds3524_ds
2015-08-18 07:15:10 -- dryrun: VMDK(s):
2015-08-18 07:15:10 -- dryrun:  vCenterUpdate.vmdk      40 GB
2015-08-18 07:15:10 -- dryrun: INDEPENDENT VMDK(s):
2015-08-18 07:15:10 -- dryrun: TOTAL_VM_SIZE_TO_BACKUP: 40 GB
2015-08-18 07:15:10 -- dryrun: ###############################################

2015-08-18 07:15:10 -- info: ###### Final status: OK, only a dryrun. ######

2015-08-18 07:15:10 -- info: ============================== ghettoVCB LOG END ================================

Запустить в ручную для списка машин:

# /ghettoVCB-master/ghettoVCB.sh -g /ghettoVCB-master/4week.conf -f /ghettoVCB-master/week.list

Каждая копия машин будет хранится в директориях, вида:
autobackup/vm01/VMNAME/VMNAME-FULL_DATE/

И представлять из себя диск машины в формате *.vmdk и файл конфигурации машины *.vmx.

Сохранение конфигурации сервера ESXi


Настройки ESXi, произведённые выше, будут жить до первой перезагрузки. Для сохранения конфигурации нужно сделать ещё ряд действий.

1. Добавим в загрузочный скрипт команды на изменение настроек cron-а:

# cat /etc/rc.local.d/local.sh
#...................
/bin/kill $(cat /var/run/crond.pid)
/bin/echo "3    18   *   *   6     /ghettoVCB-master/ghettoVCB.sh -g /ghettoVCB-master/4week.conf -f /ghettoVCB-master/week.list > /var/log/ghettoVCB-backup-week-$((($(date +\%d)-1)/7+1)).log" >> /var/spool/cron/crontabs/root
/bin/busybox crond

2. Для сохранения настроек файрвола сделаем собственный VIB пакет и установим его на сервер. Для этого используем утилиту VIB Author. К сожалению, она только для 32-х битной архитектуры, поэтому мне пришлось воспользоваться lxc контейнером. При установке может страшно ругаться на зависимости вида:

# rpm -ivh vmware-esx-vib-author-5.0.0-0.0.847598.i386.rpm
error: Failed dependencies:
        libc.so.6()(64bit) is needed by vmware-esx-vib-author-5.0.0-0.0.847598.i386
        libc.so.6(GLIBC_2.2.5)(64bit) is needed by vmware-esx-vib-author-5.0.0-0.0.847598.i386
        libc.so.6(GLIBC_2.3)(64bit) is needed by vmware-esx-vib-author-5.0.0-0.0.847598.i386
        libc.so.6(GLIBC_2.4)(64bit) is needed by vmware-esx-vib-author-5.0.0-0.0.847598.i386
        libdl.so.2()(64bit) is needed by vmware-esx-vib-author-5.0.0-0.0.847598.i386
        libdl.so.2(GLIBC_2.2.5)(64bit) is needed by vmware-esx-vib-author-5.0.0-0.0.847598.i386
        libpthread.so.0()(64bit) is needed by vmware-esx-vib-author-5.0.0-0.0.847598.i386
        libpthread.so.0(GLIBC_2.2.5)(64bit) is needed by vmware-esx-vib-author-5.0.0-0.0.847598.i386

Но это не беда, и ключ rpm --nodeps нас спасёт.

Подготавливаем дерево директорий для сборки VIB пакета:

# mkdir -p stage/payloads/payload1/etc/vmware/firewall/ 

И создаём два файла. Первый — описание нашего пакета:
# cat stage/descriptor.xml
<vib version="5.0">
  <type>bootbank</type>
  <name>mailFirewall</name>
  <version>5.0.0-0.0.1</version>
  <vendor>Lelik.13a</vendor>
  <summary>Custom VIB from Lelik.13a</summary>
  <description>Adds custom firewall rule for mail sender to ESXi host</description>
  <relationships>
    <depends>
    </depends>
    <conflicts/>
    <replaces/>
    <provides/>
    <compatibleWith/>
  </relationships>
  <software-tags>
  </software-tags>
  <system-requires>
    <maintenance-mode>false</maintenance-mode>
  </system-requires>
  <file-list>
  </file-list>
  <acceptance-level>community</acceptance-level>
  <live-install-allowed>true</live-install-allowed>
  <live-remove-allowed>true</live-remove-allowed>
  <cimom-restart>false</cimom-restart>
  <stateless-ready>true</stateless-ready>
  <overlay>false</overlay>
  <payloads>
    <payload name="payload1" type="vgz"></payload>
  </payloads>
</vib>
Подробную инструкцию к параметрам можно посмотреть на сайте утилиты.

И второй файл — email.xml, содержимое которого приведено выше. А находится он будет по пути stage/payloads/payload1/etc/vmware/firewall/email.xml, где путь после " payload1" – желаемый путь на целевом сервере.

Собираем VIB пакет:

# vibauthor -C -t stage -v mailFirewall.vib

И проверяем его содержимое
# vibauthor -i -v mailFirewall.vib
**** Info for VIB: mailFirewall.vib ****
VIB Format:             2.0.0
VIB ID:                 Lelik.13a_bootbank_mailFirewall_5.0.0-0.0.1
VIB Type:               bootbank
Name:                   mailFirewall
Version:                5.0.0-0.0.1
Vendor:                 Lelik.13a
Summary:                [Fling] Custom VIB from Lelik.13a
Description:            Adds custom firewall rule for mail sender to ESXi host
Creation Date:          2015-08-12 09:47:07.199735+00:00
Provides:
        mailFirewall = 5.0.0-0.0.1
Depends:
Conflicts:
Replaces:
        mailFirewall << 5.0.0-0.0.1
Software Tags:          []
MaintenanceMode:        remove/update: False, installation: False
Signed:                 False
AcceptanceLevel:        community
LiveInstallAllowed:     True
LiveRemoveAllowed:      True
CimomRestart:           False
StatelessReady:         True
Overlay:                False
Payloads:
  Name            Type        Boot Size        Checksums
  payload1        vgz         0    347         sha-256 69aa821faa4ccd5a5e34e487ecf6049aa6bf55652ffffbfaae1257e40610c405
                                               sha-1 4d77e529c8da74e82d4aa4e816bcf193e29ab8de


При нужде, можете воспользоваться моим пакетом (на свой страх и риск).

3. Копируем наш пакет на сервер ESXi, устанавливаем и проверяем, что получилось:

# esxcli software vib install -v /tmp/mailFirewall.vib -f
# esxcli software vib list | grep mail
# esxcli network firewall refresh
Так как пакет добавляет свои файлы в систему, то необходимо использование ключа " -f".
И на всякий случай, перечитываем правила файрвола.

Таким образом можно собрать и зафиксировать и другие полезные настройки сервера.

4. И в завершение, запускаем в ручную бэкап настроек сервера ESXi:

# /sbin/auto-backup.sh

Восстановление машины из резервной копии


Сразу нужно учитывать, что машина, резервирование которой производилось на горячую, после восстановления будет как после краша — возможна потеря данных внутри машины.

1. Подключаем хранилище с бэкапом на целевой ESXi сервер по NFS, либо просто копируем туда данные по ssh.

2. Создаём конфигурационный файл «vms_to_restore» такого вида:

# cat /ghettoVCB-master/vms_to_restore
#"<DIRECTORY or .TGZ>;<DATASTORE_TO_RESTORE_TO>;<DISK_FORMAT_TO_RESTORE>"
# DISK_FORMATS
# 1 = zeroedthick
# 2 = 2gbsparse
# 3 = thin
# 4 = eagerzeroedthick
# e.g.
"/vmfs/volumes/restore/autobackup/vm01/vCenterUpdate/vCenterUpdate-2015-08-13_07-55-50/;/vmfs/volumes/local_vm01/;3;vCenterUpdate-restore"
Где по порядку через " ;":
  • путь, где лежит восстанавливаемая машина;
  • путь, куда восстановить машину (директория под неё будет создана);
  • тип диска машины для восстановления;
  • новое имя машины (не обязательно).

3. Запускаем тестовый прогон:

# /ghettoVCB-master/ghettoVCB-restore.sh  -c /ghettoVCB-master/vms_to_restore -d 1

И боевой:
# /ghettoVCB-master/ghettoVCB-restore.sh  -c /ghettoVCB-master/vms_to_restore -l /var/log/vms-restore.log
################## Restoring VM: vCenterUpdate-restore  #####################
Start time: Fri Aug 14 06:05:06 UTC 2015
Restoring VM from: "/vmfs/volumes/restore/autobackup/vm01/vCenterUpdate/vCenterUpdate-2015-08-13_07-55-50/"
Restoring VM to Datastore: "/vmfs/volumes/local_vm01/" using Disk Format: "thin"
Creating VM directory: "/vmfs/volumes/local_vm01//vCenterUpdate-restore" ...
Copying "vCenterUpdate.vmx" file ...
Restoring VM's VMDK(s) ...
Updating VMDK entry in "vCenterUpdate-restore.vmx" file ...
Destination disk format: VMFS thin-provisioned
Cloning disk '/vmfs/volumes/restore/autobackup/vm01/vCenterUpdate/vCenterUpdate-2015-08-13_07-55-50//vCenterUpdate.vmdk'...
Clone: 100% done.
Registering vCenterUpdate-restore ...
12
End time: Fri Aug 14 06:11:19 UTC 2015

4. Радуемся.

Второй вариант. Так как бэкап представляет собой дамп машины с конфигурационным файлом, то можно просто:

1. Cкопировать его куда-нибудь на ESXi сервер.

2. Исправить файл конфигурации машины (*.vmx), изменив поля имени и местоположения диска машины:

displayName = vCenterUpdate-restore
extendedConfigFile = "vCenterUpdate-restore.vmxf"
scsi0:0.fileName  = "vCenterUpdate-restore-0.vmdk"
sched.swap.derivedName = "vCenterUpdate-ff0c3749.vswp"
Пути до файлов можно (и нужно) указывать относительно директории машины.

3. Через vSphereClient идём в хранилище:

Configuration -> storage -> ПКМ -> "browse datastore"

и добавляем новую машину в список:
ПКМ -> "Add to inventory" на файле *.vmx

4. Если сервер восстановления другой, то в настройках машины меняем «Network Connection».

5. При первом запуске оно спросит, от куда нарисовалась машина, нужно ответить, что перенесли.
Если ответить, что клонировали — изменит уникальные данные, в том числе mac адрес сетевой карты.

Вот в целом и всё. Скрипты ghettoVCB поддерживают ещё другие интересные параметры и варианты копирования, так что полезно почитать документацию. Метод далёк от идеального, но если хочется дёшево и сердито, то вполне работоспособен.

Спасибо за внимание.

Cсылки