пятница, 3 июля 2015 г.

Сохранение (backup) клиентских виртуальных машин.

Исходные данные: 
Xubuntu 14.04 (64 разряда + Windows всех мастей под VirtualBox).

Есть много (штук примерно 20) компьютеров под Xubuntu, на которых установлен VirtualBox и запускается виртуальная машина. Конечно винды, конечно с комплектом каких-то мерзких, совершенно не переносимых программ для формирования налоговой отчетности и т.п. Этот зоопарк (виртуалки) надо периодически сохранять. Бэкапить саму Ксубунту смысла никакого, ее быстрее, случись чего, заново поставить. Все полезные документы исключительно на серверах (или внутри ВМ...).  Всякие хорошие и полезные программы типа bacula ориентированы на копирование серверов и несколько избыточны в плане возможностей (ну и не слишком в плане удобства и дружелюбия). Требование примерно такие. 

  1. Все хранится в дереве файлов. Никаких доп. баз данных.
  2. Формат хранения не требует никаких средств кроме общесистемных для извлечения архивной копии.
  3. Запускается на клиенте, пишет на сервер.
  4. Желательно кроме основной копии на сервере (одной) иметь еще несколько архивных копий на самом клиенте.
  5. Ну и простота, для прозрачности процесса.

Как и что. 

В качестве хранилища rcyncd, делаем модуль в режиме write-only, это защитит копию от всякого рода рисков. Все клиенты в единое дерево, идентификация по имени машины и клиента, чтоб заранее в дереве ничего не создавать. В качестве средства создания локальной копии tar и logrotate. Запуск в "околоручном" режиме при попытке выхода из сеанса. Вот с этого места и начнем.


В xfce4 выход из сеанса реализован запуском xfce4-session-logout. Живет она где-то в /usr/bin. Если взять свой скриптик, поименовать его так же и положить в /usr/local/bin, получим его вызов стандартными средствами при попытке выхода из сеанса или выключения компьютера. 

Ну вот он и есть /usr/local/bin/xfce4-session-logout:

#! /bin/bash

###
# Пре-назначения. В конфиг файле можно все переназначить
FLAG=$HOME/.need2backupvm
VMDIR=$HOME/.Virtulbox\ VMs
VMNAME='Mint\ 17'
BASE='root@192.168.20.1::onecopy'
NROTATE=5
LOCALSTORE=$HOME/.local/share/vb_backup

CONFIG=$HOME/.config/vmbackupconfig
SYSTEMPROG=/usr/bin/xfce4-session-logout
COPY=/usr/local/bin/copy_vm.bash

# Config
test -r ${CONFIG} && . ${CONFIG}

# Check flag
if [ ! -r $FLAG ] ; then
  $SYSTEMPROG
  exit 0
fi
###

# Make selection
res=`zenity --list --radiolist \
       --title="Резервная копия виртуальной машины" \
       --text="Настало время скопировать ВМ, выберете вариант. Копирование занимает примерно час" \
       --column="Выбор" --column="parametr" --column="Что дальше" \
       TRUE "bcppower" "Запуститить копирование, по окончании выключить" \
       FALSE "bcponly" "Запустить копирование, по окончании не выключать" \
       FALSE "sys" "Отложить копирование (вызвать системый диалог)" \
       --hide-column=2 --print-column="2"`
CASE=$?

case $CASE in
0)
  case ${res} in
  sys)
  $SYSTEMPROG
  ;;
  *)
notify-send -i info Information "Резервное копирование запущено"
# Make backup here
#
# $1 - имя ВМ для остановки
# $2 - каталог, который мы копируем
# $3 - база к которой будет добавлено $DEST на сервере
# в виде root@192.168.20.1::onecopy
# $4 - Локальное хранилище                                                      
# $5 - количество копий 

$COPY "$VMNAME" "$VMDIR" $BASE "$LOCALSTORE" "$NROTATE" | logger
notify-send -i info Information "Резервное копирование завершено"
rm -f $FLAG
if [[ $res == 'bcppower' ]] ; then
 $SYSTEMPROG --halt 
fi
  ;;
  esac
  ;;
-1)
          zenity --error --text="Внутреняя ошибка 001."
  ;&
    1)
  $SYSTEMPROG
  ;;

esac

exit 0

Задача скрипта совсем не сложная - проверить флажок (пора - не пора, ставим его по крону с нужной периодичностью), получить добро у юзера и запустить вторую часть.

Часть вторая, /usr/local/bin/copy_vm.bash:

#! /bin/bash
#
# $1 - имя ВМ для остановки
# $2 - каталог, который мы копируем
# $3 - база к которой будет добавлено $DEST на сервере
# в виде root@192.168.20.1::onecopy
# $4 - Локальное хранилище
# $5 - количество копий

DEST=`hostname -s`
DEST=$DEST-$USER
LIST=`VBoxManage list runningvms |grep "$1" | cut -d'"' -f2`
LRSTATE=$HOME/.cache/logrotate/vm_copy
LRCONF=$HOME/.config/vm_copy-logrotate
TARFILE=${4}/vm.tar

# Выключаем нужную ВМ
if [[ -n $LIST ]] ; then
        VBoxManage controlvm "$LIST" savestate 2>&1  | logger
fi

# Копия на сервер
rsync -a -H -x -o --numeric-ids --del -A "$2" ${3}/$DEST/

# Локальная копия (архив)
# Делаем конфиг для logrotate
echo "$TARFILE {
  rotate $5
  compress
}" > ${LRCONF}

# Каталог нодобно заранее создать...
mkdir -p ${4}

# logrotate
touch "$LRSTATE"
test -r ${TARFILE} && logrotate -f -s "$LRSTATE" "$LRCONF"

# Тарим
tar cf ${TARFILE} "$2"

Тут и пояснять-то нечего.

На сервере (там стоит не слишком свежая Гента, но отличий почти нет). Фрагмент конфига. /etc/rsyncd.conf

# This line is required by the /etc/init.d/rsyncd script
pid file = /run/rsyncd.pid

# Global
use chroot = yes
address = 192.168.20.1

[onecopy]
path = /mnt/storage/onecopy
comment = Client backups
read only = false
write only = true
uid = root
list = false
ignore nonreadable
dont compress = *.gz *.tgz *.tar.gz *.zip *.7z *.rar *.deb *.bz2 *.iso

Что в итоге?

Во всей получившейся, довольно стройной, системе нет ни единого пароля. Все сделано без подпиливания каких-либо штатных средств. Практически вся нагрузка остается на клиенте, сервер не напрягаем. Путем небольших изменений конфига можно заставить самую последнюю копию хранить на клиенте, а остальные дублировать на сервер (а оно нужно?)
Да, в конфиге ничего интересного:
spec-5@spec-5:~/.config$ less vmbackupconfig 
VMDIR=$HOME/.VirtualBox/Machines
VMNAME='WinXP'
BASE='root@192.168.20.1::onecopy'

В /etc/cron.weekly/vmbcp (имя файла не имеет значения)
#! /bin/bash

# VM backup
DUSER=имя подставить
touch /home/${DUSER}/.need2backupvm
chmod a+rw /home/${DUSER}/.need2backupvm

Последнее изменение 20150826

Комментариев нет:

Отправить комментарий