在进入本文主题之前,先来回答一个问题:为什么需要虚拟化?
这个问题简短版本的答案是:我买不起也放不下那么多物理机,也不敢把所有东西塞一个系统里。
而专业一点的答案是:虚拟化可以让多个服务共享硬件的同时,隔离每个服务的环境。如此一来,可以根据每个服务的实时需求动态分配硬件资源,而又保证了服务之间不会互相干扰。作为家庭服务器,内部的服务往往受限于峰值性能,而几乎不需要持续性能,简直是为虚拟化量身打造的靶场。
“既然这么多好处,那么代价是什么呢?”
“百分之几的性能损失,没别的了。……硬要说的话,配置需要花时间?”
“嘻,竟有此等好事,给我也整一个!”
Changelog
Update#1 At 2023.10.03
加入了PVE 7.4升级至8.0的流程。
准备工作
通常来说,我们提到的虚拟化实际上指代的是硬件加速的虚拟化。纯软件模拟虚拟化的性能可称之为惨烈,你一定不会想体验一下的。好在现代的硬件都具备了相应的硬件虚拟化技术,可以在保证虚拟机无法逃逸的同时将虚拟机的大部分操作直接交由硬件执行,仅需要付出切换上下文和模拟特殊指令的开销。
但是要启用这些技术需要在BIOS里面进行一些必要的配置。虽然博主使用的企业级主板默认启用了几乎全部需要的功能,但是为了保险还是需要确认一下相关选项。
给宿主机接好网线。如果你的主板并非有BMC模块的企业级主板的话,还需要给它准备好键鼠和显示器。开机进入BIOS,然后调整以下选项。
IOMMU / VT-d
IOMMU是一种地址映射技术,而VT-d是Intel对该技术的别称。博主采用AMD平台,因此需要寻找IOMMU选项。这里原本的默认值是Auto,为保险起见改为Enable。

Above 4G Decoding
本项关系到PCI-E设备RAM的64位寻址能力,通常用于需要让CPU访问全部显存的场景。博主因需要配置vGPU启用此项。

SR-IOV
SR-IOV允许一个PCI-E设备被多个虚拟机使用,常见于网卡等设备的共享。

安装系统
在此博主采用Ventoy引导。下载Proxmox VE的iso安装镜像,丢进装好Ventoy的U盘内。插上U盘,进入BIOS,选择Boot Override从U盘启动。


选中刚刚放进去的安装镜像,正常模式启动。如果你不使用Ventoy的话,可以使用Rufus等工具将iso烧录进U盘并从U盘启动,后续流程无差别。
耐心等待一会,就能见到了亲切的图形安装向导。选择安装Proxmox VE,等待安装程序就位,然后跟随前进。

同意EULA之后就可以看到安装目标盘选择。博主计划使用两块硬盘raid1作为宿主及虚拟机的系统盘,点击Options打开高级选项。

在弹出菜单上方切换文件系统,选择zfs(RAID1)。PVE默认把识别到的所有硬盘加入阵列,但是此阵列仅需要两块。

点击Deselect All,然后手动选择需要做RAID1的硬盘。此处的zfs高级选项一般来说默认即可,博主没有更改。点击OK确认。

可以看到,目标已经显示为RAID1了。点击下一步继续安装。

设置好国家、时区以及管理员账户。


接下来是网络设置。
PVE在安装时会通过DHCP获取IP,但是安装完成后仅支持静态地址。虽然可以通过命令行直接修改网卡配置来修改IP或是启用DHCP,但相对于图形化设置比较繁琐,还可能出现配置失败导致宿主机断网的情况。因此建议直接在此处为宿主机分配一个合适的静态IP。
如果你有多个网口,应当确认接口是否正确。一般来说如果你只有一个活动的接口,PVE会自动选择它。如果不知道如何填写主机名,可以使用.lan结尾的本地主机名。博主的方案是从自己的域名中划出一个子域名,在路由器劫持解析到宿主机的局域网IP。

/etc/network/interfaces /etc/hosts /etc/resolv.conf安装前的最后确认,请重点确认安装的目标磁盘内没有需要保留的数据。

