pxe无盘启动
介绍 (Intro)
PXE is a great solution for booting a diskless computer (or a computer without an OS installed). This method is often used for terminal stations and OS mass installation.
PXE是引导无盘计算机(或未安装操作系统的计算机)的绝佳解决方案。 此方法通常用于终端站和OS批量安装。
Stock ubuntu (16.04) in pxe-mode can mount rootfs only from NFS. But this is not a great idea: any difficulties with the network/NFS server and the user gets problems.
pxe模式下的常规ubuntu(16.04)只能从NFS挂载rootfs。 但这不是一个好主意:网络/ NFS服务器的任何困难和用户都会遇到问题。
In my opinion, it's best to use other protocols, such as http/ftp. Once booting, you will have an independent system
我认为,最好使用其他协议,例如http / ftp。 一旦启动,您将拥有一个独立的系统
You should add information about the limits of applicability of the proposed solution and what are the dependencies and restrictions.
您应该添加有关建议的解决方案的适用性限制以及相关性和限制的信息。
短信息 (Pxe short info)
PXE (Preboot Execution Environment) is a special method for booting a computer from the bios / EFI. How it works (simplified scheme):
PXE(预引导执行环境)是一种从BIOS / EFI引导计算机的特殊方法。 工作原理(简化方案):
- The computer bios/uefi sends ordinary dhcp request (DHCPDISCOVER) 计算机BIOS / UEFI发送普通的dhcp请求(DHCPDISCOVER)
- The dhcp server sends a response with the next-server option dhcp服务器使用next-server选项发送响应
- The computer sends DHCPREQUEST/DHCPINFORM request 计算机发送DHCPREQUEST / DHCPINFORM请求
- The dhcp server sends TFTP server address and the filename to upload dhcp服务器发送TFTP服务器地址和文件名进行上传
- The computer downloads this file from the tftp server. Its size is limited so, often, it's a bootloader like pxeinux 计算机从tftp服务器下载此文件。 它的大小有限,因此通常是像pxeinux这样的引导程序
- pxelinux reads its own config and downloads Linux kernel using initramfs pxelinux读取自己的配置,并使用initramfs下载Linux内核
- Linux kernel downloads squashfs with main rootfs Linux内核使用主rootfs下载squashfs
- switch_root to its squashfs 切换到其南瓜
Keep in mind that TFTP is a slow protocol. It works around UDP with a small block size (512K). Of course, you can increase this value, but this is a way of unstable operation.
请记住,TFTP是一个缓慢的协议。 它适用于具有小块大小(512K)的UDP。 当然,您可以增加此值,但这是不稳定操作的一种方式。
A better solution:
更好的解决方案:
- get bootloader via tftp 通过tftp获取引导程序
- get kernel (+ initramfs) via tftp 通过tftp获取内核(+ initramfs)
- get main rootfs squash via http/tftp 通过http / tftp获得主要的rootfs壁球
我该怎么做 (How i do it)
Steps to solve the task:
解决任务的步骤:
- Add modules to initramfs 将模块添加到initramfs
- Write my own boot script and add it to initramfs 编写我自己的启动脚本并将其添加到initramfs
- Make new initramfs 制作新的initramfs
- Create squashfs with future rootfs 使用将来的rootfs创建squashfs
- Setup pxe server 设置pxe服务器
- Run it 运行
I used squashfs for rootfs (the simplest way is to create squashfs from installed ubuntu). Overlayfs is necessary to make rootfs writable.
我将squashfs用于rootfs(最简单的方法是从已安装的ubuntu创建squashfs)。 覆盖是使rootfs可写的必要条件。
Supported protocols are http/ftp, but you can try to add others via curl/other software.
支持的协议是http / ftp,但是您可以尝试通过curl /其他软件添加其他协议。
自定义initramfs (Customize initramfs)
There are 2 places where you can customize initramfs in ubuntu:
您可以在2个地方自定义ubuntu中的initramfs:
- /etc/initramfs-tools / etc / initramfs-tools
- /usr/share/initramfs-tools/ / usr / share / initramfs-tools /
I'll use /usr/share/initramfs-tools. First, I added needed support modules in initramfs:
我将使用/ usr / share / initramfs-tools。 首先,我在initramfs中添加了所需的支持模块:
boozlachu@comp:~$ cat /usr/share/initramfs-tools/modules.d/pxe
overlayfs
squashfs
Next, I wrote a boot script that does all the work:
接下来,我编写了一个启动脚本来完成所有工作:
boozlachu@comp:~$ cat /usr/share/initramfs-tools/scripts/pxe
#!/bin/bash
mountroot()
{
maxTryCount=5
squashfsFile="/tmp/rootfs.squashfs"
squashfsMountPoint="/mnt/ro"
tmpfsMountPoint="/mnt/rw"
overlayfsUppderDir="$tmpfsMountPoint/upper"
overlayfsWorkDir="$tmpfsMountPoint/work"
overlayfsDir="/mnt/overlayfs"
tryCount="1"
# run udevadm
wait_for_udev 10
# parce kernel cmdline args. rooturl needed
for x in $(cat /proc/cmdline); do
case $x in
rooturl=*)
export rooturl=${x#rooturl=}
;;
maxTryCount=*)
export maxTryCount=${x#maxTryCount=}
;;
esac
done
log_begin_msg "Loading modules"
modprobe squashfs || panic "can't modprobe squashfs"
modprobe af_packet || panic "can't modprobe af_packet"
modprobe overlay || panic "can't modprobe overlayfs"
log_success_msg "modules loaded"
log_begin_msg "Configure network"
configure_networking || panic "Can't configure network"
log_success_msg "Network configured"
log_begin_msg "Download rootfs"
while [ ! -f ${squashfsFile} ] && [ ${tryCount} -le ${maxTryCount} ]; do
wget ${rooturl} -O ${squashfsFile} || log_failure_msg "Can't download rootfs, count ${tryCount}"
tryCount=$(( ${tryCount} + 1 ))
sleep 0.5
done
if [ -f ${squashfsFile} ]
then
log_success_msg "Rootfs downloaded"
else
panic "Can't download rootfs"
fi
log_begin_msg "Mount rootfs"
mkdir -p $squashfsMountPoint
mount -t squashfs -o loop $squashfsFile $squashfsMountPoint || panic "Can't mount rootfs"
log_success_msg "Rootfs mounted"
log_begin_msg "Mount tmpfs"
mkdir -p $tmpfsMountPoint
mount -t tmpfs none $tmpfsMountPoint || panic "Tmpfs mount failed "
log_success_msg "Tmpfs mounted"
log_begin_msg "Mount overlayfs"
mkdir -p $overlayfsUppderDir $overlayfsWorkDir $overlayfsDir
mount -t overlay overlay -o lowerdir=$squashfsMountPoint,upperdir=$overlayfsUppderDir,workdir=$overlayfsWorkDir $overlayfsDir \
|| panic "Overlayfs mount failed"
log_success_msg "Overlayfs mounted"
log_begin_msg "Move tmpfs and squashfs to new root"
mkdir -p $overlayfsDir/$tmpfsMountPoint $overlayfsDir/$squashfsMountPoint
mount --move $squashfsMountPoint $overlayfsDir/$squashfsMountPoint || panic "squashfs move failed"
mount --move $tmpfsMountPoint $overlayfsDir/$tmpfsMountPoint || panic "tmpfs move failed"
log_success_msg "Tmpfs and squashfs moved"
log_begin_msg "Move overlayfs to new root"
mount --move $overlayfsDir ${rootmnt} || panic ""
}
The script has a lot of messages for understanding how it works.
该脚本有很多消息,可帮助您理解其工作原理。
After the modules and script, add your need to generate new initramfs:
在模块和脚本之后,添加生成新initramfs的需求:
boozlachu@comp:~$ sudo update-initramfs -c -k all
创建壁球 (Creating squashfs)
The simplest method:
最简单的方法:
- install ubuntu on drive 在驱动器上安装ubuntu
- boot from LiveCD 从LiveCD引导
- create squashfs from the installed system 从已安装的系统创建squashfs
I don't recommend this way for production since you'll have a very large squashfs (not the best idea for pxe)!
我不建议您以这种方式进行生产,因为您会有非常大的南瓜(对于pxe来说不是最好的主意)!
设置引导加载程序,squashfs和pxe服务器 (Setup bootloader, squashfs, and pxe server)
I use pxelinux as a pxe bootloader. It's an easy way. My pxe servers are Debian 10, tftp-hpa,dhcpd, and lighttpd. I’ll omit the installation details, but I’ll show the important info.
我使用pxelinux作为pxe引导程序。 这是一个简单的方法。 我的pxe服务器是Debian 10,tftp-hpa,dhcpd和lighttpd。 我将省略安装细节,但会显示重要信息。
TFRP server file struct (/srv/tftp is root dir fot tftp-hpa):
TFRP服务器文件结构(/ srv / tftp是fdir tftp-hpa的根目录):
root@debian:/srv/tftp/ubuntu# tree /srv/tftp/
/srv/tftp/
└── ubuntu
├── firmware.sq
├── initrd
├── ldlinux.c32
├── libcom32.c32
├── libutil.c32
├── menu.c32
├── pxelinux.bin
├── pxelinux.cfg
│ └── default
├── vesamenu.c32
└── vmlinuz
- firmware.sq is squashfs with rootfs firmware.sq是带有rootfs的squashfs
- *c32 are files for pxelinux * c32是pxelinux的文件
- vmlinuz is kernel vmlinuz是内核
- initrd is initramfs(which i rebuild earler) initrd是initramfs(我重建了耳环)
- pxelinux.bin — main pxelinux file pxelinux.bin —主pxelinux文件
- default is config for pxelinux 默认是pxelinux的配置
Bootloader config:
引导程序配置:
root@debian:/srv/tftp/ubuntu# cat /srv/tftp/ubuntu/pxelinux.cfg/default
ui menu.c32
timeout 30
default ubuntu_pxe
font UniCyr_8x16.psf
menu title PXE Special Boot Menu
menu color tabmsg 37;40 #80ffffff #00000000
menu color hotsel 30;47 #40000000 #20ffffff
menu color sel 30;47 #40000000 #20ffffff
menu color scrollbar 30;47 #40000000 #20ffffff
LABEL ubuntu_pxe
menu label Run ubuntu pxe
kernel vmlinuz
append initrd=initrd rooturl=http://192.168.56.2/ubuntu/firmware.sq boot=pxe maxTryCount=10
It’s impotant to set the correct kernel parameters:
设置正确的内核参数很重要:
rooturl=http://192.168.56.2/ubuntu/firmware.sq, url for rootfs
rooturl = http://192.168.56.2/ubuntu/firmware.sq,rootfs的网址
- boot=pxe, use my script for boot boot = pxe,使用我的脚本进行引导
- maxTryCount=10, number of tries for rootfs download (optional, default value 5) maxTryCount = 10,尝试下载rootfs的次数(可选,默认值为5)
And the last one is the dhcp config:
最后一个是dhcp配置:
root@debian:/srv/tftp/ubuntu# cat /etc/dhcp/dhcpd.conf
subnet 192.168.56.0 netmask 255.255.255.0 {
range 192.168.56.10 192.168.56.45;
option routers 192.168.56.2;
option domain-name-servers 192.168.2.1 ;
option broadcast-address 192.168.56.255;
default-lease-time 3600;
max-lease-time 7200;
# Important! Set bootloader file
filename "ubuntu/pxelinux.bin";
}
The extended variant (if the dhcp and tftp servers placed on different machines) requires the next-server option for dhcp.
扩展版本(如果dhcp和tftp服务器位于不同的计算机上)需要dhcp的next-server选项。
结论 (Conclusion)
This article shows you how to change the boot mode of ubuntu without any difficulties. Use it as information and write your solutions. This can be a system in the form of firmware (with squashfs), pxe, or another solution.
本文向您展示如何轻松地更改ubuntu的启动模式。 将其用作信息并编写解决方案。 这可以是固件(带有squashfs),pxe或其他解决方案形式的系统。
pxe无盘启动