Скрипт для живой миграции виртуальной машины между нодами Proxmox с ZFS-репликацией
Опубликовано:
В этой инструкции разберём готовый скрипт для миграции виртуальной машины в кластере Proxmox с двумя нодами и ZFS-репликацией дисков. Скрипт сам определяет, на какой ноде сейчас находится VM, синхронизирует диски перед переносом и запускает живую миграцию без остановки сервиса — удобный вариант, если миграция виртуальных машин Proxmox выполняется регулярно.
Настройки перед запуском
Перед первым использованием скрипт нужно адаптировать под свой кластер — все параметры вынесены в начало файла:
- NODE1 — имя первой ноды кластера.
- NODE2 — имя второй ноды.
- REPLICATION_ID — префикс задания репликации из /etc/pve/replication.cfg (обычно local).
- ONLINE — переключатель живой миграции: 1 переносит VM без остановки, 0 — офлайн.
- WITH_LOCAL_DISKS — по умолчанию должен оставаться 1. При ZFS-репликации диски VM хранятся локально на каждой ноде, а не на общем (shared) хранилище — без этого флага онлайн-миграция с локальных дисков не запустится.
* если задание репликации для VM ещё не настроено, скрипт его просто не найдёт в /etc/pve/replication.cfg и перейдёт сразу к миграции, без ошибки.
** флаг WITH_LOCAL_DISKS отключаем только если хранилище дисков уже общее для обеих нод (shared storage) — тогда --with-local-disks не нужен и Proxmox мигрирует VM без копирования данных.
- #!/bin/bash
- # Перенос VM на другую ноду кластера (ZFS replication).
- # Usage: /scripts/migrate-peer.sh <vmid>
- set -e
- # --- настройки ---
- NODE1=pve1
- NODE2=pve2
- REPLICATION_ID=local
- ONLINE=1 # 1 = live migrate, 0 = offline
- WITH_LOCAL_DISKS=1 # 1 нужен для online + local-zfs
- SSH_OPTS="-o StrictHostKeyChecking=accept-new"
- # ---
- if [ -z "${1:-}" ]; then
- cat >&2 <<EOF
- Перенос VM между нодами $NODE1 и $NODE2 (ZFS replication).
- Использование: $0 <vmid>
- Пример: $0 100
- EOF
- exit 1
- fi
- VMID=$1
- if ! [[ $VMID =~ ^[0-9]+$ ]]; then
- echo "Ошибка: vmid должен быть числом, получено: $VMID" >&2
- echo "Использование: $0 <vmid>" >&2
- exit 1
- fi
- if [ -f /etc/pve/nodes/$NODE1/qemu-server/$VMID.conf ]; then
- SRC=$NODE1
- TARGET=$NODE2
- elif [ -f /etc/pve/nodes/$NODE2/qemu-server/$VMID.conf ]; then
- SRC=$NODE2
- TARGET=$NODE1
- else
- echo "VM $VMID не найдена на $NODE1 / $NODE2" >&2
- exit 1
- fi
- echo "$VMID: $SRC -> $TARGET"
- ssh_src() {
- ssh $SSH_OPTS "root@$SRC" "$@"
- }
- JOB=$(awk -v id="$VMID" -v pref="$REPLICATION_ID" \
- '$1==(pref ":") && $2 ~ "^"id"-" {print $2; exit}' \
- /etc/pve/replication.cfg 2>/dev/null || true)
- if [ -n "$JOB" ]; then
- echo "репликация $JOB..."
- ssh_src "pvesr run --id $JOB --verbose"
- fi
- OPTS=""
- [ "$ONLINE" = 1 ] && OPTS="$OPTS --online"
- [ "$WITH_LOCAL_DISKS" = 1 ] && OPTS="$OPTS --with-local-disks"
- ssh_src "qm migrate $VMID $TARGET $OPTS"
- echo "OK: VM $VMID на $TARGET"
Как работает скрипт
Сначала скрипт проверяет, что параметр vmid передан и является числом — без этого перенос не начнётся.
Дальше скрипт ищет конфиг VM в /etc/pve/nodes на обеих нодах и сам определяет, где машина находится сейчас, а куда её нужно перенести. Направление миграции указывать вручную не нужно.
Если для VM найдено задание репликации в replication.cfg, скрипт сначала запускает pvesr run — это синхронизирует диски на целевой ноде перед переносом и сокращает время простоя при живой миграции.
После этого собираются опции для qm migrate: --online — для переноса без остановки VM, --with-local-disks — для дисков на local-zfs. Последней командой скрипт запускает саму миграцию Proxmox на целевой ноде.
Скрипт готов к использованию. Достаточно передать ему vmid — и перенос виртуальной машины пройдет автоматически.