点击Install后,安装程序就会自动启动,静待安装进度条跑完。安装结束后系统会自动重启,重启后应当可以看到如下界面。如果你又看到了U盘引导界面,那么拔掉U盘,重启再试一次。
请记住你的PVE显示的地址,包括协议https和端口号8006。这是今后和它打交道的主要途径。

至此安装已经告一段落了。暂时放下插在宿主机上的键鼠,接下来通过网络来远程配置PVE。
第一次启动
本节配置主要使用网页管理界面和SSH进行。
用浏览器打开https://<PVE_IP>:8006/,也就是上一节末尾记住的那个地址。浏览器可能会提示连接不安全,这个问题我们以后再解决。点击语言下拉框,切换成简体中文。用户名是root,密码是安装过程设置的密码。这样我们就进入了Proxmox VE的Web控制台。
用任意SSH工具连接到root@<PVE_IP>,密码是安装设置的密码。使用网页上本节点的Web Shell也可以,但仍然建议使用专用的软件。这里博主使用Windows Terminal+OpenSSH连接。
有了这两把刷子,就可以开始配置崭新的PVE系统了。
去除订阅弹窗
还记得这个一登录就拍在脸上的弹窗吗?我们第一个来收拾它。SSH执行如下命令:
sed -Ezi.bak "s/(Ext.Msg.show\(\{\s+title: gettext\('No valid sub)/orig_cmd\(\); void\(\{ \/\/\1/g" /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js
systemctl restart pveproxy.service
Shift+F5强制刷新管理界面,讨厌的弹窗应该已经消失了。
启用镜像源
这里采用USTC镜像源,并额外加入non-free仓库。
sed -i 's|^deb http://ftp.debian.org|deb https://mirrors.ustc.edu.cn|g' /etc/apt/sources.list
sed -i 's|^deb http://security.debian.org|deb https://mirrors.ustc.edu.cn/debian-security|g' /etc/apt/sources.list
sed -i 's|contrib$|contrib non-free|g' /etc/apt/sources.list
source /etc/os-release
echo "deb https://mirrors.ustc.edu.cn/proxmox/debian/pve $VERSION_CODENAME pve-no-subscription" > /etc/apt/sources.list.d/pve-no-subscription.list
rm /etc/apt/sources.list.d/pve-enterprise.list
apt update
如果希望修复本问题,可以将
https://mirrors.ustc.edu.cn/proxmox/debian/pve改为http://download.proxmox.com/debian/pve,存储库状态会从错误变恢复为警告。此外,如果需要下载CT Templates,建议执行以下命令更换CT源。更换CT源需要重启生效。
cp /usr/share/perl5/PVE/APLInfo.pm /usr/share/perl5/PVE/APLInfo.pm_back
sed -i 's|http://download.proxmox.com|https://mirrors.ustc.edu.cn/proxmox|g' /usr/share/perl5/PVE/APLInfo.pm
reboot now
HTTPS证书与端口
Proxmox VE强制HTTPS访问,但默认使用自签名的证书并监听8006端口。这让输地址需要多花几秒,并且使得浏览器认为连接不安全。为体现强迫症的自我修养,一定要找个办法解决一下。
端口部分可以通过iptables转发来解决。但是iptables的配置会在重启后丢失,需要添加一个脚本在每次启动后写入规则。
iptables -t nat -A PREROUTING -p tcp --dport 443 -j REDIRECT --to-ports 8006
iptables-save > /etc/iptables.up.rules
echo -e '#!/bin/sh\n/sbin/iptables-restore < /etc/iptables.up.rules' > /etc/network/if-pre-up.d/iptables
chmod +x /etc/network/if-pre-up.d/iptables
执行完毕后,我们就可以通过443,也就是默认的HTTPS端口访问了。每次开机后系统会自动恢复保存在/etc/iptables.up.rules的规则。
因为博主的PVE仅可在局域网内访问,因此需要使用DNS方式验证。Proxmox VE使用了来自acme.sh的dnsapi,支持海量的域名服务商,具体的列表可以参考官方wiki[1][2]。不像是某个姓Truenas的,只支持两个,约等于没法用。
左侧栏选择数据中心,打开ACME选项卡。首先来添加一个用于申请证书的账户,根据自己的信息填写,勾选接受条款,注册。

