Menci's Blog
念念不忘,必有回响
使用 Proxmox Backup Server 备份 Proxmox VE 的客户机与宿主机
  1. 1. 安装
  2. 2. 配置
    1. 2.1. 数据存储
      1. 2.1.1. 命名空间
    2. 2.2. 用户与权限
  3. 3. 备份
    1. 3.1. 添加存储
    2. 3.2. 设置备份任务
    3. 3.3. 备份 Proxmox VE 宿主机(或任意物理机)
  4. 4. 远程同步
  5. 5. 已知问题
    1. 5.1. 备份所有权错误
    2. 5.2. 虚拟机 I/O 未响应

Proxmox VE 是一款功能强大且易于使用的虚拟化平台。在不依赖其它服务的情况下,Proxmox VE 即可设置灵活的备份策略,将客户机按时备份储存到指定的存储中。但 Proxmox VE 的一般备份方式不支持增量备份,也不支持备份宿主机本身。

本篇文章将介绍 Proxmox Backup Server 的安装与使用,它为 Proxmox VE 提供了增量备份、远程同步等高级功能。

安装

由于 Proxmox Backup Server 一般与 Proxmox VE 配合使用,我们将 Proxmox Backup Server 作为虚拟机安装在 Proxmox VE 环境中,官方提供的安装方式是使用 ISO 镜像安装,适用于 KVM 虚拟机,跟随图形界面安装程序安装即可。不建议将 Proxmox Backup Server 安装在单独的物理机器上,一方面,Proxmox Backup Server 对 CPU 与内存的占用并不大,使用单独的物理机会造成浪费;另一方面,即使在同一内网中,网络可能会成为备份数据传输的瓶颈。较为轻量化的安装方式是使用 LXC 容器。

截止本文发布之时,Proxmox Backup Server 的最新版本为 2.2,基于 Debian 11。

首先创建一个 Debian 11 的 LXC 容器(不需要 Privileged),并为其设置 root 密码(Proxmox Backup Server 需要在 Web 管理界面上使用 root 密码登录)。登录到容器内,为其设置时区(定时任务会根据当前时区运行):

rm /etc/localtime
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

在 Debian 源的基础上,添加 Proxmox Backup Server 的软件源:

nano /etc/apt/sources.list.d/pbs-enterprise.list

任选一个镜像源即可:

deb http://mirrors.ustc.edu.cn/proxmox/debian/pbs bullseye pbs-no-subscription
deb http://mirrors.tuna.tsinghua.edu.cn/proxmox/pbs bullseye pbs-no-subscription
deb http://mirrors.xtom.hk/proxmox/debian/pbs bullseye pbs-no-subscription

之后添加 Proxmox 的 GPG Key,并使用 APT 安装 proxmox-backup-server 包:

wget https://enterprise.proxmox.com/debian/proxmox-release-bullseye.gpg -O /etc/apt/trusted.gpg.d/proxmox-release-bullseye.gpg
apt update && apt install proxmox-backup-server

如果 ifupdown2 包配置出错,可以忽略并重启后使用 apt -f install 修复。

安装结束后,登录 https://IP:8007(注意,与 Proxmox VE 的 8006 端口不同,Proxmox Backup Server 使用 8007 端口),使用创建 LXC 容器时的 root 密码登录,即可进入 Proxmox Backup Server 的管理界面。

注意,ISO 镜像中的图形化安装程序会设置管理员邮箱,但手动安装时不会询问。如果需要邮件通知,请在安装之后需要手动再管理界面中设置管理员邮箱(左侧菜单中选择「Configuraion → Access Control」,双击右侧的 root 用户):

编辑管理员用户

为 Proxmox Backup Server 设置管理员邮箱

最后可以手动禁用 systemd 中不需要的 failed 服务:

systemctl disable zfs-mount.service zfs-share.service zfs-zed.service systemd-modules-load.service

配置

