Proxmox Backup Server: установка, настройка и восстановление VM — полный гайд

⚡ TL;DR - весь процесс за 60 секунд

PBS — это: отдельный сервер бэкапов от команды Proxmox. Устанавливается с ISO или поверх Debian 12. Подключается к PVE как storage. Делает инкрементальные дедуплицированные бэкапы. Восстанавливает VM за минуты.

Минимальный путь: установи PBS → создай datastore → подключи к PVE → создай backup job → проверь restore. Без последнего шага бэкапов у тебя нет.

Время: 40–60 минут на чистой установке. Требования: 2 ядра, 2 GB RAM (лучше 4+), отдельный диск под хранилище, Debian 12 под капотом.

Что будет в статье: установка PBS (ISO + Debian), datastore на XFS/ZFS, подключение к PVE, backup job для VM и CT, PBS Agent для Windows, retention + GC, восстановление (полное, file-level, тест), мониторинг через Zabbix, шифрование, troubleshooting с командами, скрипты автоматизации.

1. Диагноз: бэкап на том же диске — это не бэкап

У тебя Proxmox VE с десятком виртуалок. Бэкапы «настроены». По факту — папка /var/lib/vz/dump/ на том же диске, куда пишутся VM. Или снапшот раз в неделю на том же хосте.

Диск умрёт — прощай и VM, и бэкап одновременно. RAID не поможет: он защищает от отказа железа, но не от rm -rf, крипто-локера или пожара в стойке.

Второй сценарий хуже: бэкапы есть, но восстановление никто не проверял с момента настройки. Это означает — бэкапов нет. Есть большие файлы непонятного содержания.

Правило трёх: 3 копии, 2 разных носителя, 1 офсайт. Бэкап на том же сервере — это иллюзия спокойствия, а не защита данных.

Почему обычный vzdump без PBS — плохая идея

Критерий vzdump (локально) Proxmox Backup Server
Дедупликация ✅ Чанковая дедупликация
Инкрементальные бэкапы ❌ Всегда полный ✅ После первого — только дельта
Сжатие ✅ zstd/lzo ✅ zstd
Шифрование ✅ AES-256-GCM клиентское
Проверка целостности ✅ Verify по расписанию
File-level restore ✅ Монтирование бэкапа
Web UI для восстановления Через PVE ✅ Отдельный UI PBS
Место на диске 100 GB VM × 7 дней = 700 GB 100 GB VM + инкременты ≈ 120–200 GB
Изоляция от PVE ❌ Один хост — один риск ✅ Отдельный сервер

Что получишь после этой статьи:

  • Рабочий PBS, физически отделённый от PVE
  • Datastore с retention policy — место не закончится неожиданно
  • Backup job для всех VM и CT по расписанию
  • VSS-консистентные бэкапы Windows через PBS Agent
  • Полное и file-level восстановление — с командами
  • Мониторинг в Zabbix + ежедневный email-отчёт
  • Troubleshooting: 10 типичных ошибок с решениями

2. Архитектура PBS: как это работает

Три компонента системы

Компонент Что делает Где живёт
Proxmox VE (PVE) Гипервизор. Запускает VM и CT. Инициирует бэкапы через vzdump Основной сервер виртуализации
Proxmox Backup Server (PBS) Сервер бэкапов. Принимает, хранит, дедуплицирует, шифрует. Управляет retention Отдельный физический сервер или VM с passthrough-диском
Datastore Директория на PBS, куда физически пишутся бэкапы. Может быть несколько (локальный, NAS, S3) Отдельный диск на PBS-сервере

Как работает инкрементальный бэкап PBS

  • Первый бэкап — полный. PBS получает весь диск VM чанками по 4 MB, дедуплицирует, сжимает, сохраняет
  • Последующие бэкапы — только изменённые чанки. PVE отслеживает dirty blocks через CBS (Changed Block Tracking). PBS сравнивает хеши чанков и пишет только новое
  • Дедупликация — одинаковые чанки хранятся один раз. Если у тебя 10 VM с одинаковой базой ОС — общие блоки дисков хранятся единожды
Результат на практике: 10 VM по 50 GB = 500 GB «на бумаге». В реальности PBS с дедупликацией и инкрементами за 30 дней может занять 200–300 GB вместо 15 TB при ежедневных полных бэкапах.

Варианты развёртывания PBS

  • PBS на отдельном физическом сервере — правильно. Бэкапы физически изолированы. Умер PVE-хост — PBS цел
  • PBS как VM на PVE — допустимо для лабы и старта. Обязательно: отдельный диск через passthrough (qm set VMID --scsi1 /dev/sdb), иначе смысл теряется
  • PBS на NAS (Debian + PBS пакеты) — хороший вариант если есть NAS с x86 и достаточно RAM

3. Требования к серверу PBS

