PBS — это: отдельный сервер бэкапов от команды Proxmox. Устанавливается с ISO или поверх Debian 12. Подключается к PVE как storage. Делает инкрементальные дедуплицированные бэкапы. Восстанавливает VM за минуты.
Минимальный путь: установи PBS → создай datastore → подключи к PVE → создай backup job → проверь restore. Без последнего шага бэкапов у тебя нет.
Время: 40–60 минут на чистой установке. Требования: 2 ядра, 2 GB RAM (лучше 4+), отдельный диск под хранилище, Debian 12 под капотом.
1. Диагноз: бэкап на том же диске — это не бэкап
У тебя Proxmox VE с десятком виртуалок. Бэкапы «настроены». По факту — папка /var/lib/vz/dump/ на том же диске, куда пишутся VM. Или снапшот раз в неделю на том же хосте.
Диск умрёт — прощай и VM, и бэкап одновременно. RAID не поможет: он защищает от отказа железа, но не от rm -rf, крипто-локера или пожара в стойке.
Второй сценарий хуже: бэкапы есть, но восстановление никто не проверял с момента настройки. Это означает — бэкапов нет. Есть большие файлы непонятного содержания.
Почему обычный 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 с одинаковой базой ОС — общие блоки дисков хранятся единожды
Варианты развёртывания 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) | ||
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.
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
# Расписание 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
- Datacenter → Storage → Add → Proxmox Backup Server
- Заполняй:
- ID:
pbs-main - Server: IP или hostname PBS
- Username:
pve-backup@pbs!pve-token - Password: значение токена
- Datastore:
main - Fingerprint: скопируй с PBS выше
- ID:
Через 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
- Datacenter → Backup → Add
- Настройки:
- Storage:
pbs-main - Schedule:
02:00(каждый день в 2 ночи) - Selection: All — все VM и CT
- Mode: Snapshot
- Compression: zstd
- Send email to: твой email
- Storage:
Через 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
- Скачай MSI-установщик: сайт Proxmox → Downloads → Proxmox Backup Client → Windows
- Запусти с правами администратора
- После установки служба 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
10. Восстановление VM из PBS: полное, частичное, тест
Полное восстановление VM через веб PVE
- PVE → Storage → pbs-main → Content
- Выбери нужный бэкап по дате и VMID
- Нажми Restore
- Укажи: целевую ноду, storage для диска, VMID (новый или тот же если исходная VM удалена)
- 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
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 и текст ошибки из логов задачи. Разберёмся.
Оставайтесь на связи
Рецепты от IT-боли. Без воды, без рекламы, без маркетинговой шелухи.
Подписаться на IT-Аптеку →


