Применимо к редакции: МСВСфера 9 (ФСТЭК)

14.9. Резервное копирование

14.9.1. Резервное копирование настроек гипервизора

Системные настройки гипервизора libvirt хранятся в виде файлов в каталоге /etc/libvirt. Соответственно, для создания их резервной копии может быть применён любой инструмент резервного копирования, умеющий работать с файлами и каталогами. В состав операционной системы включены утилиты tar, rsync и система резервного копирования bacula.

Пример создания локальной резервной копии с помощью команды tar:

$ tar -cjpf "etc-libvirt.$(date --iso-8601).tar.bz2" /etc/libvirt

В результате выполнения в текущем каталоге будет создан файл etc-libvirt-YYYY-MM-DD.tar.bz2 где YYYY — год, MM — месяц и DD — сегодняшнее число.

Автоматизировать создание резервных копий можно с помощью службы периодического выполнения заданий cron или таймеров systemd.

Например, для создания ежедневных архивов вы можете создать файл (в данном примере libvirt-backup.sh) в каталоге /etc/cron.daily следующего содержания:

#!/bin/bash

# прекратить выполнение если любая из команд вернёт ненулевой код возврата
set -e

# сменить текущий каталог на /srv/backup
cd /srv/backup
# создать архив с конфигурационными файлами гипервизора libvirt
tar -cjpf "etc-libvirt.$(date --iso-8601).tar.bz2" /etc/libvirt

И сделать его исполняемым:

$ sudo chmod +x /etc/cron.daily/libvirt-backup.sh

После этого служба cron будет автоматически выполнять сценарий каждый день.

Для восстановления можно использовать следующую команду (замените etc-libvirt.YYYY-MM-DD.tar.bz2 на реальное имя файла):

$ tar -C / -xpvf etc-libvirt.YYYY-MM-DD.tar.bz2

14.9.1.1. Резервное копирование виртуальных машин

В данном разделе описаны различные подходы к резервному копированию виртуальных машин.

Для начала определимся с данными, которые подлежат резервному копированию:

  • XML конфигурация виртуальной машины — содержит все метаданные, необходимые для запуска виртуальной машины: название и идентификатор, описание выделяемых ресурсов, виртуальных устройств и т.д.;

  • диск (или несколько дисков, в зависимости от конфигурации) виртуальной машины — на нём хранятся разделы и файловые системы, с которыми работает виртуальная машина.

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

14.9.1.2. Ручное создание полной копии файлов виртуальной машины

Самым простым, но при этом самым неэффективным способом резервного копирования виртуальной машины является создание полной копии её дисков вручную:

  • достоинства:
    • простая процедура создания резервной копии;

    • простая процедура восстановления;

  • недостатки:
    • требуется остановка виртуальной машины на время создания копии;

    • каждая последующая резервная копия будет занимать такой же объём дискового пространства, как и исходные диск(и) виртуальной машины.

  • требования:
    • диски виртуальной машины хранятся в виде файлов образов в хранилище типа «каталог» (dir).

Создание резервной копии

Рассмотрим процедуру создания ежедневной резервной копии на примере виртуальной машины msvsphere-9-arm.

  1. Создайте каталог для хранения резервной копии:

    $ mkdir -p -v "/srv/backup/msvsphere-9-arm/$(date --iso-8601)"
    mkdir: created directory '/srv/backup/msvsphere-9-arm/2024-12-16'
    

    Название каталога может быть любым, в этом примере используется вывод команды date --iso-8601, возвращающий текущую дату в формате YYYY-MM-DD.

  2. Остановите виртуальную машину, в противном случае вы рискуете получить неконсистентные данные в резервной копии:

    $ virsh --connect qemu:///system shutdown msvsphere-9-arm
    Domain 'msvsphere-9-arm' is being shutdown
    
  3. Получите список дисков виртуальной машины с помощью команды virsh domblklist:

    $ virsh --connect qemu:///system domblklist msvsphere-9-arm
    Target   Source
    ---------------------------------------------------------
    vda      /var/lib/libvirt/images/msvsphere-9-arm.qcow2
    sda      -
    
  4. Сделайте копию каждого из дисков виртуальной машины в ранее созданный каталог:

    $ cp -a /var/lib/libvirt/images/msvsphere-9-arm.qcow2 \
          /srv/backup/msvsphere-9-arm/2024-12-16/
    
  5. Сделайте копию XML-конфигурации виртуальной машины:

    $ virsh --connect qemu:///system dumpxml msvsphere-9-arm > \
          /srv/backup/msvsphere-9-arm/2024-12-16/msvsphere-9-arm.xml
    
  6. Резервное копирование виртуальной машины завершено и теперь её можно включить:

    $ virsh --connect qemu:///system start msvsphere-9-arm
    Domain 'msvsphere-9-arm' started
    

Как и в случае с резервным копированием конфигурации гипервизора, для автоматизации можно применять shell-сценарий и cron или таймеры systemd. Ниже представлен пример такого сценария.

#!/bin/bash

set -eo pipefail

# список имён виртуальных машин, для которых необходимо выполнять резервное
# копирование
VM_NAMES=('msvsphere-9-arm' 'msvsphere-9-server')
# каталог для хранения резервных копий
BACKUP_DIR='/srv/backup'
TODAY="$(date --iso-8601)"