Параметр Минимум Рекомендуется Примечание
CPU 2 ядра x86-64 4+ ядра Дедупликация и verify нагружают CPU
RAM 2 GB 4–8 GB Индекс чанков хранится в RAM. ~1 GB на каждые 1 TB datastore
Системный диск 32 GB 60+ GB SSD Только ОС. Бэкапы — на отдельный диск
Диск для хранилища Отдельный HDD/SSD отдельный от системы XFS рекомендуется. ZFS — если есть RAM под ARC
Сеть 1 Gbit 10 Gbit для крупных окружений Узкое место при больших VM и коротком окне бэкапа
ОС Debian 12 Bookworm (устанавливается автоматически с PBS ISO)
Не экономь на RAM. При нехватке памяти PBS начинает использовать swap для индекса чанков — производительность падает в 10–20 раз. Бэкап ночью не успевает до утра.

4. Установка Proxmox Backup Server

Вариант A: установка с ISO (рекомендуется)

Скачай актуальный ISO с официального сайта Proxmox. На момент написания — PBS 3.x.


# Записываем ISO на USB:
# Linux:
dd if=proxmox-backup-server_3.x.iso of=/dev/sdX bs=1M status=progress

# Windows: используй Ventoy или Rufus

Установка стандартная: выбираешь системный диск (не тот, куда будут писаться бэкапы!), hostname, IP, пароль root. После перезагрузки:


# Открой в браузере:
https://IP_СЕРВЕРА:8007
# Логин: root
# Пароль: заданный при установке

Что должно быть: Dashboard PBS с нулевыми datastores и зелёным статусом сервиса.

Вариант B: установка на существующий Debian 12


# Добавляем репозиторий PBS (no-subscription)
echo "deb http://download.proxmox.com/debian/pbs bookworm pbs-no-subscription" \
  > /etc/apt/sources.list.d/pbs.list

# Добавляем GPG-ключ
wget -qO- https://enterprise.proxmox.com/debian/proxmox-release-bookworm.gpg \
  | gpg --dearmor \
  > /etc/apt/trusted.gpg.d/proxmox-release-bookworm.gpg

# Обновляем и ставим
apt update && apt install -y proxmox-backup-server

# Запускаем сервисы
systemctl enable --now proxmox-backup proxmox-backup-proxy

# Проверяем статус
systemctl status proxmox-backup proxmox-backup-proxy

Что должно быть: оба сервиса в статусе active (running). Веб-интерфейс доступен по https://IP:8007.

No-subscription репозиторий — полностью функциональный без каких-либо ограничений по возможностям. Subscription даёт только приоритетные обновления и поддержку вендора. Для домашней лабы и небольших компаний — no-subscription нормально.

5. Создание Datastore и настройка хранилища

Подготовка диска под хранилище


# Смотрим доступные диски
lsblk -o NAME,SIZE,FSTYPE,MOUNTPOINT,MODEL

# Предположим, диск под хранилище - /dev/sdb
# Форматируем под XFS (рекомендуется для PBS)
parted /dev/sdb mklabel gpt
parted /dev/sdb mkpart primary xfs 0% 100%
mkfs.xfs /dev/sdb1

# Получаем UUID для fstab (надёжнее чем /dev/sdX)
blkid /dev/sdb1
# Вывод: UUID="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"

# Создаём точку монтирования и монтируем
mkdir -p /mnt/backup-store
echo "UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx /mnt/backup-store xfs defaults,nofail 0 2" \
  >> /etc/fstab
mount -a

# Проверяем
df -h /mnt/backup-store

XFS vs ZFS для PBS — что выбрать

Критерий XFS ZFS
Требования к RAM Минимальные 1 GB на каждые 1 TB диска для ARC
Производительность записи Высокая Высокая, но требует настройки
Защита данных Базовая (journaling) Checksums, self-healing, снапшоты
RAID Нет (нужен mdadm/hardware) Встроенный RAIDZ
Когда выбирать Мало RAM, простой сценарий Есть RAM, нужна надёжность

# Вариант ZFS: создаём пул (если два диска - mirror)
zpool create backup-pool mirror /dev/sdb /dev/sdc

# Или один диск:
zpool create backup-pool /dev/sdb

# Статус пула:
zpool status backup-pool

# PBS будет использовать /backup-pool как путь к datastore

Создание Datastore


# Через CLI:
proxmox-backup-manager datastore create main /mnt/backup-store \
  --comment "Основное хранилище VM бэкапов"

# Проверяем:
proxmox-backup-manager datastore list

Через веб-интерфейс: Administration → Datastore → Create. Имя — main, путь — /mnt/backup-store.

Retention Policy — настраивай сразу, не потом

Без retention policy диск заполнится, новые бэкапы перестанут писаться, старые не удалятся. Полный паралич.


# Пример политики: 7 ежедневных, 4 еженедельных, 3 ежемесячных, минимум 3 последних
proxmox-backup-manager datastore update main \
  --keep-last 3 \
  --keep-daily 7 \
  --keep-weekly 4 \
  --keep-monthly 3

# Через веб: Datastore → main → Options → Prune Options
Prune vs Garbage Collection — разные вещи: Prune удаляет старые снапшоты по политике (убирает ссылки). GC физически освобождает место, удаляя чанки без ссылок. Prune без GC — место не освобождается. Настрой оба по расписанию.

# Расписание GC - каждый день в 02:30
proxmox-backup-manager datastore update main \
  --gc-schedule "02:30"