数据存储

在 Proxmox Backup Server 中,备份被存储在数据存储(Datastore)中,每个数据存储对应文件系统上的一个文件夹。备份文件被以 Proxmox Backup Server 的自有格式组织在文件系统上,数据以分块的形式存储,对文件系统的性能要求(相对于直接存储压缩文档)较高,所以不建议使用远程存储(CIFS / NFS)作为数据存储,推荐使用本地硬盘。如果需要在 NAS 上储存备份数据,建议在 NAS 上安装 Proxmox Backup Server 虚拟机。

将需要存储数据的硬盘分区挂载到任意目录下(如 /mnt/data)。如果在 Proxmox VE 管理界面为 Proxmox Backup Server 客户机分配备份存储空间,请注意不要勾选备份(Backup)选项。如果需要在 LXC 容器中挂载远程 NFS 共享作为数据存储目录,请在宿主机中为其开启 NFS 支持。对于 KVM,可以将备份硬盘直通给虚拟机进行使用;对于 LXC,可以将备份硬盘挂载到宿主机上,并映射给 LXC 容器:

pct set 111 -mp0 /mnt/hdd,mp=/mnt/data # 将宿主机的 /mnt/hdd 映射到 LXC 容器 111 的客户机 /mnt/data 路径中

对于 Unprivileged 容器,会遇到容器中无法写入的问题,这是由于 LXC 将容器内的 UID/GID 映射到了宿主机上的其他 UID/GID。可以在宿主机上检查容器内 root 用户/用户组所对应的 UID/GID:

stat -c "%u %g" /proc/$(pgrep -f proxmox-backup-api)
100000 100000

将宿主机上的数据目录的属主/属组改为上述命令输出的 UID/GID 即可:

chown 100000:100000 /mnt/hdd

确保 Proxmox Backup Server 可以正确写入存储目录后,在管理界面上创建数据存储(左侧菜单中选择「Datastore → Add Datastore」):

添加 Datastore

添加 Datastore

右侧的 GC Schedule 和 Prune Schedule 分别表示进行垃圾回收与删除多余备份的定时任务时间,默认的 daily 表示每天 00:00。删除备份时的保留策略在第二个选项卡「Prune Options」中设置:

设置 Datastore 的保留策略

设置 Datastore 的保留策略

如图所示,表示保留互相间隔一天的 7 个备份,互相间隔一周的 8 个备份,互相间隔一个月的 6 个备份。这些选项也可以在 Proxmox VE 的备份任务中设置,但更推荐在 Proxmox Backup Server 中设置。

点击「Add」提交后,系统将开始创建数据存储,由于需要对文件系统上的目录结构进行一些初始化,在 HDD 或远程存储上可能需要较长的时间。

命名空间

每个数据存储中可以包含多个命名空间,命名空间并不隔离访问权限与存储设备,仅隔离备份名称。每一组备份以 VM/CT 的 ID 或者宿主机的主机名来命名,在不同命名空间中放置来自不同 Proxmox VE 服务器的数据,可以确保名称不会冲突。

在 Datastore 的管理界面选择「Content」选项卡,并在下方列表的右上方点击「Add NS」按钮,即可创建命名空间。

用户与权限

除仅用于登录管理界面的 root 用户使用 PAM 认证外,其他管理员用户或备份客户端均使用 Proxmox Backup Server 自带的用户管理系统进行认证。在左侧菜单中选择「Configuration → Access Control」,并点击右侧的「Add」按钮,输入用户名与密码:

添加用户

添加用户

如果该用户是另一位管理员用户,则可以输入其邮箱地址,之后可以将邮件通知设为发往其邮箱。如果是备份客户端用户,则不需要填写邮箱。

然后在「Permissions」选项卡中,点击「Add → User Permission」,为刚刚创建的用户添加权限:

为用户授予权限

为用户授予权限