# функция возвращает текущее состояние виртуальной машины
get_vm_state() {
    local -r vm_name="${1}"
    virsh --connect qemu:///system domstate "${vm_name}"
}

# функция выполняет команду выключения виртуальной машины и ожидает
# соответствующего изменения её статуса
shutdown_vm() {
    local -r vm_name="${1}"
    local -r max_try=10
    local vm_state
    local cur_try=0
    local output
    if ! output="$(virsh --connect qemu:///system shutdown ${vm_name} 2>&1)"; then
        echo "VM ${vm_name} shutdown request failed: ${output}" >&2
        return 1
    fi

    while [ ${cur_try} -lt ${max_try} ]; do
        vm_state="$(get_vm_state ${vm_name})"
        if [ "${vm_state}" == 'shut off' ]; then
            return 0
        else
            cur_try=$((cur_try + 1))
            sleep 5
        fi
    done
    echo "VM ${vm_name} shutdown timeout, state: ${vm_state}" >&2
    return 1
}

# функция выполняет резервное копирование всех дисков и конфигурационного файла
# виртуальной машины
backup_vm() {
    local -r vm_name="${1}"
    local -r backup_dir="${BACKUP_DIR}/${vm_name}/${TODAY}"
    local disk

    mkdir -p "${backup_dir}"

    for disk in $(virsh --connect qemu:///system domblklist "${vm_name}" --details | awk '/disk/{print $4}'); do
        echo "Backing up VM ${vm_name} disk ${disk}" >&2
        ln -s "${disk}" "${backup_dir}/"
        echo "Backing up VM ${vm_name} configuration" >&2
        virsh --connect qemu:///system dumpxml "${vm_name}" > "${backup_dir}/${vm_name}.xml"
    done
}

# обработка заданных виртуальных машин в цикле
for vm_name in "${VM_NAMES[@]}"; do
    echo "Processing VM ${vm_name}" >&2
    vm_state="$(get_vm_state ${vm_name})"
    if [ "${vm_state}" == 'running' ]; then
        # выключение виртуальной машины если она запущена
        echo "VM ${vm_name} is running, shutting it off" >&2
        shutdown_vm "${vm_name}"
        echo "VM ${vm_name} has been shutted off"
    elif [ "${vm_state}" != 'shut off' ]; then
        # поддерживаются только два статуса виртуальной машины: running и
        # shut off
        echo "VM ${vm_name} state is not supported: ${vm_state}" >&2
        exit 1
    fi
    # вызов функции резервного копирования
    backup_vm "${vm_name}"
    # включение виртуальной машины, которая была запущена перед началом
    # процедуры резервного копирования
    if [ "${vm_state}" == 'running' ]; then
        echo "Starting VM ${vm_name} back" >&2
        virsh --connect qemu:///system start "${vm_name}"
    fi
done

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

Для восстановления виртуальной машины из полной копии необходимо выполнить следующие операции.

  1. Если виртуальная машина в данный момент запущена, то необходимо её остановить:

    $ virsh --connect qemu:///system shutdown msvsphere-9-arm
    Domain 'msvsphere-9-arm' is being shutdown
    
  2. Восстановите конфигурацию виртуальной машины из сохранённого XML-файла:

    $ virsh --connect qemu:///system define /srv/backup/msvsphere-9-arm/2024-12-16/msvsphere-9-arm.xml
    Domain 'msvsphere-9-arm' defined from /srv/backup/msvsphere-9-arm/2024-12-16/msvsphere-9-arm.xml
    
  3. Восстановите образ диска виртуальной машины из резервной копии:

    $ sudo /usr/bin/cp /srv/backup/msvsphere-9-arm/2024-12-16/msvsphere-9-arm.qcow2 \
          /var/lib/libvirt/images/msvsphere-9-arm.qcow2
    

    Если вы забыли в каком каталоге должен находиться файл или как он должен называться, то эта информация доступна в блоке disk XML-файла с конфигурацией виртуальной машины:

    <domain type='kvm'>
      ...
      <devices>
        ...
        <disk type='file' device='disk'>
          <driver name='qemu' type='qcow2' discard='unmap'/>
          <source file='/var/lib/libvirt/images/msvsphere-9-arm.qcow2'/>
         <target dev='vda' bus='virtio'/>
         <address type='pci' domain='0x0000' bus='0x04' slot='0x00' function='0x0'/>
       </disk>
       ...
      </devices>
      ...
    </domain>
    
  4. Восстановите владельца и права доступа к файлу образа диска:

    $ sudo chown qemu:qemu /var/lib/libvirt/images/msvsphere-9-arm.qcow2
    $ sudo chmod 600 /var/lib/libvirt/images/msvsphere-9-arm.qcow2
    
  5. После этого восстановленную виртуальную машину можно запускать и продолжать работу:

    $ virsh --connect qemu:///system start msvsphere-9-arm
    Domain 'msvsphere-9-arm' started
    

В случае необходимости, вы можете внести необходимые правки в XML-конфигурацию перед её загрузкой в гипервизор. Например, вам может потребоваться изменить имя (тег name) виртуальной машины если вы восстанавливаете её на другом узле, где уже существует виртуальная машина с таким именем.