# Расписание Prune - каждый день в 03:00 (после GC)
proxmox-backup-manager datastore update main \
  --prune-schedule "03:00"

# Запустить GC вручную немедленно:
proxmox-backup-manager garbage-collection start main

# Статус GC:
proxmox-backup-manager garbage-collection list main

6. Создание пользователя и API-токена для PVE

Не используй root для подключения PVE к PBS. Отдельный пользователь с минимальными правами — стандарт безопасности.


# Создаём пользователя (realm @pbs - внутренний PBS, не @pam)
proxmox-backup-manager user create pve-backup@pbs \
  --password "СложныйПароль123!" \
  --comment "Пользователь для подключения PVE"

# Генерируем API-токен (рекомендую вместо пароля)
proxmox-backup-manager user generate-token pve-backup@pbs pve-token
# ВАЖНО: сохрани токен - он показывается ОДИН РАЗ
# Формат: pve-backup@pbs!pve-token = xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

# Назначаем права на datastore
proxmox-backup-manager acl update /datastore/main \
  --auth-id "pve-backup@pbs!pve-token" \
  --role DatastoreBackup

Роли PBS:

Роль Что может Когда использовать
DatastoreAdmin Всё, включая удаление Только для администратора PBS
DatastoreBackup Только запись бэкапов Для токена PVE → PBS
DatastoreReader Чтение и восстановление Для техподдержки, read-only доступ
DatastoreAudit Только просмотр метаданных Для мониторинга (Zabbix)
RemoteAdmin Управление remote-репозиторием Для sync jobs между PBS-серверами

7. Подключение PBS к Proxmox VE

Получи fingerprint PBS


# На PBS-сервере:
proxmox-backup-manager cert info | grep "Fingerprint"

# Результат вида:
# Fingerprint: AB:CD:EF:12:34:56:...

Через веб-интерфейс PVE

  1. Datacenter → Storage → Add → Proxmox Backup Server
  2. Заполняй:
    • ID: pbs-main
    • Server: IP или hostname PBS
    • Username: pve-backup@pbs!pve-token
    • Password: значение токена
    • Datastore: main
    • Fingerprint: скопируй с PBS выше

Через CLI на PVE-хосте


pvesm add pbs pbs-main \
  --server IP_PBS \
  --datastore main \
  --username "pve-backup@pbs!pve-token" \
  --password "ЗНАЧЕНИЕ_ТОКЕНА" \
  --fingerprint "AB:CD:EF:..." \
  --content backup

# Проверяем статус storage
pvesm status | grep pbs-main

# Смотрим содержимое (существующие бэкапы)
pvesm list pbs-main

Что должно быть: pvesm status показывает pbs-main со статусом active и свободным местом.

8. Настройка Backup Job: расписание и режимы

Режимы бэкапа

Режим Как работает Консистентность Когда использовать
Snapshot VM продолжает работать. PVE делает live-снапшот диска Хорошая (с агентом — отличная) Production VM, нельзя останавливать
Suspend VM замораживается на время снапшота, потом продолжает Отличная Если нет агента, допустима пауза
Stop VM останавливается, бэкапируется, запускается снова Максимальная Некритичные VM, ночное окно обслуживания

Создание Backup Job через веб PVE

  1. Datacenter → Backup → Add
  2. Настройки:
    • Storage: pbs-main
    • Schedule: 02:00 (каждый день в 2 ночи)
    • Selection: All — все VM и CT
    • Mode: Snapshot
    • Compression: zstd
    • Send email to: твой email

Через CLI


# Создаём backup job: все VM, каждую ночь в 02:00
pvesh create /cluster/backup \
  --storage pbs-main \
  --schedule "02:00" \
  --all 1 \
  --mode snapshot \
  --compress zstd \
  --mailnotification always \
  --mailto admin@example.com

# Смотрим все backup jobs
pvesh get /cluster/backup

Ручной запуск бэкапа прямо сейчас


# Бэкап конкретной VM (vmid 101)
vzdump 101 --storage pbs-main --mode snapshot --compress zstd

# Бэкап нескольких VM
vzdump 101 102 103 --storage pbs-main --mode snapshot --compress zstd

# Бэкап всех VM на ноде
vzdump --all --storage pbs-main --mode snapshot --compress zstd

# С подробным выводом (полезно при первом запуске)
vzdump 101 --storage pbs-main --mode snapshot --compress zstd --verbose 1

Остановить текущий бэкап


# Найти PID
pgrep -a vzdump

# Через PVE API
pvesh get /nodes/$(hostname)/tasks | grep vzdump
pvesh delete /nodes/$(hostname)/tasks/UPID:...

# Грубо - только в крайнем случае
pkill -f vzdump

9. PBS Agent для Windows VM: VSS-консистентные бэкапы

Без агента бэкап Windows VM — это снапшот блочного устройства. NTFS может быть в несогласованном состоянии: незафлашенные буферы, открытые транзакции БД. Восстановишь — получишь грязный диск с ошибками файловой системы.

С агентом PVE использует VSS (Volume Shadow Copy Service). Все буферы сброшены, транзакции завершены. Бэкап чистый.

