Консистентное резервное копирование контейнеров в Proxmox встроенными средствами
12 Июль 2023 17:25 Сергей Морозов (изменено 12 Июль 2023 18:45)
Суть проблемы: по умолчанию, в случае с резервным копированием контейнеров в Proxmox штатными средствами, мы получаем "грязную" копию. Например, если в контейнере находится MySQL, он не знает, что его копируют, и не сохраняет изменения на диск.
В случае с виртуальными машинами эта проблема решается средствами Qemu Guest Agent. Для контейнеров такого средства нет, но vzdump (встроенное в Proxmox средство резервного копирования) может запускать скрипт на каждую операцию, и в этом скрипте можно выполнить pct exec
для того, чтобы подготовить контейнер к резервному копированию.
Добавляем в /etc/vzdump.conf строку:
script: /var/lib/vz/snippets/proxmox-hook-backup.sh
Код скрипта /var/lib/vz/snippets/proxmox-hook-backup.sh:
#!/bin/bash
ACTION=${1}
METHOD=${2}
CTID=${3}
run-hook-pct() {
HOOK=${1}
pct exec ${CTID} -- /bin/sh -c "[ -x /etc/proxmox-hook-backup.sh ] && /etc/proxmox-hook-backup.sh ${HOOK}" || true
}
backup-start() {
if pct status ${CTID} ; then
run-hook-pct backup-start
fi
}
backup-end() {
if pct status ${CTID} ; then
run-hook-pct backup-end
fi
}
pre-stop() {
if pct status ${CTID} ; then
run-hook-pct pre-stop
fi
}
pre-restart() {
if pct status ${CTID} ; then
run-hook-pct pre-restart
fi
}
post-restart() {
if pct status ${CTID} ; then
run-hook-pct post-restart
fi
}
case ${ACTION} in
backup-start) backup-start ;;
backup-end) backup-end ;;
pre-stop) pre-stop ;;
pre-restart) pre-restart ;;
post-restart) post-restart ;;
esac
Теперь на каждую операцию vzdump внутри каждого контейнера будет выполняться скрипт /etc/proxmox-hook-backup.sh (при его наличии), а в первом параметре будет передано имя хука. Вот пример такого скрипта для резервного копирования MySql:
#!/bin/sh
MYSQL_USER="backup"
MYSQL_PASSWORD="super-secret-password"
cd /tmp
backup_start() {
echo "Locking mysql tables"
echo "FLUSH TABLES WITH READ LOCK;" | mysql -u "${MYSQL_USER}" -p "${MYSQL_PASSWORD}"
sync
}
post_restart() {
echo "Unlocking mysql tables"
echo "UNLOCK TABLES;" | mysql -u "${MYSQL_USER}" -p "${MYSQL_PASSWORD}"
}
case $1 in
backup-start) backup_start ;;
post-restart) post_restart ;;
esac
Этот скрипт в хуке backup-start (перед резервным копированием) выполняет FLUSH TABLES WITH READ LOCK
, затем, в хуке post-restart (после резервного копирования) разблокирует таблицы, выполняя UNLOCK TABLES
.