惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

量子位
Stack Overflow Blog
Stack Overflow Blog
人人都是产品经理
人人都是产品经理
The GitHub Blog
The GitHub Blog
Engineering at Meta
Engineering at Meta
Vercel News
Vercel News
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Y
Y Combinator Blog
The Cloudflare Blog
Last Week in AI
Last Week in AI
B
Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
T
Tailwind CSS Blog
V
Visual Studio Blog
博客园 - 三生石上(FineUI控件)
小众软件
小众软件
Google DeepMind News
Google DeepMind News
D
DataBreaches.Net
博客园 - 司徒正美
B
Blog RSS Feed
Microsoft Azure Blog
Microsoft Azure Blog
罗磊的独立博客
Hugging Face - Blog
Hugging Face - Blog
L
LangChain Blog

Stray Episode

From OPC to NPC 如何手搓一辆公路车 捡垃圾,H3C TX1801 plus路由器刷OpenWRT AI时代,人人都是架构师(bushi 捡垃圾,折腾一下HP 544+ FLR 老板,来杯IPA,像我生活一样苦的 偷一个ICC文件,把你的相机变哈苏 基于泰山派的 PiKVM 现代Python CRUD技术栈 电子佛曰:我看你是完全不懂哦 一个按键都被你玩出花——《节奏医生》 为什么学渣不喜欢上学 使用Telepresence开发调试k8s应用 因为山就在那里,《Celeste蔚蓝》 只要开始摆烂,那我就是无敌的
PXE自动化无人值守安装Ubuntu
Windfarer · 2025-10-26 · via Stray Episode

在家里尝试了下跑通PXE装机流程,纯流水帐记录,能跑就行。

先说句题外话,我家里是用PVE起的虚拟机,需要注意的是创建VM时网卡型号不能选VirtIO,可能跑DHCP会有问题,选Intel E1000E是可以用的。另外如果要测试UEFI,只要把BIOS类型选成OVMF(UEFI)即可,不需要创建EFI Disk。

整个PXE流程里,主要涉及这几个玩意:

  • DHCP Server:给新来的机器分配ip,仙人指路到tftp下pxe需要的东西
  • TFTP Server:用于提供efi文件(UEFI模式)或者pxelinux(Legacy模式),以及相应的引导配置文件
  • HTTP Server:用于提供ubuntu的安装.iso和autoinstall用的user-data文件,没啥特殊要求,用nginx或者caddy都行,或者直接python起一个。
  • autoinstall:Ubuntu官方的无人值守安装工具,通过一个YAML文件描述安装过程中所有要填的配置项,从而实现完全自动化安装。

dnsmasq 配置

安装dnsmasq用作dhcp server,这个玩意自带了tftp,省事了。
我是直接把家里主路由的DHCP关了,让这家伙独自工作的。如果网络中有其他DHCP server,好像要用Proxy模式,目前还没研究。

apt update
apt install dnsmasq 

mkdir /srv/tftp

vim /etc/dnsmasq.conf
# 加一行上游dns resolver
server=server=8.8.8.8

# 编辑pxe配置内容
vim /etc/dnsmasq.d/pxe.conf

pxe.conf文件内容,需要根据对应网络设备和情况来配置网卡,网段等信息

interface=eth0
bind-interfaces
dhcp-range=10.4.0.100,10.4.0.200,255.0.0.0,12h
dhcp-option=option:router,10.0.0.1

enable-tftp
tftp-root=/srv/tftp

dhcp-match=set:bios,option:client-arch,0

dhcp-match=set:uefi64,option:client-arch,7
dhcp-match=set:uefi64,option:client-arch,9

dhcp-boot=tag:bios,pxelinux.0
dhcp-boot=tag:uefi64,bootx64.efi

启动dnsmasq服务,因为可能systemd resolved这个家伙已经把53端口给占了,所以先把它干掉再起dnsmasq。

systemctl stop systemd-resolved

systemctl restart dnsmasq

# 关了防火墙,免得捣乱
systemctl stop ufw

TFTP Server文件准备

UEFI 模式

下载个ubuntu iso然后mount

mount -o loop ubuntu-22.04.5-live-server-amd64.iso /mnt

# 下面的目录在tftp里都是固定的,不能随意改,不然可能找不到文件
cp /mnt/casper/{vmlinuz,initrd} /srv/tftp/

apt download shim-signed
dpkg-deb --fsys-tarfile shim-signed*deb | tar x ./usr/lib/shim/shimx64.efi.signed.latest -O > /srv/tftp/bootx64.efi

apt download grub-efi-amd64-signed
dpkg-deb --fsys-tarfile grub-efi-amd64-signed*deb | tar x ./usr/lib/grub/x86_64-efi-signed/grubnetx64.efi.signed -O > /srv/tftp/grubx64.efi

apt download grub-common
dpkg-deb --fsys-tarfile grub-common*deb | tar x ./usr/share/grub/unicode.pf2 -O > /srv/tftp/unicode.pf2

# grub.cfg放在哪和发行版相关,这玩意应该是焊死在grubx64.efi里的,所以随便放个目录,会导致grub会找不到cfg文件,没法正常引导后续安装
mkdir /srv/tftp/grub

# 编写grub配置文件内容
vim /srv/tftp/grub/grub.cfg

/srv/tftp/grub/grub.cfg 文件内容如下,注意以下几点:

  1. ds=nocloud-net后面的;前面有个转义符不能忘记
  2. s=参数后面填的是http server中有user-data这个文件的目录路径
  3. 命令结尾有---
set default="0"
set timeout=0

if loadfont unicode ; then
  set gfxmode=auto
  set locale_dir=$prefix/locale
  set lang=en_US
fi
terminal_output gfxterm

set menu_color_normal=white/black
set menu_color_highlight=black/light-gray
if background_color 44,0,30; then
  clear
fi

function gfxmode {
        set gfxpayload="${1}"
        if [ "${1}" = "keep" ]; then
                set vt_handoff=vt.handoff=7
        else
                set vt_handoff=
        fi
}

set linux_gfx_mode=keep

export linux_gfx_mode

menuentry 'Ubuntu 22.04.5' {
        gfxmode $linux_gfx_mode
        linux /vmlinuz $vt_handoff ip=dhcp url=http://10.4.0.12:8000/ubuntu-22.04.5-live-server-amd64.iso autoinstall ds=nocloud-net\;s=http://10.4.0.12:8000/ ---
        initrd /initrd
}

Legacy BIOS 模式

wget http://archive.ubuntu.com/ubuntu/dists/focal/main/installer-amd64/current/legacy-images/netboot/pxelinux.0
mkdir -p /srv/tftp
mv pxelinux.0 /srv/tftp/

apt install -y syslinux-common
cp /usr/lib/syslinux/modules/bios/ldlinux.c32 /srv/tftp/

mkdir /srv/tftp/pxelinux.cfg

# 编写pxelinux配置
vim /srv/tftp/pxelinux.cfg/default

/srv/tftp/pxelinux.cfg/default 文件内容,需要注意

  1. ds=nocloud-net后面的;前面没有转义符
  2. s=参数后面填的是http server中有user-data这个文件的目录路径
  3. 命令结尾有---
DEFAULT install
LABEL install
  KERNEL vmlinuz
  INITRD initrd
  APPEND root=/dev/ram0 ramdisk_size=1500000 ip=dhcp url=http://10.4.0.12:8000/ubuntu-22.04.5-live-server-amd64.iso autoinstall ds=nocloud-net;s=http://10.4.0.12:8000/ ---

HTTP Server文件准备

先把ubuntu-22.04.5-live-server-amd64.iso放到这个目录下。

然后添加一些autoinstall的配置文件进来。

touch meta-data

vim user-data

user-data文件内容,手写或者从一个安装完的机器/var/log/installer/autoinstall-user-data抄一个过来,配置文件的内容编写参考 https://canonical-subiquity.readthedocs-hosted.com/en/latest/reference/autoinstall-reference.html
注意必须有#cloud-config开头,安装程序才能正确识别和加载

#cloud-config
autoinstall:
  version: 1
  locale: "en_US.UTF-8"
  keyboard:
    layout: "us"
    variant: ""
  identity:
    hostname: "new-machine"
    username: "eric"
    # 用"openssl passwd -6"生成一个
    password: "$6$WTiT9hNmg735gtCQ$db6Mkz3V.DF/ymHFR3R1t6/QZ4Gj87v5SladOxKqaxr2XgzQVYcwuXP3I.iBOifNY46EJDEW03zeh.qpNBm.k1"
  storage:
    layout:
      name: direct
  network:
    version: 2
    ethernets:
      eth0:
        dhcp4: true
  ssh:
    install-server: true
    allow-pw: true
  packages:
    - vim
    - curl
  late-commands:
    - echo "Autoinstall complete" > /target/root/autoinstall.log

把http server起来

python -m http.server

安装

让机器从网络启动,它在DHCP成功后会自己跑完PXE流程,加载完内核,引导ubuntu安装iso,并通过autoinstall跑完整个安装流程,整个过程不需要任何人工介入。

dnsmasq在有请求时可以看到日志,通过命令查看

journalctl -u dnsmasq -f