如果该用户是另一位管理员用户,可以选择为其授予根路径的管理员权限。如果用于 Proxmox VE 服务器上的备份客户端,并且希望在 Proxmox VE 上管理备份,可以选择在特定数据存储下的 DatastoreAdmin 权限。

备份

添加存储

首先需要在 Proxmox VE 中将 Proxmox Backup Server 添加为存储(Storage)。登录 Proxmox VE 管理界面,选择「Datacenter → Storage」,在「Add」按钮的菜单中选择「Proxmox Backup Server」:

在 Proxmox VE 中添加备份存储

在 Proxmox VE 中添加备份存储

在 Server 字段中填写 Proxmox Backup Server 的 IP 地址或域名。如果在特殊情况下,Proxmox Backup Server 位于 NAT 之后无法被主动连接,可以使用 Rathole 等内网穿透工具,这种时候可将 8007 端口转发到任意端口号,并在 Server 字段中填写 IP:PORT。对于 Username 字段,请注意在创建时输入的用户名后面加上 @pbs,表示是 Proxmox Backup Server 自己的账户系统(而非 PAM)。

建议对备份进行加密,在「Encryption」选项卡中选择第二项「Auto-generate a client encryption key」,自动生成客户端加密密钥。对备份进行加密可以确保服务器端无法访问备份数据的内容,特别是对于使用共享的 Proxmox Backup Server,或者为了冗余需要将备份同步到其他 Proxmox Backup Server 时。

为备份存储设置加密

为备份存储设置加密

点击「Add」按钮添加后,如果使用了默认的自签证书(未被 Proxmox VE 客户端所信任),会提示 SSL Fingerprint 不匹配,这时候复制错误文本中的 Fingerprint 文本,填写到「General」选项卡的对应字段中,即可添加成功。添加成功后,Proxmox VE 会提示你将自动生成的加密密钥保存。再次添加该存储并读取已有的备份时,需要选择「Upload an existing client encryption key」,将保存好的 Key 文件上传,即可解密之前的备份数据。

下载加密密钥

下载加密密钥

设置备份任务

在 Proxmox VE 管理面板中,选择「Datacenter → Backup → Add」,指定需要备份的客户机列表与备份时间,选择 Storage 为刚刚添加的 Proxmox Backup Server,即可创建备份任务。

创建备份任务后,可以在列表中选中任务点击「Run now」,测试备份任务是否可以正常工作。

备份 Proxmox VE 宿主机(或任意物理机)

截至本文发布之时,Proxmox Backup Server 还没有完整支持对 Proxmox VE 宿主机的备份,我们暂时无法在管理界面中配置宿主机备份。但是该功能已存在于当前的版本中,可以通过手动调用 proxmox-backup-client 来使用。参考官方文档,使用 --backup-type host 参数可以创建宿主机备份。

对于使用 LVM 安装的 Proxmox VE,我们可以编写一个脚本,首先对 Proxmox VE 的宿主机根分区创建一个 LVM 快照(宿主机的写入量不大,快照的大小只需要能满足备份期间宿主机写入量即可,所以快照不需要太大),然后调用 proxmox-backup-client 对快照块设备进行备份,最后删除快照:

#!/bin/bash
lvremove -y pve/root_snapshot || true
lvcreate -pr -L 5G --monitor y --snapshot --name root_snapshot pve/root

export PBS_PASSWORD_FILE=/etc/pve/priv/storage/menci-pbs-home.pw
proxmox-backup-client backup root.img:/dev/pve/root_snapshot --backup-type host --repository Menci-Home@[email protected]:HDD --ns Home --keyfile /etc/pve/priv/storage/menci-pbs-home.enc

lvremove -y pve/root_snapshot

上述命令中,--repository 表示备份目标存储,格式为 <username>@pbs@<host:port>:<datastore>,命名空间通过 --ns 参数指定。密码和加密密钥通过文件指定,对于在 Proxmox VE 管理面板添加过的存储,对应的文件即为 /etc/pve/priv/storage/ 目录下的 .pw.enc 文件。

