Автор Тема: Резервная копия виртуальных машин на лету (libvirt)  (Прочитано 603 раз)

Оффлайн KALIBR-10

  • Давно тут
  • **
  • Сообщений: 427
Наконец-то доработал под себя скрипт создания бекапов ВМ и решил поделиться для критики и предложений  :-)
Имеется:
Сервер (Альт Базовая виртуализация 9) + СХД на которой находятся тома LVM
На сервер в /backupvm смонтирована NFS-шара
В крон добавлено задание выполнения скрипта, в котором по очереди выполняются скрипты следующего содержания:

#!/bin/bash
# Название ВМ
vmname="asterisk";

#Вычисление текущей даты
curdata=`date +"%Y-%m-%d"`;

#Определение каталога для бекапа
backupdir="/backupvm/$curdata";

#Название виртуального диска (логического тома)
diskname0="vm-342-disk-0";

#Генерируется имя снапшота
snapname0=$vmname"_snap";

#Имя группы логических томов где расположен виртуальный диск
lvname="veqlogic1";

#Определение работает ли ВМ в данный момент
checkvm=`/usr/bin/virsh list | grep $vmname | sed 's/ //g'`;

#Проверка условия: есть ли файл в директории и работает ли ВМ
#Данный файл создан на сервере NFS, добавлен аттрибут +i, то есть файл нельзя удалить даже root
# По сути если данного файла нет в этом каталоге то NFS-шара недоступна
if [ -f "/backupvm/control" ] && [ -n "$checkvm" ] ; then

#Если оба условия истина начинается бекап
#Создание каталога бекапа
mkdir -p $backupdir/$vmname;

#Сообщение в лог-файл ВМ о времени начала бекапа
echo "`date +"%Y-%m-%d_%H-%M-%S"` Start backup VM" > $backupdir/$vmname/progress.log

#Сообщение в лог-файл ВМ о времени начала сохранения конфигурации ВМ
echo "`date +"%Y-%m-%d_%H-%M-%S"` Save cofiguration VM" >> $backupdir/$vmname/progress.log

#Скохрание конфигурации дисков ВМ (данные об объёме)
/usr/bin/virsh domblkinfo $vmname --all > $backupdir/$vmname/diskinfo

#Сохраниения общей конфигурации ВМ
/usr/bin/virsh dumpxml $vmname > $backupdir/$vmname/config.xml

#Запись в лог-файл ВМ времени начала сохранения состояния ВМ
echo "`date +"%Y-%m-%d_%H-%M-%S"` Save state VM" >> $backupdir/$vmname/progress.log

#Сохранение состояния ВМ
/usr/bin/virsh save $vmname $backupdir/$vmname/statevm --running >> $backupdir/$vmname/progress.log

#Запись в лог-файл ВМ времени начала создания снапшота
echo "`date +"%Y-%m-%d_%H-%M-%S"` Create snapshot LV" >> $backupdir/$vmname/progress.log

#Создание снапшота (размер COW-таблиц подбирать опционально. 256М на ненагруженных системах. На SQL приходится задавать более 2G)
/sbin/lvcreate -s -n $snapname0 -L256M /dev/$lvname/$diskname0 >> $backupdir/$vmname/progress.log

#Запись в лог-файл ВМ времени начала восстановления состояния ВМ
echo "`date +"%Y-%m-%d_%H-%M-%S"` Restore state VM" >> $backupdir/$vmname/progress.log

#Восстановление состояния ВМ
/usr/bin/virsh restore $backupdir/$vmname/statevm >> $backupdir/$vmname/progress.log

#Запись в лог-файл времени начала бекапа снапшота
echo "`date +"%Y-%m-%d_%H-%M-%S"` Backup snapshot" >> $backupdir/$vmname/progress.log

#Бекап снапшота и его сжатие
/bin/dd if=/dev/$lvname/$snapname0 bs=4k | /usr/bin/zstd -c --fast > $backupdir/$vmname/"$snapname0".zst

#Запись в отдельный файл информации о состоянии снапшота после окончания бекапа
/sbin/lvdisplay /dev/$lvname/$snapname0 > $backupdir/$vmname/$diskname0"_snapstate"

#Опредение состояния снапшота
snapstate=`cat $backupdir/$vmname/$diskname0"_snapstate" | grep 'LV snapshot status' | cut -b 26-31`;
if [ $snapstate = 'active' ]; then

#Если активен значит статус ОК
snapstatus='OK'
else

#Если не активен значит статус ERROR (нужно увеличить размер COW-таблиц)
snapstatus='ERROR'
fi

#Запись в лог-файл ВМ времени удаления снапшота
echo "`date +"%Y-%m-%d_%H-%M-%S"` Remove snapshot" >> $backupdir/$vmname/progress.log

#Удаление снапшота
/sbin/lvremove -y /dev/$lvname/$snapname0 >> $backupdir/$vmname/progress.log

#Запись в лог-файл ВМ времени окончания бекапа ВМ
echo "`date +"%Y-%m-%d_%H-%M-%S"` End backup VM" >> $backupdir/$vmname/progress.log

#Запись в общий лог-файл текущих бекапов информации о выполнении бекапа и статусе снапшота
echo "`date +"%Y-%m-%d_%H-%M-%S"` Backup VM $vmname is completed [$snapstatus]" >> $backupdir/backupvm.log
else

#Запись в общий лог-файл текущих бекапов информации об ошибке выполнения бекапа (либо NFS-шара недоступна либо ВМ выключена)
echo "`date +"%Y-%m-%d_%H-%M-%S"` !!!ERROR!!! Failed backup VM $vmname" >> $backupdir/backupvm.log
fi


Вот как-то так  ;-)

Простой ВМ незначительный, только во время сохранения состояния и восстановления (зависит от объёма используемой системой ОЗУ и скорости записи на NFS-шару) в моём случае например ВМ с 4ГБ ОЗУ недоступна лишь 5 секунд.

При восстановлении бекапа так же восстанавливается и состояние ВМ, для неё это будет просто перемещение во времени, uptime продолжается.
« Последнее редактирование: 25.01.2021 15:59:45 от KALIBR-10 »
Разбаньте в телеге шакалы!!!

Оффлайн rits

  • Завсегдатай
  • *
  • Сообщений: 1 041
  • ITS
#Определение работает ли ВМ в данный момент
checkvm=`/usr/bin/virsh list | grep $vmname | sed 's/ //g'`;
а почему не так?
# virsh domstate "host"
Возможно ddrescue быстрее будет чем dd, правда сам не проверял по конвейеру, это так к слову, для оптимизации, можно проверить.

Оффлайн KALIBR-10

  • Давно тут
  • **
  • Сообщений: 427
а почему не так?
# virsh domstate "host"
Мне такая проверка показалась проще, так как если ВМ выключена, то значение будет пустое. Иначе пришлось бы выбирать по условию относительно возвращаемого значения.

Про ddrescue даже не знал, затестирую.
Разбаньте в телеге шакалы!!!