接下来配置DNS挑战需要的DNS API,也就是界面上的“质询插件”。首先请在官方wiki[1][2]查询自己使用的域名提供商教程,跟随对应教程获得API Key并记下来。
当你获得了API Key之后,就不需要按照wiki指引通过export添加环境变量了。回到PVE的ACME界面,在下方质询插件处添加一个新的插件。插件ID可以按喜好填写,DNS API选择自己的域名服务商。
对于部分服务商,界面已经逐个列出了需要配置的变量,逐项填入即可。而一些仅会给出一个“API数据”配置框,此时需要把相关参数一行一个以如图的格式填入。确认无误后点击添加。


左侧栏选择本节点,打开系统-凭证选项卡,在ACME部分点击添加创建一个新配置。质询类型选择DNS,插件选择刚才填入的插件ID,域名填写访问PVE使用的域名。

点击ACME部分“使用账户:无”后方的编辑按键,选择后应用。“立即预定凭证”的按钮应该已经亮起,点击它来启动第一次申请。因为要等待DNS记录传播,申请过程总共需要约一分钟。申请成功后PVE会自动启用新的证书。
刷新网页,双击页面下方任务记录的“预定凭证”任务,如果日志包含All domains validated!等内容且任务状态为OK则证书已经申请成功。如果此处任务失败可以参考日志进行除错。

使用域名访问PVE,此时浏览器应该会显示象征安全的小锁了。只要第一次申请成功,此后pve-daily-update.service会在有效期不足30天时自动申请新证书。
初试虚拟化
此时,Proxmox VE宿主机已经很好地运行起来了。如果虚拟机不需要任何特殊资源的话,不需要任何额外配置就可以运行。倘若要使用PCI-E直通等功能,则还需要对宿主机动动刀子。
在此将演示将一块HBA卡直通给虚拟化的Truenas所需要的额外配置。
配置宿主
为了直通PCI-E设备给虚拟机,需要对宿主系统的引导和模块做一些修改。
首先修改/etc/default/grub。用文本编辑器打开该文件,修改GRUB_CMDLINE_LINUX_DEFAULT一行为:
GRUB_CMDLINE_LINUX_DEFAULT="quiet amd_iommu=on iommu=pt"GRUB_CMDLINE_LINUX_DEFAULT="quiet intel_iommu=on iommu=pt"修改完后需要更新grub。
update-grub
然后加入vfio模块。
echo "vfio" > /etc/modules
echo "vfio_iommu_type1s" >> /etc/modules
echo "vfio_pci" >> /etc/modules
echo "vfio_virqfd" >> /etc/modules
update-initramfs -k all -u
创建虚拟机
首先需要准备好要想安装的系统安装镜像。点击左侧栏本节点下local存储,打开ISO镜像标签页。点击上传,从本地选择ISO上传到宿主机。
页面右上角点击创建虚拟机。操作系统选择刚刚上传的ISO镜像,机型选择Q35,BIOS选择OMVF。然后分配虚拟机可以使用的CPU、内存和磁盘。创建成功后先不要启动虚拟机,点击虚拟机的硬件配置页。添加-PCI设备,选中需要直通的设备。
点击控制台,启动虚拟机,接下来的安装流程与在裸金属机上安装相同系统一致。安装完成后从硬件配置页面分离安装盘,重启到刚刚安装完毕的系统。此时,应当可以在虚拟机内看到直通进去的PCI-E设备。
Proxmox VE升级
本部分是一次小版本升级(7.3 -> 7.4)的流程,参考官方手册。
前期准备
qm list
qm set 100 --onboot 0
... #对每一台开启自启的虚拟机重复
保险起见,关闭全部虚拟机的开机自启。(可选)
cat /etc/apt/sources.list
检查软件源设置。确认软件源配置包含debian 主仓库,升级仓库,安全更新仓库以及pve仓库。可以参考如下内容:
deb http://deb.debian.org/debian bullseye main contrib
deb http://deb.debian.org/debian bullseye-updates main contrib
# security updates
deb http://security.debian.org bullseye-security main contrib
deb http://download.proxmox.com/debian/pve bullseye pve-no-subscription
升级
apt update
apt dist-upgrade
reboot
升级并重启。因为更新了内核,下次启动时会出现如下内核选择界面。不需要操作,等待菜单超时自动选择即可。