Установка агента на Windows VM

  1. Скачай MSI-установщик: сайт Proxmox → Downloads → Proxmox Backup Client → Windows
  2. Запусти с правами администратора
  3. После установки служба Proxmox Backup Agent стартует автоматически

# Проверяем статус в PowerShell (на Windows VM):
Get-Service "ProxmoxBackupAgent"

# Если не запущена:
Start-Service "ProxmoxBackupAgent"
Set-Service "ProxmoxBackupAgent" -StartupType Automatic

Запуск бэкапа Windows VM с агентом


# На PVE-хосте:
vzdump 105 --storage pbs-main --mode snapshot --compress zstd --agent 1

# В backup job через веб: включи галку "Guest Agent" при настройке job
Агент работает только в режиме snapshot. В режимах stop и suspend VM уже остановлена — диск консистентен без VSS. Агент там не нужен и не задействуется.
Настройка OSPF MikroTik RouterOS 7 Мониторинг сервисов: Uptime Kuma за 5 минут DNS-диагностика: nslookup и dig для сисадмина NetDiag: диагностика сети без установки

 

10. Восстановление VM из PBS: полное, частичное, тест

Бэкап, который ты не проверял — это не бэкап. Восстанавливай тестовую VM хотя бы раз в квартал. Скрипт для этого — в разделе «Профилактика».

Полное восстановление VM через веб PVE

  1. PVE → Storage → pbs-main → Content
  2. Выбери нужный бэкап по дате и VMID
  3. Нажми Restore
  4. Укажи: целевую ноду, storage для диска, VMID (новый или тот же если исходная VM удалена)
  5. Start after restore — включи если нужно сразу стартовать

Полное восстановление через CLI


# Посмотреть доступные бэкапы VM 101
pvesh get /nodes/$(hostname)/storage/pbs-main/content \
  --content backup | grep "vm/101"

# Восстановить VM 101 из последнего бэкапа
# Формат snapshot: vm/101/2025-01-15T02:00:00Z
qmrestore pbs-main:backup/vm/101/2025-01-15T02:00:00Z 101 \
  --storage local-lvm \
  --force 1

# Восстановить LXC-контейнер 201
pct restore 201 pbs-main:backup/ct/201/2025-01-15T02:00:00Z \
  --storage local-lvm \
  --force 1

# Восстановить как новую VM с другим VMID (старая остаётся)
qmrestore pbs-main:backup/vm/101/2025-01-15T02:00:00Z 901 \
  --storage local-lvm

File-level восстановление: достать отдельные файлы из бэкапа

Не нужно восстанавливать всю VM ради одного файла. PBS умеет монтировать бэкап как файловую систему.


# Монтируем бэкап (только чтение)
proxmox-backup-client mount \
  --repository "pve-backup@pbs!pve-token@IP_PBS:main" \
  vm/101/2025-01-15T02:00:00Z \
  /mnt/restore-point

# Смотрим что внутри - образы дисков VM
ls /mnt/restore-point/
# drive-scsi0.img  drive-scsi1.img  ...

# Монтируем нужный диск (ext4/xfs/ntfs)
# Linux:
mount -o ro,loop /mnt/restore-point/drive-scsi0.img /mnt/vm-disk

# Windows NTFS:
mount -o ro,loop,offset=1048576 /mnt/restore-point/drive-scsi0.img /mnt/vm-disk
# (offset зависит от таблицы разделов, используй: fdisk -l /mnt/restore-point/drive-scsi0.img)

# Копируем нужные файлы
cp /mnt/vm-disk/var/www/html/config.php /tmp/restored-config.php

# Размонтируем всё
umount /mnt/vm-disk
proxmox-backup-client umount /mnt/restore-point

Скачать бэкап на локальный диск


# Экспортировать бэкап как .vma.zst (стандартный формат Proxmox)
proxmox-backup-client restore \
  --repository "pve-backup@pbs!pve-token@IP_PBS:main" \
  vm/101/2025-01-15T02:00:00Z \
  drive-scsi0.img.fidx \
  /tmp/vm101-disk.img

# С шифрованием - нужен ключ:
proxmox-backup-client restore \
  --repository "pve-backup@pbs!pve-token@IP_PBS:main" \
  vm/101/2025-01-15T02:00:00Z \
  drive-scsi0.img.fidx \
  /tmp/vm101-disk.img \
  --keyfile /etc/pve/priv/pbs-encryption.key

# Через веб PBS: Datastore → main → vm → 101 → выбери snapshot → Download

11. S3 как дополнительное хранилище: offload бэкапов

PBS не пишет напрямую в S3 — работает только с локальными директориями. Решение: смонтировать S3 как файловую систему через rclone.

Вариант A: rclone mount (рекомендуется)


# Устанавливаем rclone и fuse3
apt install -y rclone fuse3

# Настраиваем подключение к S3 интерактивно
rclone config
# n → имя "s3backup" → тип s3 → провайдер (AWS/Yandex/Selectel)
# → access_key_id, secret_access_key → endpoint (для не-AWS)

# Проверяем подключение
rclone lsd s3backup:

# Создаём systemd-unit для автомонтирования
mkdir -p /mnt/s3-backup

