TLDR:基于ipxe网络引导,使用iscsi作为存储的无盘系统教程。
目标
首先要弄清,PXE引导安装程序和PXE引导操作系统是两回事,可以单独使用前者,比如iventory,或者单独使用后者,比如netbootxyz,但是这两者功能上都有限制。也可以直接用ipxe,实现两者的功能。但是不管是哪个软件,原理都是一样的。
这次我想要通过pxe引导proxmox安装程序并且将proxmox安装到ceph提供的iscsi磁盘上,之后通过pxe引导iscsi磁盘启动运行,让计算节点省一块系统盘。实现真正的硬件通用化,换硬件不换操作系统,或者灵活更换主机的操作系统。
关于PXE,中文互联网的教程大都写得很模糊,更多都是发一个文件压缩包或者一个制作好的虚拟机模板告诉你怎么用,让我在探索的过程中走了不少弯路。都折腾这种小众功能了,怎么可以不知其所以然呢。
实现过程
用的是普通PC的主板,不需要支持bios挂载iscsi设备,只需要支持pxe启动。要是主板支持bios挂载iscsi磁盘,就简单得多了。
这篇文章不会提及具体的操作过程也不会提供现成的文件下载,只会分享实现原理和PXE/debian在PXE iscsi引导过程中踩过的坑。毕竟各自的软硬件环境都不同,但是理解了原理,实际上还是很简单的。
作者先生请出山这篇文章里的这张图把PXE启动流程解释得非常棒。
DHCP
第一步主机会向网络中的DHCP服务器发出请求,DHCP服务器除了下发ip地址、掩码、网关、dns信息外,还需要配置next server和option67的filename。看到有网友在cisco论坛讨论opeion66 tftp-server和next-server是不是一回事,看起来似乎是有些区别的,我用做dhcp服务器的fortigate系统中也把next server和tftp server区分成两个字段。
next-server字段告诉主机要去哪个server获取efi启动固件,file-name字段告诉主机启动固件文件名是哪个。
如果你的dhcp服务器不支持自定义字段的功能,可以选择dnsmasq、dhcpd、windows dhcp server或者任意支持的dhcp server软件。
网上的教程里配置dhcp服务器通过判断主机dhcp请求信息来区分bios还是uefi来动态返回filename字段,以及是否包含user-class来告知客户端ipxe主配置文件url。但是我的Fortigate里的dhcp服务不支持这部分功能,但是不用担心,这部分不是必须,filename我写死ipxe.efi,用UEFI启动。BIOS的话是undionly64.kpxe。告知客户端ipxe配置文件可以在编译ipxe.efi的时候指定EMBED参数来传递主配置文件url。
TFTP
第二步客户端会从dhcp响应的tftp server中加载ipxe固件,这里可以从源码自行编译,或者从官网下载编译好的文件。
但是如果要注入EMBED配置则必须自行编译。
编译需要这些依赖
gcc
binutils
make
perl
liblzma or xz header files
mtools
mkisofs or genisoimage or xorrisofs (needed only for building .iso images)
syslinux (for isolinux, needed only for building .iso images)
根据需要编译uefi/legacy的固件
# UEFI
make bin-x86_64-efi/ipxe.efi EMBED=chain.ipxe
# LEGACY
make bin/undionly.kpxe EMBED=chain.ipxe
可以将自定义的ipxe编译到固件中,这样就不需要dhcp服务器响应ipxe配置文件。
#!ipxe
dhcp
chain http://[webserver]/boot.ipxe
将编译好的ipxe固件放到tftp服务器。同样,tftp服务器可以选择任意tftp-server软件。
WEBSERVER
第三步第四步,客户端会去chain.ipxe提供的ipxe配置文件url加载执行在webserver上的boot.ipxe。同理这里可以使用任何你喜欢的webserver。 将boot.ipxe和之后会用到的系统镜像放到webserver。
引导proxmox安装程序
启动proxmox安装程序,使用filename [iso镜像]是无效的,这里用了morph027/pve-iso-2-pxe这个项目的脚本来提取linux26和initrd文件,放到webserver下。 这两个命令来启动proxmox安装程序的debug模式,为什么不是install模式?因为即便在boot.ipxe中使用sanhook挂载了iscsi磁盘,进到安装程序后iscsi磁盘会断开连接从而找不到用来安装proxmox的磁盘。
# boot.ipxe
initrd http://10.1.2.106/pxeboot/initrd
chain http://10.1.2.106/pxeboot/linux26 vga=791 video=vesafb:ywrap,mtrr ramdisk_size=26777216 rw quiet initrd=initrd splash=verbose proxdebug
参考proxmox论坛的这篇文章,进debug模式后安装iscsi相关软件包,手动挂载iscsi磁盘。 回到安装界面完成安装后,取消自动reboot回到命令行,挂载并且chroot到安装好的iscsi磁盘,添加iscsi配置,更新grub和initramfs。
这一步很重要,不然使用iscsi磁盘引导启动后会因为连不上iscsi磁盘无法继续启动操作系统。而我按照教程update-initramfs的时候提示找不到/boot/efi,这里需要手动mount /dev/sda2 /boot/efi
之后就是重启,ipxe使用sanboot命令从iscsi启动。
#从iscsi启动。挂载iscsi磁盘并且从磁盘启动。
sanboot iscsi:[iscsiserver]:::[lun]:[iqn]
后记
至此,成功使用pxe引导无盘proxmox启动。windows和其他linux发行版的引导启动方式也大同小异,不要拘泥于他人教程里的方式,过程中用到的pxe、dhcp、tftp、webserver、iscsi软件都可以选择不同的产品灵活组合使用,甚至见过有文章介绍用nfs作为linux启动磁盘的。
花了一整个晚上摸索实现,其实动机只是为了省一块nvme硬盘,笑…proxmox不像esxi,启动后还是会频繁对系统盘进行读写,U盘长时间顶不住,大容量的nvme做系统盘又浪费,才费尽心思实现无盘proxmox,其实想想作为弹性算力节点,还挺合适的。