该命令中的 root.img:/dev/pve/root_snapshot 部分可以指定多次,用于备份多个磁盘分区。前半部分为生成的备份中的文件名,后半部分为文件系统中的源文件(或目录)的路径。如果后半部分是一个路径,则前半部分需要是 .pxar 格式的文件名,表示将文件夹打包为 Proxmox Backup Server 的 Proxmox File Archive Format 格式,可以使用对应的命令行工具进行处理。

对于使用 ZFS 安装的 Proxmox VE,其根文件系统是一个 ZFS dataset(默认位于 /rpool/ROOT/pve-1),我们可以为其创建快照。ZFS 快照可以被挂载为一个只读目录,可以使用 .pxar 格式对快照目录进行备份即可:

ZFS 快照目录默认可能是隐藏的,需要先执行 zfs set snapdir=visible rpool/ROOT/pve-1 将其设为可见。

#!/bin/bash
zfs destroy rpool/ROOT/pve-1@backup || true
zfs snapshot rpool/ROOT/pve-1@backup

export PBS_PASSWORD_FILE=/etc/pve/priv/storage/menci-pbs-home.pw
proxmox-backup-client backup root.pxar:/.zfs/snapshot/backup --backup-type host --repository Menci-Home@[email protected]:HDD --ns Home --keyfile /etc/pve/priv/storage/menci-pbs-home.enc

zfs destroy rpool/ROOT/pve-1@backup

将编写好的备份脚本保存,例如保存到 /root/backup-host.sh。为其添加执行权限,并加入到 cron 中定时执行(注意添加 PATH 行,否则 cron 定时任务执行时的 PATH 不完整会导致执行失败):

PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
0 3 * * * /root/backup-host.sh

当需要进行恢复时,使用同样在命令行下使用 proxmox-backup-client 工具进行恢复:

proxmox-backup-client restore host/Menci-PVE root.img restored_root.img --repository Menci-Home@[email protected]:HDD --ns Home --keyfile /etc/pve/priv/storage/menci-pbs-home.enc

上述命令表示,从该备份存储中,恢复 host/Menci-PVE(格式为 host/<hostname>,可在 Web 管理界面中看到这些备份)中的 root.img 文件,下载到本地的 restored_root.img 文件中。

除备份 Proxmox VE 宿主机外,proxmox-backup-client 命令行工具也可以在其他任何 Linux 机器上运行,官方提供了该工具的 APT 源。理论上来说,任何支持快照的文件系统均可使用该工具进行备份。

远程同步

Proxmox Backup Server 支持在多个服务器之间将备份进行同步,具体的实现方式是,原本的备份数据存放在 A 服务器上,B 服务器定时连接 A 服务器拉取备份。注意这里只能由 B(需同步到的目标服务器)主动连接 A(存放原始备份的源服务器),如果 A 在 NAT 之后无法由 B 主动连接,可以使用上述添加存储时一样的解决方案,使用 Rathole 等内网穿透工具进行端口映射。

与进行备份时一样,进行同步时,B 服务器也需要使用用户和密码登录到 A 服务器。按照上述方法在 A 服务器上创建用户,仅需授予 DatastoreReader 权限。同步备份无需客户端密钥,因为 Proxmox VE 在备份客户端所进行的加密,对 Proxmox Backup Server 是透明的,同步时也无需解密。所以,如果之后要从 B 服务器上恢复备份,同样需要连接 A 服务器时的密钥。

在 B 服务器上选择左侧菜单中的「Configuration → Remotes」,点击右侧的「Add」按钮,添加 A 服务器(按照同样的方式填写 Fingerprint):

添加远程服务器

添加远程服务器

之后在 B 服务器上创建一个数据存储,并创建对应的命名空间(如果需要)。在创建好的数据存储中选择「Sync Jobs」选项卡,点击「Add」按钮:

