试图给一台远程的非空的 Proxmox VE 主机改名,改完名重启。然而 Proxmox VE 的配置文件目录是跟主机名强绑定的,于是不出意料的炸了。现在是 web 页面访问不了,ssh 连不上去(提示密钥错误),非常崩溃。
这个问题修起来也不是很容易。Proxmox VE 已经不能正常启动了,得想办法用其他启动盘启动,然后挂载主机硬盘把主机名改回去。可惜机器在 1000 公里外的家里,没法自己去操作,也很难让家里人帮忙操作……
好消息是,家里另外一台机器我还能连上,挂掉的这台机器开启了 Intel AMT 主动管理功能。那么,如果我通过 AMT 连接到挂掉的这台机器上,让她以网络启动,那么是不是就能救活她了?
远程救援的理论基础
在开始实操救援之前,先让我们理一理救援的理想过程,看看都需要配置哪些服务、解决哪些问题。
- 使用 Intel AMT 将被救援主机重启到网络引导(PXE)模式
- PXE 程序发送 DHCP 请求,获得 IP 地址、下一步服务器地址
next-server
、引导程序文件名filename
- PXE 程序使用 TFTP 协议从
next-server
下载filename
指定的引导程序(iPXE),然后运行 iPXE - iPXE 通过 TFTP 协议从
next-server
下载autoexec.ipxe
脚本,根据脚本通过 HTTP 下载 Alpine 的 Linux 内核、initramfs,启动内核并传递指定的内核参数 - Alpine 根据内核参数配置 ssh 密钥、软件包仓库镜像地址,并下载并加载 modloop(打包好的额外的内核模块),最终完成初始化进入登录界面
- 通过 Intel AMT Serial over LAN 或者 SSH 连入 Alpine
- 安装 zfs 工具,导入 Proxmox VE 的启动池,挂载相关数据集,修改罪魁祸首
/etc/hosts
- 卸载数据集,导出池,关机,重启后 Proxmox VE 恢复正常。
使用 Intel AMT 连接到被救援服务器
之前部署这台服务器的时候,专门进 BIOS 里打开了 AMT 功能,现在想来真是有先见之明。这里简要介绍下 AMT 的启用流程:
- 在启动菜单中,选择进入 BIOS 设置(Computer Setup),找到 Advanced、Remote Management Options,确保 Active Management(AMT)被打开
- 在启动菜单中,选择进入 Intel Management Engine 设置
- 默认密码是 admin,登录后修改密码,要求必须是带有数字、字母、符号的强密码
- 启用需要的功能,应该不需要改太多
首先我们尝试用 AMT 连接到服务器。可以直接用浏览器访问服务器的 16992 端口外,还可以使用使用开源的 Intel AMT 客户端 MeshCommander。我们后续都使用后者。输入服务器 IP 和密码,顺利连上。
坏消息是,我的这台 HP 机器上没有 KVM(键盘、视频、鼠标)的选项,远程管理仅能用 Serial over LAN(SoL)远程串口功能。我在互联网上翻了一圈,大概是因为这台机器原装是 i3 处理器,不具备 Intel vPro 功能,于是 HP 直接在主板 BIOS 里干掉了 KVM 功能,后面再换 i5、i7 处理器也用不了 KVM 了。这个可以通过修改 BIOS 芯片数据来实现(参考1,参考2),只不过当时没时间搞了……
对 SoL 进行了一系列探索,发现 Reset to BIOS 时能够让 SoL 有正常输出,可惜是乱码。盲操修改了语言,这下能看到正常的启动菜单了。
启动菜单可以选择 Network (PXE) Boot,也可以在电源操作里选择 Reset to PXE 。
配置 dnsmasq(DHCP 和 TFTP)
我们已经能够用 AMT 让服务器从 PXE 引导,接下来配置 PXE 启动所需的 DHCP 和 TFTP 服务。在 PXE 启动中,DHCP 用于下发 next-server
、filename
等启动参数,TFTP 用于传输引导文件。
这里的 DHCP 就是那个自动分配 IP 地址的 DHCP,那么就有个问题:在家庭网络环境中,路由器往往仅提供了基础 DHCP 服务,无法扩展 PXE 所需的配置项;若禁用路由器的 DHCP 功能、部署独立的 DHCP 服务器,则可能有网络全面断联的风险。为解决这一问题,我们使用 Proxy DHCP 技术:当客户端发出 DHCP 请求时,原有 DHCP 服务器仍下发 IP 地址,Proxy DHCP 服务器补充下发 PXE 所需的附加参数,两者协同工作。现代 PXE 网卡应该都支持 Proxy DHCP。
我准备了一台全新的 Ubuntu 24.04 虚拟机用来提供网络启动所需的一切服务,使用 dnsmasq 来同时提供 DHCP 和 TFTP 服务。
|
|
配置 dnsmasq,以启用 proxy DHCP 和 TFTP。将下面的配置文件保存到 /etc/dnsmasq.d/pxe.conf
。
|
|
这里我只为 UEFI 做了配置(因为我的服务器就是 UEFI 启动的)。更多配置项可以仔细阅读 /etc/dnsmasq.conf
或者 dnsmasq 的 man 页面。
接下来创建 TFTP 根目录、让 dnsmasq 检查配置文件、重启 dnsmasq 服务。
|
|
然后就可以在虚拟机尝试进行 PXE 启动了!虚拟机的 BIOS/PXE 会抱怨找不到 ipxe.efi 文件(这个我们下一步去搞),但它已经知道了要去哪里找引导文件。也可以再去看看 dnsmasq 的日志,应该也能找到它类似的抱怨。
一定要先在虚拟机尝试 PXE 启动,确保所有组件部署完成、一切无误后再去救援实体机。
把虚拟机的磁盘、光盘设备都删光,它自然会去尝试 PXE 启动。
配置 iPXE
iPXE 是一个更高级的网络启动固件,能够直接通过 HTTP 协议下载引导文件,比 TFTP 要快许多。我们用 PXE 引导 iPXE,然后再让 iPXE 启动 Linux 内核。
除了 iPXE,还可以选择 pxelinux 来启动 Linux 内核,具体参考 Ubuntu 的网络启动指南。我选择 iPXE 单纯是我参考的博客选择了 iPXE,实际上 pxelinux 使用更广泛一点)
我们从源码构建 iPXE,并把编译好的 iPXE 放到 TFTP 根目录。
|
|
接下来就又可以在虚拟机尝试启动了!你应该能看到 iPXE 的输出,并且它在抱怨找不到任何可以启动的东西。
iPXE 会尝试从 TFTP 服务器获得 autoexec.ipxe,它抱怨的就是找不到这个文件。跟前面一样,这里也可以去看看 dnsmasq 的日志。稍后我们在配置 Alpine 时会去搞这个文件。
配置 HTTP 服务器
前面我们提到 iPXE 可以通过 HTTP 服务器来下载引导文件,实际上 Alpine Linux 启动过程中也需要从 HTTP 下载文件。我们需要部署一个 HTTP 服务器,这里选择最简单的 Apache2.
|
|
Ubuntu 的 Apache2 开箱即用,不需要什么配置。其默认根目录是 /var/www/html
,稍后我们就会把 Alpine Linux 的各种文件丢进去。现在,打开浏览器访问服务器地址,应该能看到它的默认页。
配置 Alpine Linux
Alpine Linux 是一个新兴的 Linux 发行版,主打轻小、简单、安全,挺适合当救援系统的。
选其他发行版来搞救援也行,比如 Ubuntu。这里选 Alpine 单纯是看到了相关的博客。
获取 Netboot 文件
Alpine Linux 本身就提供了 Netboot 的版本,从它的下载页下载,直接解压到 HTTP 服务器根目录里。
|
|
解压后应该能得到如下文件:
|
|
所有文件都有 lts
和 virt
结尾的两份,lts
是标准版,virt
是针对虚拟机裁剪的版本,我们后面总是使用前者。这些文件中,我们实际上只使用下面 3 个:
|
|
记得检查所有文件的权限,确保它们都能通过浏览器下载。
|
|
另外,往 HTTP 服务器根目录下丢一个公钥文件 ssh_key
,用于稍后 SSH 登录。
配置 iPXE 启动脚本
创建 autoexec.ipxe
文件,放在 TFTP 根目录 /var/ftpd
下。
|
|
对于 ZFS 的额外处理
我的 Proxmox VE 是装在两块 NVME 盘组的 zfs 阵列上的,我的救援系统就必须有 zfs 支持,包括 zfs 内核模块和 zfs 工具。然而,netboot 版的 Alpine Linux 并没有自带 zfs 内核模块,我在启动后尝试用 apk 安装会报莫名其妙的错误,救援一下子陷入了僵局。
机缘巧合下,我发现 Alpine Linux 的 Extended 版带有 zfs 模块,那么把 Extended 和 Netboot 整合一下是不是就可以了?我注意到:
- 两者的 lts 内核完全一致(通过比较 config 和 md5sum)
- 两者的 initramfs 各有千秋(通过
lsinitramfs
) - Extended 比 Netboot 的 modloop 多了一些模块,其中包括 zfs (通过
unsquashfs -l
)
那么可以试着用 Extended 的 modloop 替换掉 Netboot 的 modloop,具体如下:
- 下载 Extended 的 ISO,挂载到文件系统,找到
boot/modloop-lts
,替换掉原来的文件; - 在
autoexec.ipxe
作以下可选修改command
的modules
选项修改为modules=loop,squashfs,zfs
,以自动加载 zfs 内核模块kernel
命令中添加modloop_verify=no
,关闭 modloop 校验
这下 Alpine 就有 zfs 模块了。
启动!
现在,可以在虚拟机上做最后的测试了。经过漫长的启动后,如果没有意外,应该能看到这样的登录画面。用户名是 root,没有密码。
Alpine 默认开启了 ssh 服务器,可以用 ssh 连接,前面添加的 ssh 公钥此时派上用场了。
到此,一切就绪,可以尝试在物理服务器上进行 PXE 启动了。
救援 ZFS
通过 ssh 连接到被救援服务器,安装相关工具,挂载 zfs 文件系统,进行必要的修改。
|
|
用 Intel AMT 再次启动服务器,web、ssh 全部恢复正常,救援成功!
结语
这次远程救援花了好几天时间,最终省下了 1000 块钱的车票,总是值得的。
Intel AMT 还是好用的,不过我下次回家一定得把 KVM 功能恢复了,SoL 的可用性实在堪忧啊。另外,从 MeshCommander 的网站上看到,它的开发者在 2022 年的时候被 Intel 裁掉了,真是令人唏嘘。
希望这篇文章对你有所帮助~
参考
- 这两篇文章是我 PXE 启动 Alpine Linux 的主要参考,感谢 apalrd。
- 有关 Alpine Linux 网络启动的官方文档
- 有关 dnsmasq 的配置
- 有关 Alpine Linux + ZFS 的文章
- 有关 ZFS 操作的材料