Резервное копирование виртуальных машин в KVM
В данной статье мы рассмотрим несколько вариантов резервного копирования виртуальных машин на гипервизоре KVM, а так сценарии восстановления из бэкапов. Хочется сразу отметить, что как таковых удобных инструментов для резервного копирования под KVM нет, и каждый администратор использует свои варианты, скрипты и костыли. Есть 2 сценария бэкапа ВМ в KVM: с остановкой ВМ (самый простой, но используется крайне редко) и без остановки виртуальной машины.
Прежде всего хочется отметить, что особенности резервного копирования в вашем KVM сильно зависят от типа используемых виртуальных дисков: LVM, RAW (IMG) или qcow2. На моих серверах KVM диски виртуальных машин имеют формат qcow2. Я считаю, что данный формат выигрывает у остальных по двум причинам:
- Размер диска всегда имеет размер по занимаемому пространству внутри машины, его достаточно просто увеличить и уменьшить;
- Данный формат поддерживает снапшоты.
Поэтому виртуальные диски в формате qcow2 для меня бэкапить проще всего.
Создание резервных копий в KVM с остановкой виртуальной машины
Если ваш проект допускает кратковременную остановку виртуальной машины, то можно воспользоваться самым простым способом создания резервной копии. Для того, чтобы у вас всегда под рукой были актуальные резервные копии, вам нужно скопировать файл диска и конфигурационный файл самой виртуальной машины (на случай если меняется конфигурация).
С помощью virsh выведем список виртуальных машин в KVM:
# virsh list
Id Name State ---------------------------------------------------- 1 test-centos running 4 generic running
Так же у меня есть директория, куда я планирую сохранять резервные копии виртуальных машин:
# df -h | grep backup
/dev/sda1 1.8T 77M 1.7T 1% /backup
Конфигурационный файл виртуальной машины, можно скопировать следующей командой:
# virsh dumpxml VM > /backup/VM.xml
Где VM – это имя вашей виртуальной машины.
Теперь, чтобы создать резервную копию диска виртуальной машины, нужно остановить виртуальную машину и скопировать образ диска в целевой каталог:
# virsh shutdown test-centos
# cp /vz/disk/test-centos.img /backup/
После того, как диск полностью скопировался, нужно запустить виртуальную машину:
# virsh start test-centos
Для каждой виртуальной машины, можно создавать отдельную директорию и автоматизировать процесс создания копий, добавив команды скрипт и настроить задания в cron.
Либо можете воспользоваться небольшим и простым скриптом:
#!/bin/bash
data=`date +%Y-%m-%d`
backup_dir=/backup
vm=`virsh list | grep . | awk '{print $2}'| sed 1,2d | tr -s '\n' ' '`
for activevm in $vm
do
mkdir -p $backup_dir/$activevm
# Бэкапим конфигурацию XML для виртуальной машины
virsh dumpxml $activevm > $backup_dir/$activevm/$activevm-$data.xml
# Адрес дисков виртуальных машин
disk_path=`virsh domblklist $activevm | grep vd | awk '{print $2}'`
# Останавливаем рабочую машин
virsh shutdown $activevm
sleep 2
for path in $disk_path
do
# Убираем имя файла из пути
filename=`basename $path`
# Создаем бэкап диска
gzip -c $path > $backup_dir/$activevm/$filename-$data.gz
sleep 2
virsh start $activevm
sleep 2
done
done
/usr/bin/find /backup/ -type f -mtime +7 -exec rm -rf {} \;
Добавьте данный скрипт в крон и выполняйте так часто, как вам это требуется. Скрипт автоматически останавливает виртуальную машину, бэкапит файл диска и файл конфигурации, после чего автоматически запускает виртуальную машину.
В результате выполнения скрипта, у вас будут созданы директории для каждой виртуальной машины и в них помещены файл диска и дамп конфигурации, а также удалены старые резервные копии (количество дней укажите сами):
# ls -la test-centos
-rw-r--r-- 1 root root 5440 Feb 19 12:17 test-centos-2020-02-19.xml -rw-r--r-- 1 root root 38609784 Feb 19 12:18 test-centos.img.gz
KVM: резервное копирование без остановки виртуальной машины
Естественно, в большинстве случае администраторы хотят использовать вариант “живого” резервного копирования виртуальных машин KVM без остановки. Он немного сложнее первого варианта и требует дополнительных действий. В данном варианте используется создание снапшота и последующее его объединение с файлом диска виртуальной машины. В самом начале статьи я писал, что использую формат дисков qcow2 и как раз это и позволяет создать живой бэкап. Для того, чтобы вы могли корректно создать копию виртуальной машины, в ВМ должен быть добавлен Channel Device с именем org.qemu.guest_agent.0 (можно добавить через конфигурационный файл или virt-manager).
Совет. Если не установить настроить агент для гостевые ВМ, при создании снапшота будет появляться ошибка:
error: argument unsupported: QEMU guest agent is not configured
Не забудьте добавить конфигурационный XML файл виртуальной машины следующий блок:
<channel type='unix'> <target type='virtio' name='org.qemu.guest_agent.0'/> </channel>
Добавляется он в секцию “Device”, после чего нужно сохранить конфигурацию и выполнить ребут машины.
Затем в гостевой ОС нужно установить пакет qemu-guest-agent (установите его через yum/dnf):
# yum install qemu-guest-agent -y
Для создания снапшота ВМ используется следующая команда:
# virsh snapshot-create-as --domain VM snapshot --disk-only --atomic --quiesce –no-metadata
Где VM — это имя виртуальной машины. Далее нужно создать бэкап файла диска:
# gzip -c VM > /backup/VM/VM.gz
После того, как диск виртуальной машины будет скопирован, нужно выполнить объединение его со снапшотом:
# virsh blockcommit VM vda --active --verbose --pivot
Где vda – это результат выполнения команды:
# virsh domblklist VM | grep vd | awk '{print $1}'
Я переделав предыдущий скрипт бэкапа с остановкой виртуальных машин. Теперь резервное копирование запускается по cron с созданием снапшотов и объединением его с диском виртуальной машины:
#!/bin/bash
data=`date +%Y-%m-%d`
backup_dir=/backup
vm=`virsh list | grep . | awk '{print $2}'| sed 1,2d | grep -vf /root/bin/exclude | tr -s '\n' ' '`
for activevm in $vm
do
mkdir -p $backup_dir/$activevm
# Бэкапим конфигурацию XML для виртуальной машины
virsh dumpxml $activevm > $backup_dir/$activevm/$activevm-$data.xml
# Список дисков виртуальных машин
disk_list=`virsh domblklist $activevm | grep vd | awk '{print $1}'`
# Адрес дисков виртуальных машин
disk_path=`virsh domblklist $activevm | grep vd | awk '{print $2}'`
# Создаем снапшот диcков
virsh snapshot-create-as --domain $activevm snapshot --disk-only --atomic --quiesce --no-metadata
sleep 3
for path in $disk_path
do
# Убираем имя файла из пути
filename=`basename $path`
# Создаем бэкап диска
gzip -c $path > $backup_dir/$activevm/$filename-$data.gz
sleep 3
done
for disk in $disk_list
do
# Определяем путь до снепшота
snapshot=`virsh domblklist $activevm | grep $disk | awk '{print $2}'`
# Объединяем снапшот с диском
virsh blockcommit $activevm $disk --active --verbose --pivot
sleep 2
# Удаляем снепшот
rm -rf $snapshot
done
done
/usr/bin/find /backup/ -type f -mtime +7 -exec rm -rf {} \;
Данный скрипт выполнит резервное копирование подобно первому варианту, только без остановки виртуальной машины (работает корректно, протестировано на виртуальных серверах с postgresql, mariadb и nginx с php-fpm). Конечный результат будет точно такой же, у вас будет бэкап конфигурационного файла и файла диска.
Для хранения резервных копий вы можете использовать удаленные сервера (можно копировать данные через Rsync) или хранилища .