pveversion -v
确认系统组件版本,并对照官方手册给出的对应版本参考值,核对是否有未升级成功的组件。
需要注意的是,更新后部分我们修改过的文件可能会被覆盖,导致订阅弹窗屏蔽失效等问题。因此建议更新后逐个检查曾经修改过的文件。
当确认更新成功后,就可以使用qm set 100 --onboot 1恢复虚拟机自启并手动启动所有虚拟机了。
清除旧版本内核(可选)
如果你细心比对了pveversion -v的输出,应该可以注意到我们的系统多出了一条类似于pve-kernel-5.15.85-1-pve: 5.15.85-1的条目。可以删除旧的内核来让开机加速几秒钟。
首先确认正在使用的内核,然后列出系统内安装的内核。
uname -a
dpkg --get-selections |grep kernel
应当能得到类似于这样的输出:
❯ uname -a
Linux Nijika 5.15.102-1-pve #1 SMP PVE 5.15.102-1 (2023-03-14T13:48Z) x86_64 GNU/Linux
❯ dpkg --get-selections |grep kernel
proxmox-kernel-helper install
pve-kernel-5.15 install
pve-kernel-5.15.102-1-pve install
pve-kernel-5.15.85-1-pve install
pve-kernel-helper deinstall
这代表我们正在使用5.15.102-1-pve,而pve-kernel-5.15.85-1-pve是多余的。如果不确定哪些是多余的,可以参考引导时的内核选择界面,一定不能误删。
在这里,我们以pve-kernel-5.15.85-1-pve为例子。首先自动清除不再需要的包,然后移除掉该内核。
apt autoremove -y
dpkg --purge --force-remove-essential pve-kernel-5.15.85-1-pve
内核卸载完成,下次启动时应当不会再看到内核选择页面了。
结语
如果说Homelab是一座综合体工厂,那么现在我们终于站在一块铺好水电管路的坚固地基上了。不得不感谢相关软硬件厂商在虚拟化技术上的努力。正是因为他们,博主才能用便宜的二手企业级硬件配上免费软件建起属于自己的赛博实验室。如果有细心观察文章配图的朋友,会发现大部分图像都来源于一个全新的PVE系统,而这个演示用的新系统就是博主从宿主开出的虚拟机。
然而本片文章中涉足的尚且是有直射阳光的浅海。作为缺失专业技术支持的业余用户,潜向技术海洋深处会是一段艰难的旅程。这部分内容将在vGPU篇详细讲解。
Update#1 更新PVE到8.0
作为本文的一次后续更新,本部分记录了从PVE 7.4升级到PVE 8.0的过程。
你应当至少具有一定Linux系统基础,了解升级的风险,并明白自己在做什么。
你已经被警告过了!
先决条件
根据先决条件部分内容,进行以下操作。读者应当自行阅读文档,确认是否有其他未满足的条件。
升级到7.4-latest
可以按照本文档从7.x升级到7.4 latest。本文中由7.4-3升级至7.4-16。
本部分细节参考上文7.3升级到7.4即可。
apt update
apt dist-upgrade
reboot now
升级vGPU
如果安装了低于16.0版本的vGPU,则需要更新vGPU版本。
6.2内核至少需要vGPU 16.0+。相关升级流程见此文章的Update#1更新。
预检查脚本
7.4 latest附带了名为pve7to8的检查脚本。
使用pve7to8 --full命令运行脚本,并检查其中所有有问题的项目。
例如,根据脚本,应当停止全部正在运行的虚拟机。
升级
更新APT存储库
需要更新的存储库包括Debian基础存储库、PVE存储库以及可能存在的Ceph存储库。以下命令可以将/etc/apt/sources.list中的版本全部替换。
sed -i 's/bullseye/bookworm/g' /etc/apt/sources.list
同时应当检查/etc/apt/sources.list.d/目录下的所有文件。ceph的存储库更新较为特殊,涉及到代号更改。
对于使用了镜像源的情况,最好从镜像源使用帮助处复制新的bookworm镜像源,覆盖原本的配置。最终配置如下:
❯ cat /etc/apt/sources.list
deb https://mirrors.tuna.tsinghua.edu.cn/debian/ bookworm main contrib non-free non-free-firmware
deb https://mirrors.tuna.tsinghua.edu.cn/debian/ bookworm-updates main contrib non-free non-free-firmware
deb https://mirrors.tuna.tsinghua.edu.cn/debian/ bookworm-backports main contrib non-free non-free-firmware
deb https://mirrors.tuna.tsinghua.edu.cn/debian-security bookworm-security main contrib non-free non-free-firmware
deb http://mirrors.ustc.edu.cn/proxmox/debian/pve bookworm pve-no-subscription
❯ cat /etc/apt/sources.list.d/ceph.list
deb https://mirrors.ustc.edu.cn/proxmox/debian/ceph-quincy bookworm no-subscription
更改完成后打开PVE Web管理界面,查看节点下存储库配置。“套件”处应当不再包含任何bullseye字样。如下图:

更新软件包
确认没有遗漏后,通过以下命令刷新apt源。确保刷新过程没有任何报错。
apt update
启动升级。注意,在apt dist-upgrade后将无法返回现有状态,请谨慎操作。
apt dist-upgrade
安装过程中会弹出一系列配置窗口。读者应按自己的情况配置。记录个人选择如下:
- 键盘布局选择默认的English(US)
/etc/issue的更改选N- 询问是否不询问便重启服务,选择是
chrony.conf的更改选择查看diff,实际diff为一行注释以及ntp配置,选择保留现有。/etc/ssh/sshd_config的更改查看diff,符合文档描述,选择使用包维护者版本。/etc/lvm/lvm.conf的更改,根据文档,我并未更改过此文件,选择使用包维护者版本。/etc/default/grub的更改选择查看diff,仅包括注释更改,选择使用包维护者版本。pve-enterprise.list的更改。果断选择N。
如果出现了其他的配置窗口,请读者根据具体情况抉择。
确保升级进程无错误地退出。
检查
使用pve7to8 --full命令运行检查脚本。
博主的情况中共出现4个警告。其中两个因为尚未重启,一个因为安装了vGPU。
最后一个警告是因为使用了zfs文件系统但缺少了systemd-boot,apt install systemd-boot即可解决。
确认无误后重启PVE宿主。再运行一次检查脚本,发现需要重启的警告消失了。
恢复配置
去除订阅弹窗
sed -Ezi.bak "s/(Ext.Msg.show\(\{\s+title: gettext\('No valid sub)/orig_cmd\(\); void\(\{ \/\/\1/g" /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js
systemctl restart pveproxy.service
更改后Shift+F5强制刷新Web管理界面。
CT模板配置镜像源
sed -i.bak 's|http://download.proxmox.com|https://mirrors.ustc.edu.cn/proxmox|g' /usr/share/perl5/PVE/APLInfo.pm
更改后重启生效。
收尾
列出现有的内核
❯ dpkg --get-selections |grep kernel
proxmox-default-kernel install
proxmox-kernel-6.2 install
proxmox-kernel-6.2.16-14-pve install
proxmox-kernel-helper install
pve-kernel-5.15 install
pve-kernel-5.15.102-1-pve deinstall
pve-kernel-5.15.116-1-pve install
pve-kernel-helper deinstall
清理不需要的软件包以及旧内核
apt autoremove -y
dpkg --purge --force-remove-essential pve-kernel-5.15 pve-kernel-5.15.102-1-pve pve-kernel-5.15.116-1-pve