cat > /etc/systemd/system/rclone-s3.service << 'EOF'
[Unit]
Description=RClone S3 Mount for PBS offload
After=network-online.target
Wants=network-online.target

[Service]
Type=notify
ExecStart=/usr/bin/rclone mount s3backup:ИМЯ_БАКЕТА /mnt/s3-backup \
  --vfs-cache-mode writes \
  --allow-other \
  --dir-cache-time 72h \
  --log-level INFO \
  --log-file /var/log/rclone-s3.log
ExecStop=/bin/fusermount -u /mnt/s3-backup
Restart=on-failure
RestartSec=10

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl enable --now rclone-s3
systemctl status rclone-s3

# Добавляем S3 как отдельный datastore в PBS
proxmox-backup-manager datastore create s3-offload /mnt/s3-backup \
  --comment "S3 offload - длительное хранение"

# Retention для S3 (хранить дольше, чем локально)
proxmox-backup-manager datastore update s3-offload \
  --keep-monthly 12 \
  --keep-yearly 3

Вариант B: скрипт еженедельной синхронизации PBS → S3


#!/bin/bash
# /opt/scripts/sync-pbs-to-s3.sh
# cron: 0 4 * * 0 root /opt/scripts/sync-pbs-to-s3.sh

SOURCE="/mnt/backup-store"
DEST="s3backup:ИМЯ_БАКЕТА/pbs"
LOG="/var/log/pbs-s3-sync.log"

echo "$(date): Старт синхронизации PBS → S3" >> "$LOG"

rclone sync "$SOURCE" "$DEST" \
  --transfers 4 \
  --checkers 8 \
  --exclude "*.tmp" \
  --stats 60s \
  --log-file "$LOG" \
  --log-level INFO

RC=$?
if [ $RC -eq 0 ]; then
  echo "$(date): Синхронизация завершена успешно" >> "$LOG"
else
  echo "$(date): ОШИБКА синхронизации, код: $RC" >> "$LOG"
  echo "PBS→S3 sync failed (code $RC). See $LOG" | \
    <a class="wpil_keyword_link" title="mail" href="https://it-apteka.com/tag/mail/" target="_blank" rel="noopener" data-wpil-keyword-link="linked" data-wpil-monitor-id="1337">mail</a> -s "PBS Sync Error $(date +%Y-%m-%d)" admin@example.com
fi

chmod +x /opt/scripts/sync-pbs-to-s3.sh
echo "0 4 * * 0 root /opt/scripts/sync-pbs-to-s3.sh" \
  >> /etc/cron.d/pbs-s3-sync

12. Шифрование бэкапов PBS

Если бэкапы уходят на S3 или в недоверенное хранилище — шифрование обязательно. PBS использует клиентское шифрование AES-256-GCM: ключ знает только клиент, PBS хранит зашифрованные чанки.


# Генерируем ключ шифрования на PVE-хосте
proxmox-backup-client key create /etc/pve/priv/pbs-encryption.key

# СРАЗУ делаем бумажную копию (paperkey)
proxmox-backup-client key paperkey /etc/pve/priv/pbs-encryption.key \
  --output-format text
# Распечатай и положи в сейф. Это не метафора.

# Прописываем ключ в backup job (через웹 PVE: Edit job → Encryption Key)
# Или вручную при vzdump:
vzdump 101 --storage pbs-main --mode snapshot --compress zstd \
  --encrypt /etc/pve/priv/pbs-encryption.key
Потеря ключа = потеря всех зашифрованных бэкапов. Навсегда. Ключ храни отдельно от сервера с бэкапами. Минимум две копии: одна в сейфе (paperkey), одна в защищённом менеджере паролей или Vault.

13. Мониторинг PBS через Zabbix

Бэкапы без мониторинга — это шрёдингеровский бэкап: есть и нет одновременно. Узнаешь правду только когда нужно восстанавливаться.

Создаём API-токен для мониторинга (только чтение)


# Создаём пользователя
proxmox-backup-manager user create zabbix@pbs \
  --password "ZabbixReadOnly!" \
  --comment "Zabbix мониторинг"

# Генерируем токен
proxmox-backup-manager user generate-token zabbix@pbs monitoring
# Сохрани токен!

# Только аудит - никаких записей и удалений
proxmox-backup-manager acl update / \
  --auth-id "zabbix@pbs!monitoring" \
  --role Audit

Скрипт для Zabbix External Check


#!/bin/bash
# /usr/lib/zabbix/externalscripts/pbs_check.sh
# Использование: ./pbs_check.sh <IP> <TOKEN_ID> <TOKEN_VALUE> <CHECK>

PBS_HOST="$1"
TOKEN_ID="$2"
TOKEN_VALUE="$3"
CHECK="$4"

URL="https://${PBS_HOST}:8007/api2/json"
AUTH="PBSAPIToken=${TOKEN_ID}:${TOKEN_VALUE}"

api() { curl -sk -H "Authorization: ${AUTH}" "${URL}/$1"; }