添加拉取任务

添加拉取任务

指定从源 A 服务器的某个数据存储的某个命名空间,同步到当前 B 服务器的某个数据存储的某个命名空间,并填写计划时间。如果传输在公网上进行,建议设置带宽限制,以免影响双方(特别是上传方)的其他网络应用。可以勾选「Remove vanished」选项以自动删除在原服务器 A 上已删除的备份,或者在 B 服务器上为数据存储设置保留策略。

创建完成后可以点击「Run now」测试同步是否可以正常工作。

已知问题

备份所有权错误

类似 Linux 的文件系统权限管理,Proxmox Backup Server 会记录每个备份组是由哪个用户所创建的。例如,如果用户 A 连接到服务器创建了一个 vm/101(ID 为 101 的 KVM 虚拟机)的备份,则以用户 B 连接时,无法在同一命名空间创建再次创建名为 vm/101 的另一个备份。

即使删除掉已有的 vm/101 下的所有备份,所有权仍然不会消除。如果需要使用另一个用户创建同名的备份,请使用命令手动修改所有权。登录任意具有 DatastoreAdmin 权限的用户即可更改所有权。

proxmox-backup-client change-owner vm/101 New-User@pbs --repository Any-User@[email protected]:HDD --ns Home

在 Web 管理界面上可以看到每个备份组的所有者,但暂时无法进行修改。目前仅支持使用上述命令修改所有权。

虚拟机 I/O 未响应

Proxmox VE 传统的 vzdump 备份统一采用 LVM / ZFS 快照来捕捉客户机(KVM 虚拟机和 LXC 容器)的一致性的文件系统,不会影响客户机的运行。向 Proxmox Backup Server 备份时,Proxmox VE 对 LVM 采用同样的方式进行,并采用对两次快照进行对比的方式实现增量(对宿主机备份也是如此),但对于 KVM 虚拟机,他们使用了另一种由 QEMU 提供的一致性增量备份接口:Dirty Bitmaps

QEMU Dirty Bitmap 可以记录 KVM 虚拟机在虚拟磁盘设备的哪些位置进行了写入操作,并允许虚拟机管理程序仅将被修改的部分记录到备份中。在创建备份时,QEMU 在内存中进行一个快照,向虚拟机管理程序提供一致性的 Bitmap 和虚拟磁盘数据。但由于缺少类似 LVM 的 Copy on Write 机制,为了保证虚拟机能够正常运行不被中断,QEMU 只能将备份期间虚拟机进行的磁盘写入操作暂时缓存在内存中,待备份结束后再写回存储设备。

这导致了一个问题,如果单个虚拟机备份耗时较长,同时在这个时间内虚拟机进行了较多的磁盘写入操作,则 QEMU 内部的快照缓冲区会被占满,此时 QEMU 只能将接下来的写入操作完全阻塞,导致虚拟机无响应,造成服务中断。而如果该虚拟机位于 Proxmox VE 到 Proxmox Backup Server 的网络出口上(例如,向公网上的服务器备份,途中作为路由器/防火墙的虚拟机被阻塞),则备份过程会被阻塞,最终因连接中断而备份失败。

有用户曾经提出过使用 LVM / ZFS 快照进行 KVM 备份的建议,但被官方驳回,官方更倾向于使用 QEMU 自带的增量备份机制。QEMU 在 7.0 中加入了名为 Fleecing 的机制,可以利用磁盘作为备份快照的写入缓冲,以解决内存中的缓冲区不足的问题,但 Proxmox VE 还没有跟进支持。

目前针对此问题的建议是,不要直接从 Proxmox VE 向异地的 Proxmox Backup Server 发送备份,而是先备份到本地的 Proxmox Backup Server 中,确保单个虚拟机的备份过程不会持续太久,之后再同步到远程服务器上。