case "$CHECK" in
  node.uptime)
    api "nodes/localhost/status" | python3 -c \
      "import sys,json; print(json.load(sys.stdin)['data'].get('uptime',0))"
    ;;
  datastore.used.pct)
    api "admin/datastore/main/status" | python3 -c \
      "import sys,json
d=json.load(sys.stdin)['data']
print(round((1 - d.get('avail',0)/max(d.get('total',1),1))*100, 2))"
    ;;
  datastore.avail.gb)
    api "admin/datastore/main/status" | python3 -c \
      "import sys,json
d=json.load(sys.stdin)['data']
print(round(d.get('avail',0)/1073741824, 2))"
    ;;
  backup.errors)
    # 0 = OK, 1 = есть ошибки
    api "nodes/localhost/tasks?typefilter=backup&limit=20" | python3 -c \
      "import sys,json
tasks=json.load(sys.stdin)['data']
failed=[t for t in tasks if t.get('status') and t['status'] not in ('OK','running','')]
print(1 if failed else 0)"
    ;;
  backup.last.age)
    # Сколько секунд прошло с последнего успешного бэкапа
    api "nodes/localhost/tasks?typefilter=backup&limit=50" | python3 -c \
      "import sys,json,time
tasks=json.load(sys.stdin)['data']
ok=[t for t in tasks if t.get('status')=='OK']
if ok:
    last=max(t['starttime'] for t in ok)
    print(int(time.time())-last)
else:
    print(999999)"
    ;;
  *)
    echo "Unknown: $CHECK"; exit 1 ;;
esac

chmod +x /usr/lib/zabbix/externalscripts/pbs_check.sh

# Тест:
./pbs_check.sh 192.168.1.50 "zabbix@pbs!monitoring" "ТОКЕН" "datastore.used.pct"
# Ожидаем: число 0–100
./pbs_check.sh 192.168.1.50 "zabbix@pbs!monitoring" "ТОКЕН" "backup.errors"
# Ожидаем: 0 (нет ошибок) или 1

Триггеры Zabbix

Метрика Триггер Severity
datastore.used.pct > 80% Warning
datastore.used.pct > 92% High
datastore.avail.gb < 50 GB High
backup.errors = 1 High
backup.last.age > 90000 (25 ч) Average
node.uptime = 0 (недоступен) Disaster

Ежедневный email-отчёт о состоянии бэкапов


#!/bin/bash
# /opt/scripts/pbs-daily-report.sh
# cron: 0 7 * * * root /opt/scripts/pbs-daily-report.sh

PBS_HOST="IP_PBS"
TOKEN_ID="zabbix@pbs!monitoring"
TOKEN_VALUE="ТОКЕН"
MAIL_TO="admin@example.com"
URL="https://${PBS_HOST}:8007/api2/json"
AUTH="Authorization: PBSAPIToken=${TOKEN_ID}:${TOKEN_VALUE}"

# Статус хранилища
DS=$(curl -sk -H "$AUTH" "${URL}/admin/datastore/main/status")
TOTAL=$(echo "$DS" | python3 -c "import sys,json; d=json.load(sys.stdin)['data']; print(round(d['total']/1073741824,1))")
USED=$(echo "$DS" | python3 -c "import sys,json; d=json.load(sys.stdin)['data']; print(round(d['used']/1073741824,1))")
AVAIL=$(echo "$DS" | python3 -c "import sys,json; d=json.load(sys.stdin)['data']; print(round(d['avail']/1073741824,1))")
PCT=$(echo "$DS" | python3 -c "import sys,json; d=json.load(sys.stdin)['data']; print(round(d['used']/max(d['total'],1)*100,1))")

# Ошибки за последние задачи
TASKS=$(curl -sk -H "$AUTH" "${URL}/nodes/localhost/tasks?typefilter=backup&limit=50")
FAILED=$(echo "$TASKS" | python3 -c "
import sys,json
tasks=json.load(sys.stdin)['data']
bad=[t for t in tasks if t.get('status') and t['status'] not in ('OK','running','')]
for t in bad:
    print(f\"  FAIL: vm/{t.get('id','?')} | {t.get('starttime','?')} | {t.get('status','?')}\")
")

STATUS="OK"
[ -n "$FAILED" ] && STATUS="ERRORS DETECTED"

REPORT="PBS Daily Report | $(date '+%Y-%m-%d') | ${STATUS}

=== Хранилище main ===
Всего:     ${TOTAL} GB
Занято:    ${USED} GB (${PCT}%)
Свободно:  ${AVAIL} GB

=== Ошибки бэкапов ===
${FAILED:-Ошибок нет.}

PBS: https://${PBS_HOST}:8007
"

SUBJECT="PBS Report $(date '+%Y-%m-%d')"
[ -n "$FAILED" ] && SUBJECT="⚠️ PBS ERRORS $(date '+%Y-%m-%d')"

echo "$REPORT" | mail -s "$SUBJECT" "$MAIL_TO"

chmod +x /opt/scripts/pbs-daily-report.sh
echo "0 7 * * * root /opt/scripts/pbs-daily-report.sh" \
  >> /etc/cron.d/pbs-report

14. Troubleshooting: диагностика проблем PBS

Чеклист отладки — запускай по порядку


# 1. Статус сервисов PBS
systemctl status proxmox-backup proxmox-backup-proxy

# 2. Свободное место на PBS
df -h /mnt/backup-store
proxmox-backup-manager datastore list

# 3. Проверка соединения PVE → PBS (с PVE-хоста)
curl -sk \
  -H "Authorization: PBSAPIToken=pve-backup@pbs!pve-token:ТОКЕН" \
  https://IP_PBS:8007/api2/json/version

# 4. Логи задач бэкапа на PVE
journalctl -u pvedaemon --since "1 hour ago" | grep -i backup

# 5. Список задач на PBS (последние 20)
proxmox-backup-manager task list --limit 20

# 6. Лог конкретной задачи на PVE
pvesh get /nodes/$(hostname)/tasks/UPID:$(hostname):XXXXX:backup:/log

# 7. Проверка целостности datastore
proxmox-backup-manager verify start main
proxmox-backup-manager task list --limit 5 | grep verify

Таблица типичных ошибок

Симптом Причина Решение
authentication failed - invalid credentials Неверный токен или realm. Указан @pam вместо @pbs Пересоздай токен на PBS. Проверь: realm должен быть @pbs. Обнови в Storage settings PVE
SSL: unable to get local issuer certificate Fingerprint не указан или устарел (после обновления сертификата PBS) Получи актуальный fingerprint: proxmox-backup-manager cert info. Обнови в PVE Storage config
Бэкап завис, прогресс не движется часами Первый бэкап большой VM (это нормально). Или медленный диск / сеть Проверь I/O: iostat -x 2 5. Проверь сеть: iperf3 -s на PBS, iperf3 -c IP_PBS на PVE
unable to create backup lock Предыдущий бэкап не завершился, lock-файл завис rm /var/run/vzdump.lock. Убедись что нет живых vzdump-процессов: pgrep vzdump
Место на PBS не освобождается после prune Prune удалил ссылки, но GC не запускался — чанки физически не удалены proxmox-backup-manager garbage-collection start main. Дождись завершения — это может занять час
connection refused при подключении к PBS Сервис PBS не запущен, firewall, неверный IP systemctl status proxmox-backup-proxy. Проверь порт: ss -tlnp | grep 8007
Windows VM бэкапируется очень долго VSS создаёт снапшот медленно. Или агент не установлен, используется suspend Установи PBS Agent. Проверь состояние VSS: vssadmin list writers в cmd на Windows VM
datastore is full, новые бэкапы не пишутся Retention не настроен или GC давно не запускался Запусти prune + GC вручную. Настрой retention policy и расписание GC
Restore завершается с verify failed Повреждение чанков на PBS — возможна ошибка диска proxmox-backup-manager verify start main. Проверь SMART: smartctl -a /dev/sdX
PBS не принимает PVE после обновления Несовместимость версий клиента и сервера PBS 3.x работает с PVE 8.x. Обнови PBS и PVE до одной мажорной версии

15. Профилактика: автоматизация и best practices

Скрипт тест-восстановления раз в месяц


#!/bin/bash
# /opt/scripts/test-restore.sh
# Запускай вручную раз в квартал или из cron раз в месяц

VMID_SOURCE=101       # VM, которую тестируем
VMID_TEST=9101        # Временный VMID (должен быть свободен)
STORAGE="pbs-main"
STORAGE_DISK="local-lvm"
MAIL_TO="admin@example.com"

echo "$(date): Тест-восстановление VM ${VMID_SOURCE} → ${VMID_TEST}"

# Находим последний бэкап
LAST=$(pvesh get /nodes/$(hostname)/storage/${STORAGE}/content \
  --content backup 2>/dev/null \
  | grep "vmid.*${VMID_SOURCE}" \
  | sort -t'/' -k5 -r \
  | head -1 \
  | awk '{print $1}')

if [ -z "$LAST" ]; then
  echo "ОШИБКА: бэкап VM ${VMID_SOURCE} не найден!"
  echo "Restore test FAILED: no backup found for VM ${VMID_SOURCE}" \
    | mail -s "PBS Restore Test FAILED" "$MAIL_TO"
  exit 1
fi

echo "Восстанавливаем: ${LAST}"

qmrestore "${STORAGE}:${LAST}" "$VMID_TEST" \
  --storage "$STORAGE_DISK" \
  --force 1

RC=$?
if [ $RC -eq 0 ]; then
  echo "$(date): Восстановление УСПЕШНО. VM ${VMID_TEST} создана."
  echo "Restore test OK. VM ${VMID_TEST} ready. Delete when verified: qm destroy ${VMID_TEST}" \
    | mail -s "PBS Restore Test OK $(date +%Y-%m-%d)" "$MAIL_TO"
  echo "Удали тестовую VM вручную после проверки: qm destroy ${VMID_TEST}"
else
  echo "$(date): ОШИБКА восстановления!"
  echo "Restore test FAILED with code $RC" \
    | mail -s "PBS Restore Test FAILED" "$MAIL_TO"
  exit 1
fi

chmod +x /opt/scripts/test-restore.sh
# Раз в первое воскресенье месяца в 05:00
echo "0 5 1-7 * 0 root /opt/scripts/test-restore.sh" \
  >> /etc/cron.d/pbs-restore-test

Чеклист production-ready PBS

Пункт Статус Команда проверки
PBS на отдельном железе или VM с disk passthrough Физически проверь
Datastore на отдельном диске (не системном) df -h
Retention policy настроена proxmox-backup-manager datastore list
GC и Prune по расписанию proxmox-backup-manager datastore info main
API-токен вместо пароля root для PVE proxmox-backup-manager user list
Уведомления об ошибках бэкапа настроены Backup job → Email
Мониторинг в Zabbix (диск, ошибки, uptime) ./pbs_check.sh ... backup.errors
Восстановление проверено хотя бы раз qmrestore ...
Ключ шифрования (если используется) в двух копиях Сейф + менеджер паролей
Offsite-копия (S3 или второй PBS) rclone lsd s3backup:

16. FAQ по Proxmox Backup Server

Почему backup не создаётся, хотя job настроен?

Три причины: (1) ошибка подключения к PBS — проверь pvesm status; (2) нет места на datastore — df -h /mnt/backup-store; (3) lock-файл завис — ls /var/run/vzdump.lock. Логи задачи: Datacenter → Tasks → выбери упавший job → Log.

Почему место на PBS не освобождается после удаления бэкапов?

Prune удаляет ссылки на снапшоты, но физически чанки остаются на диске до запуска Garbage Collection. Запусти GC вручную: proxmox-backup-manager garbage-collection start main. GC может работать час и более — это нормально.

Можно ли запустить PBS как VM внутри того же PVE?

Можно, но только правильно: дай PBS отдельный физический диск через passthrough (qm set VMID --scsi1 /dev/sdb). Иначе PBS и VM живут на одном диске — при его отказе теряешь всё. Смысл PBS в изоляции.

Сколько памяти нужно PBS при большом количестве бэкапов?

Правило: примерно 1 GB RAM на каждые 1 TB datastore. При нехватке PBS уходит в swap — производительность падает катастрофически. Для 4 TB хранилища нужно минимум 4–6 GB RAM на PBS-сервере.

Как ускорить первый бэкап большой VM?

Три варианта: (1) увеличь пропускную способность сети — 10 Gbit вместо 1 Gbit; (2) используй --bwlimit 0 в vzdump чтобы снять ограничения; (3) запусти в нерабочее время и не прерывай — первый бэкап всегда самый долгий, дальше только инкременты.

Что такое verify и зачем запускать?

Verify проверяет целостность всех чанков в datastore — что данные не повреждены и восстановление возможно. Включи verify-new=true для автоматической проверки новых бэкапов: proxmox-backup-manager datastore update main --verify-new true. Еженедельный полный verify — через расписание в веб-интерфейсе PBS.

PBS умеет реплицировать бэкапы на второй PBS?

Да. PBS → PBS синхронизация через Sync Jobs. Настраивается в PBS веб-интерфейсе: Remote → Add (добавь второй PBS), затем Datastore → Sync Jobs → Add. Это правильный способ организовать offsite-копию без S3.

Как откатить VM на конкретную дату, а не на последний бэкап?

При restore в веб PVE или CLI выбираешь конкретный снапшот по дате. Формат: vm/101/2025-01-10T02:00:00Z. Список всех снапшотов: pvesh get /nodes/HOSTNAME/storage/pbs-main/content --content backup.

Итог: что теперь работает

Установлен PBS на отдельном железе, datastore с retention policy и расписанием GC, backup job для всех VM по расписанию, VSS-агент на Windows-машинах. Восстановление проверено — и полное, и file-level. Zabbix мониторит диск и ошибки, ежедневный отчёт приходит на почту. Offsite-копия уходит на S3.

Это называется «иметь бэкапы», а не «думать, что они есть». Разница обнаруживается в момент восстановления — и лучше пусть это будет плановый тест, а не аварийная ситуация.

💬 Что-то пошло не так?

Пиши в комментарии. Укажи: версию PBS (proxmox-backup-manager version), версию PVE (pveversion), вывод pvesm status и текст ошибки из логов задачи. Разберёмся.

Андрей Анатольевич
Author: Андрей Анатольевич

Руководитель ИТ / Кризис-менеджер 25 лет в IT: от инженера в МегаФоне до руководителя отдела. Знаю, как выглядит бардак: нестабильные сети, устаревшая инфраструктура, конфликты в команде, раздутые сроки. Помогаю бизнесу выходить из кризиса: навожу порядок в легаси, стабилизирую то, что разваливается, выстраиваю прогнозируемые процессы. Не раз возвращал к жизни ИТ-структуры — знаю цену хаосу. 📍 Ищу проект для полной реорганизации / стабилизации. 📬 Telegram: @over_dude ✉️ mail@it-apteka.com

Оставайтесь на связи

Рецепты от IT-боли. Без воды, без рекламы, без маркетинговой шелухи.

Подписаться на IT-Аптеку →

Мы ВКонтакте

IT-Аптека — советы, новости и помощь рядом.

Вступить в группу ВКонтакте →
Поделитесь:

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

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Прокрутить вверх