PXE无人值守安装Ubuntu 20.04:dnsmasq+Apache+autoinstall实战

发布时间:2026/10/21 15:09:06

PXE无人值守安装Ubuntu 20.04:dnsmasq+Apache+autoinstall实战 机房新到一批机器要统一装 Ubuntu 20.04 server十几台机器挨个插U盘装到晚上九点还是小事真正烦的是装出来的系统细节对不上有人分区选了LVM有人忘了配SSH有人装完才发现网卡名不一样。后来我在一台 Ubuntu 20.04 desktop 上把整套 PXE 网络安装环境搭了起来同一网段的裸机开机就自动进安装流程全程无人值守装完就是我要的配置。这套东西听起来名字长拆开其实就三样服务加一份自动安装配置下面把从零搭建的完整过程、每一条配置的用途、以及我实际踩过的坑都写出来照着敲就能复现适合刚开始接触 PXE 的运维新手也适合想从老式 preseed 迁移到 subiquity autoinstall 的朋友。1. PXE引导链路与20.04自动安装的特殊性1.1 为什么批量装机最后都会走到PXE一两台机器的时候U盘和启动盘完全够用但机器数量一上来U盘方案的痛点就很明显首先是物理成本你得有足够的U盘还得一台台插拔、等待、确认其次是版本一致性今天装的和昨天装的因为软件源更新或者操作偏差最后拿到手的系统很难完全一样。PXE 的本质是把安装介质从一块移动硬盘变成一个网络服务客户端开机后网卡固件主动去网络上找启动文件和安装源装出来的系统完全由服务端的一份配置决定不存在手工差异。PXE 是 Intel 定义的预启动执行环境规范它不在操作系统里运行而是嵌在网卡固件或者主板固件里。只要同一广播域里有一个服务端愿意回应它的请求它就能完成获取网络地址 → 下载引导程序 → 加载内核 → 启动安装器这一整套动作。对批量装机来说这几乎是唯一一条维护成本低、结果可复现的路。1.2 PXE三个服务角色整条引导链路依赖三个服务很多人配置失败就是因为只搞了其中一两个。我用一张表把它们的职责理清楚服务端口负责内容本文使用软件DHCP67/UDP分配IP地址并告诉客户端从哪台TFTP服务器下载哪个引导文件dnsmasqTFTP69/UDP传输引导程序、内核 vmlinuz 和内存盘 initrddnsmasq 内置HTTP80/TCP提供 Ubuntu server 的 ISO 镜像和 autoinstall 配置文件Apache2完整流程是客户端 PXE 固件发出 DHCP 广播 → dnsmasq 返回 IP同时附上 next-server 和 bootfile 两个关键选项 → 客户端去 TFTP 下载 bootloader → bootloader 再通过 TFTP 拉取内核与 initrd → 内存系统启动 → cloud-init 从 HTTP 拉取 autoinstall 配置 → subiquity 安装器执行无人值守安装。任何一个环节断了客户端的表现都是卡住不动或者一行看不懂的英文错误这也是 PXE 排错一开始容易懵的原因。1.3 Ubuntu 20.04 server 安装器的变化20.04 server 的默认安装方式已经和 14.04、16.04 时代完全不同。现在官方 ISO 是 live-server 版安装器叫 subiquity底层是 curtin 加 cloud-init自动安装能力通过一份 cloud-init 的 user-data 文件来定义也就是 autoinstall。早年那套传统的 debian-installer 加 preseed 方式在 20.04 里还能用但官方维护重心已经转移到 autoinstall 上新环境直接走 subiquity 路线更省事。用 desktop 版做服务端没有任何问题PXE 相关的服务对系统版本依赖很低20.04 desktop 装完后自带桌面环境反而方便你在图形界面里顺手改配置、看日志。你只需要把它当成一台普通的 Ubuntu 服务器来用桌面环境不构成任何负担。2. 实验台搭建前的网络规划与软件准备2.1 我这边实验网络的划分方式PXE 启动依赖广播客户端和服务端必须处于同一个二层网络。最省事的做法是准备一台普通交换机PXE 服务器和待安装机器全部接在上面单独划出一个装机网段不要和办公网混在一起。我这边实验网段是 192.168.1.0/24PXE 服务器固定 192.168.1.10dnsmasq 的地址池从 192.168.1.100 到 192.168.1.200网关是上级路由器 192.168.1.1。这里有个重要提醒装机网段里绝对不能同时存在另一个 DHCP 服务器。家用路由器、公司网关很多时候默认开着 DHCP两个 DHCP 在同一广播域里会随机响应客户端的请求客户端拿到的 IP 可能一会儿来自路由器一会儿来自 dnsmasqPXE 引导时好时坏症状非常难查。实验环境里最好把上级设备的 DHCP 关掉或者干脆用一个独立交换机把装机网段隔离开。PXE 服务器自身的 IP 必须静态配置。桌面版直接在图形界面的网络设置里把 IPv4 改成 Manual 也可以用但我更建议用 netplan方便以后复制到别的机器。需要注意桌面版默认的 renderer 是 NetworkManager如果你用 netplan 改配置要把 renderer 保持一致别混着改同一张网卡否则重启后网络可能起不来。2.2 需要安装的软件包在 PXE 服务器上执行sudo apt update sudo apt install -y dnsmasq apache2 syslinux grub-efi-amd64-signed这四个包的职责分别是dnsmasq一个进程同时承担 DHCP 和 TFTP配置文件短PXE 选项表达直观。apache2提供 HTTP 服务分发 ISO 镜像和 autoinstall 配置。syslinux提供 BIOS 客户端要用的 pxelinux.0 引导程序和 ldlinux.c32 模块。grub-efi-amd64-signed提供 UEFI 客户端要用的 grub 网络引导镜像。注意这里没有安装 tftpd-hpa。很多老教程会让你装一个独立的 TFTP 服务但本文使用 dnsmasq 内置的 TFTP如果你再把 tftpd-hpa 启动起来两个进程都会去抢 69 端口结果就是客户端 TFTP 超时。这属于最容易掉进去的坑先在这里挡住。2.3 端口与服务冲突排查安装完成后先确认端口没有被占用ss -ulpn | grep -E :(67|69)\b ss -tlnp | grep :80如果启用了 ufw 防火墙需要放行 DHCP、TFTP 和 HTTPsudo ufw allow 67/udp sudo ufw allow 69/udp sudo ufw allow 80/tcp还有一个隐藏的冲突点Ubuntu 桌面版默认跑着 systemd-resolved它占用 53 端口。本文的 dnsmasq 配置会把 DNS 功能整个关闭只保留 DHCP 和 TFTP所以不会和 systemd-resolved 冲突不需要额外处理。如果你习惯在 dnsmasq 里同时开 DNS那就得先把 systemd-resolved 的监听停掉否则 dnsmasq 会报地址被占用直接退出。3. dnsmasq一分钟搞定DHCP和TFTP联动3.1 为什么我不用isc-dhcp-server网上大量教程用的是 isc-dhcp-server 加 tftpd-hpa 加 nginx 的三件套这套方案很成熟在企业里也很常见但组件多意味着配置文件多、需要同步维护的点也多。dnsmasq 把 DHCP 和 TFTP 揉进一个进程配置文件只有十几行PXE 的 tag 匹配逻辑写起来非常直白对实验室、小机房这种场景是最省心的选择。如果你的环境要求 DHCP 和企业现有网络严格隔离或者需要非常细粒度的 vendor class 控制再考虑切到 isc-dhcp-server 也不迟。3.2 这份配置文件的每一行在干什么先创建 TFTP 根目录然后编辑 /etc/dnsmasq.confsudo mkdir -p /srv/tftp sudo vim /etc/dnsmasq.conf写入以下内容port0 interfaceens33 bind-interfaces dhcp-range192.168.1.100,192.168.1.200,255.255.255.0,12h dhcp-option3,192.168.1.1 dhcp-option6,192.168.1.1 dhcp-authoritative enable-tftp tftp-root/srv/tftp dhcp-matchx64-uefi,option:client-arch,7 dhcp-matchx86-uefi,option:client-arch,9 dhcp-boottag:x64-uefi,grubx64.efi dhcp-boottag:x86-uefi,grubx64.efi dhcp-bootpxelinux.0逐行解释关键项port0关闭 dnsmasq 的 DNS 功能。我们只需要 DHCP 和 TFTP这样不会和系统的 53 端口起冲突。interfaceens33指定服务监听哪块网卡改成你自己服务器的实际网卡名。dhcp-range定义分配地址池、掩码和租约时间。这里的地址池要和 PXE 服务器本身处于同一网段。dhcp-option3 和 dhcp-option6下发网关和 DNS 服务器地址让客户端装完系统后网络配置直接可用。dhcp-authoritative让 dnsmasq 对网段内的 DHCP 请求立即响应不用等一个 ping 探测客户端开机引导速度会快一些。enable-tftp 和 tftp-root启用内置 TFTP并指定引导文件的根目录。dhcp-match按 DHCP 选项 93client-arch给客户端打 tag。架构编号 7 是 x64 UEFI9 是 x86 UEFI。dhcp-bootdnsmasq 会优先匹配带 tag 的几行所以 UEFI 客户端拿到 grubx64.efi而没有匹配 tag 的 BIOS 客户端落到最后一行 pxelinux.0。重启服务并观察日志sudo systemctl restart dnsmasq sudo systemctl enable dnsmasq tail -f /var/log/syslog | grep dnsmasq如果 UEFI 客户端拿到的是 pxelinux.0 而不是 grubx64.efi绝大多数情况是 dhcp-match 没匹配上。可以在 dnsmasq 日志里看到客户端上报的 client-arch 值按实际值补一条匹配规则就行。3.3 已有DHCP网络怎么办proxyDHCP模式如果装机网段里已经有了一个你动不了的 DHCP 服务器dnsmasq 还有另一种用法proxyDHCP。把 dhcp-range 改成dhcp-range192.168.1.0,proxy,255.255.255.0此时 dnsmasq 不再主动分配 IP而是等客户端拿到地址后额外补充 PXE 相关的 next-server 和 bootfile 信息。这让 PXE 环境可以叠加在现有网络上不必去改上游 DHCP。不过 proxy 模式对 PXE 客户端固件的兼容性不如独立 DHCP 稳定实验环境如果条件允许还是优先用独立 DHCP。4. 引导文件BIOS和UEFI两条腿走路4.1 BIOS客户端pxelinux.0部署BIOS 客户端的引导程序来自 syslinux 包复制两个文件到 TFTP 根目录sudo cp /usr/lib/PXELINUX/pxelinux.0 /srv/tftp/ sudo cp /usr/lib/syslinux/modules/bios/ldlinux.c32 /srv/tftp/ sudo mkdir -p /srv/tftp/pxelinux.cfg然后创建 /srv/tftp/pxelinux.cfg/defaultDEFAULT install PROMPT 0 TIMEOUT 30 LABEL install MENU LABEL Install Ubuntu 20.04 Server (autoinstall) KERNEL casper/vmlinuz INITRD casper/initrd APPEND ipdhcp urlhttp://192.168.1.10/iso/ubuntu-20.04.6-live-server-amd64.iso autoinstall dsnocloud;shttp://192.168.1.10/autoinstall/ ---pxelinux 的引导参数全部写在 APPEND 这一行。pxelinux.cfg 的配置查找顺序是 GUID、MAC 地址、IP 地址最后才是 default这意味着你可以给特定机器建一个以 MAC 命名的文件写不同的安装参数后面我会再展开讲这个用法。4.2 UEFI客户端grubnetx64.efi.signed和grub/grub.cfgUEFI 客户端走的是 grub 路线。grub-efi-amd64-signed 这个包里带了一个专门用于网络引导的签名镜像直接复制成引导文件名sudo cp /usr/lib/grub/x86_64-efi-signed/grubnetx64.efi.signed /srv/tftp/grubx64.efi sudo mkdir -p /srv/tftp/grub sudo vim /srv/tftp/grub/grub.cfggrub.cfg 内容如下set default0 set timeout30 menuentry Install Ubuntu 20.04 Server (autoinstall) { set gfxpayloadkeep linux /casper/vmlinuz ipdhcp urlhttp://192.168.1.10/iso/ubuntu-20.04.6-live-server-amd64.iso autoinstall dsnocloud\;shttp://192.168.1.10/autoinstall/ --- initrd /casper/initrd }这个 grub 网络镜像会把配置文件的位置固定为 TFTP 根目录下的 /grub/grub.cfg所以路径必须放对否则客户端会在 grub 提示符里停住。还有一个细节URL 里的 dsnocloud;s 中间有个分号grub 的命令解析器会把分号当作命令分隔符所以要写成 dsnocloud;shttp://...用反斜杠转义。这个坑我一开始没注意结果内核参数被截断cloud-init 一直没拿到 autoinstall 配置安装器直接进了交互界面。如果你的 grub 包路径和我写的不一样用 dpkg -L grub-efi-amd64-signed 查一下实际文件位置。还有一种做法是用 grub-mknetdir 生成网络启动镜像但对大多数场景直接复制签名镜像更省事。4.3 从server ISO里提取vmlinuz和initrd内核和 initrd 在 Ubuntu 20.04 live-server ISO 的 casper 目录里。先把 ISO 挂载出来把两个文件复制到 TFTPmkdir -p /tmp/isomnt sudo mount -o loop,ro ubuntu-20.04.6-live-server-amd64.iso /tmp/isomnt sudo mkdir -p /srv/tftp/casper sudo cp /tmp/isomnt/casper/vmlinuz /srv/tftp/casper/ sudo cp /tmp/isomnt/casper/initrd /srv/tftp/casper/ sudo umount /tmp/isomnt sudo chmod -R ar /srv/tftpinitrd 有 100MB 左右TFTP 传输不算快单台机器完全能接受。几十台机器同时开装时可以考虑把 vmlinuz 和 initrd 放到 HTTP 上grub.cfg 里用 http://192.168.1.10/... 这样的前缀去拉传输速度会快很多。但 BIOS 这条链路的 pxelinux 对 HTTP 内核支持比较麻烦建议保持 TFTP 不动。这里特别提醒千万不要用 desktop 版 ISO 的 casper 文件搭配 server 版 ISO 的 url 参数两个版本的内核和安装器行为不一致启动后会出现各种奇怪错误。TFTP 里的三个文件必须来自同一个 server ISO。5. HTTP镜像与autoinstall无人值守配置5.1 镜像ISO直接交给HTTP服务autoinstall 的安装源可以是一个 HTTP 地址指向的 ISO 文件安装器启动后会自己下载并挂载它不需要我们把整个 ISO 解压到目录里。把 ISO 放进 Apache 的根目录就行sudo mkdir -p /var/www/html/iso sudo cp ubuntu-20.04.6-live-server-amd64.iso /var/www/html/iso/这样做的好处是省事坏处是每台客户端都要完整下载一遍这个 2GB 左右的 ISO机器多的时候 Apache 的并发和出口带宽会吃紧。小批量安装完全无所谓几十台并发时再考虑 NFS 或者本地镜像源。另外如果以后换了新版本 ISO记得和 TFTP 里的 vmlinuz/initrd 同步更新版本必须锁死这一点我在最后一节还会单独强调。5.2 user-data里到底该写什么autoinstall 的本质是 cloud-init 的 user-data由 cloud-init 在内存系统启动后从指定 URL 拉取。我们需要建立两个文件sudo mkdir -p /var/www/html/autoinstall sudo vim /var/www/html/autoinstall/meta-datameta-data 可以很简单instance-id: pxe-ubuntu-2004-lab local-hostname: pxe-client然后编辑 /var/www/html/autoinstall/user-data#cloud-config autoinstall: version: 1 locale: zh_CN.UTF-8 keyboard: layout: cn network: network: version: 2 ethernets: all-eth: match: name: e* dhcp4: true storage: layout: name: lvm identity: hostname: pxe-client username: labadmin password: $6$mysalt123$生成的哈希值 ssh: install-server: true allow-pubkey: true authorized-keys: - ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAA... 你的公钥 packages: - qemu-guest-agent - vim late-commands: - echo pxe installed by autoinstall /target/pxe-info.txt这份配置里几个关键点说明一下locale 和 keyboard按需设置中文环境写 zh_CN.UTF-8 和 cn不写就保持英文环境。network 段是 netplan 语法这里用 match 匹配所有以 e 开头的网卡名避免不同主板的网卡名差异把安装卡住。生产环境如果有多网卡需要做 bond 或者固定 IP可以在这里写完整的 netplan 配置。storage.layout.name 是 subiquity 的 guided 分区方式lvm 表示全盘走 LVMdirect 表示不套 LVM 直接用物理分区。服务器我一般都选 lvm方便以后扩逻辑卷。identity 里的 password 不是明文必须是 crypt(3) 的 SHA-512 哈希。生成方式openssl passwd -6 -salt mysalt123 你的密码把输出结果填到 password 字段里别手滑把明文写进去否则装完登录不进去。ssh 段开启 SSH server并且允许注入公钥。如果是纯内网实验环境authorized-keys 可以不写用密码登录就行。late-commands 是 curtin 在目标系统 chroot 环境里执行的命令所以路径要带 /target。这里写了一个标识文件方便安装完成后确认机器确实走了 autoinstall 而不是手动装的。还有一个必须记住的约定user-data 第一行必须是 #cloud-config否则 cloud-init 不会识别它meta-data 和 user-data 两个文件都必须存在于同一个目录下cloud-init 会分别去拉 s 路径下的这两个文件。5.3 kernel cmdline各参数的含义把引导参数拆开看每一段都有明确的用途参数含义ipdhcp让内存系统启动后通过 DHCP 获取网络配置url告诉 subiquity 安装器安装源 ISO 位于哪个 HTTP 地址autoinstall声明启用自动安装找不到 user-data 时直接失败并提示而不是退回交互界面dsnocloud;s指定 cloud-init 使用 NoCloud 数据源并从 s 后面的 URL 拉取 meta-data 和 user-data---casper 环境的分隔符之后的内容交给 initrd 处理特别注意 s 这个 URL 的末尾要有斜杠cloud-init 会在后面拼接 /meta-data 和 /user-data少一个斜杠就拼出一个 404 地址。如果你不想把安装源写在 kernel 参数里也可以在 user-data 的 autoinstall 段里通过 source 字段指定但 kernel 参数的方式更直观排查起来也容易。5.4 先验证HTTP再开机上物理机之前先在 PXE 服务器上把三个 HTTP 资源都验一遍curl -s http://192.168.1.10/autoinstall/meta-data curl -s http://192.168.1.10/autoinstall/user-data | head -5 curl -I http://192.168.1.10/iso/ubuntu-20.04.6-live-server-amd64.iso三处都能正常返回再让客户端开机。PXE 排错最忌讳一次改多个变量先把服务端资源全部确认无误再去动客户端能省掉大量无效排查时间。6. 从虚拟机到物理机验证流程与排错6.1 用虚拟化平台先跑一遍全流程在碰物理机之前强烈建议先在虚拟化平台上完整跑一遍。我用 virt-manager 新建了一台虚拟机网络选择桥接到 PXE 服务器所在网段固件类型按需求选 UEFI 或 BIOS磁盘给 20GB内存 4GB启动方式直接选网络启动PXE。过程很简单重点是一次完整的无人值守安装应该能看到这样的流程grub 菜单出现 → 选 Install 条目 → 内核加载 → cloud-init 拉取配置 → subiquity 界面出现安装进度 → 自动分区、装包 → 重启。虚拟机这步能过滤掉八成以上的配置错误。安装完成后用创建的用户登录系统检查 /pxe-info.txt 文件是否存在再确认分区是不是 LVM 布局、SSH 是否开启。虚拟机都过不了的话物理机大概率也不行没必要去机房蹲着试错。6.2 安装现场的高频故障定位即使配置看起来全对客户端开机后仍然可能出问题。以下是我实际遇到过的故障和排查路径现象可能原因排查方法客户端一直拿不到 IPdhcp-range 不在同一网段、interface 写错、网段里有别的 DHCPtail /var/log/syslog 看 dnsmasq 日志tcpdump -i ens33 port 67 or port 68 抓包拿到 IP 但 TFTP 超时69 端口被防火墙挡、tftpd-hpa 和 dnsmasq 抢端口、tftp-root 路径不存在ss -ulpn 检查 69 端口归属确认 /srv/tftp 里文件存在报 PXE-E53 或者加载引导文件失败UEFI 客户端没匹配到 grubx64.efi拿到了 pxelinux.0dnsmasq 日志里看 client-arch 值补 dhcp-matchgrub 能启动但停在 grub 命令行/grub/grub.cfg 位置不对确保文件在 /srv/tftp/grub/grub.cfg且大小写正确直接进入 subiquity 交互界面autoinstall 数据没被识别检查 dsnocloud 的 URL 末尾斜杠、user-data 第一行、meta-data 是否存在安装中途提示找不到安装源url 指向的 ISO 不可达或 TFTP 里的 vmlinuz/initrd 与实际 ISO 版本不一致curl -I 验证 ISO确认三个文件来自同一版本存储阶段提示 No disk found虚拟机没挂磁盘或 SCSI 控制器类型不对检查虚拟机的磁盘设备尝试换 virtio 控制器安装器一旦跑起来出问题要看两个日志目标系统里的 /var/log/installer/subiquity-server-debug.log 和内存系统里的 /var/log/cloud-init.log。大多数 autoinstall 拉取失败的问题都能在这两个日志里直接看到请求了哪个 URL、返回了什么状态码。6.3 UEFI安全启动与网卡固件的现实问题物理机和虚拟机最大的差别在固件层面。如果你的客户端开着 Secure Boot本文用的签名 grub 镜像在多数主板上能通过校验但个别主板对网络启动流程的 Secure Boot 检查很严格表现是引导文件下载完就被拒绝执行。实验环境里我通常先把 Secure Boot 关掉把整个 PXE 流程跑通后再回头琢磨怎么在开启 Secure Boot 的情况下用 shim 方案引导。不要在排错初期让 Secure Boot 和 PXE 两个变量叠加在一起。另外很多主板默认没有开启网卡的网络启动栈不同厂商的选项名字还不一样有的叫 Network Stack有的叫 UEFI Network Boot。找不到网络启动入口的时候先进固件设置里确认这个开关再考虑按 F12、F11、Esc 这些一次性启动菜单快捷键的问题。实在不行就把 Network Boot 设为第一启动项。7. 几轮批量装机之后我留下的经验7.1 镜像版本必须锁死TFTP 里的 vmlinuz 和 initrd 必须和 HTTP 上的 ISO 来自同一个发布版本。20.04.1 的内核配上 20.04.6 的安装源短时间可能没感觉但安装器会在某些特定步骤出现行为偏差尤其是 casper 对内核参数的解析错一个版本就可能出现根文件系统挂载失败。我的习惯是 ISO 文件名带上具体版本号TFTP 和 HTTP 目录里也按版本建子目录PXE 配置里写死完整路径不搞 latest 这种软链接。latest 看着方便一旦镜像更新所有客户端引导全断排查起来反而更累。7.2 用MAC或固件型号做引导分流同一套 PXE 环境装不同硬件时最灵活的做法是按客户端分流。pxelinux.cfg 目录下创建以 MAC 地址命名的文件/srv/tftp/pxelinux.cfg/01-aa-bb-cc-dd-ee-ff文件内容结构和 default 一样但 KERNEL 和 APPEND 可以改成不同的内核参数或 autoinstall 文件。grub 里也有类似能力在 grub.cfg 里可以根据网卡 MAC 设置不同的变量。这个功能特别适合机房混有不同品牌机器、需要不同分区方案或不同内核参数的环境不用维护多套 PXE 服务。7.3 把这套环境安全地送进生产网络PXE 服务本身不复杂复杂的是怎么不破坏现有网络。第一不要把 dnsmasq 的 DHCP 地址池和公司现有 DHCP 重叠两个 DHCP 在同一广播域互相抢答轻则 IP 冲突重则有人电脑突然断网重取地址。第二装机网段最好单独一个 VLAN装完一批机器后直接停掉 dnsmasqsudo systemctl disable --now dnsmasq这样能防止后续哪台机器因为误触网络启动而意外重装。第三Apache 不需要开目录索引知道确切路径的人能访问就够了避免网内其他人顺手把你的 ISO 下载走。7.4 如果要走传统preseed路线20.04 的 legacy netboot 镜像仍然可以下载使用老环境或者特殊需求可以继续用 preseed但新项目不建议再走这条路。subiquity 的 autoinstall 对网络安装的支持已经非常完整配置表达也更清晰而且官方所有新文档和工具链都以 autoinstall 为准。花了时间学会 autoinstall以后升级到更新版本基本是平滑过渡抱着 preseed 不放只会越来越吃力。最后说一个我自己的习惯每次改完配置文件我都会先在服务端用 curl、ss、tail 三条命令把 HTTP、TFTP、DHCP 三样分别验一遍再让客户端开机。PXE 排错最忌讳一次改多个变量因为引导文件、DHCP 选项、autoinstall 任何一个环节出错客户端表现看起来都差不多不是黑屏就是一串 PXE 错误。把服务端三件套都锁死剩下的问题基本都集中在内核参数和 cloud-init 的 URL 拼接上。按这个节奏来这台 Ubuntu 20.04 desktop 就能稳稳当当地把整个机房的无人值守安装任务扛下来以后再接新机器只需要插上网线剩下的交给网络。
延伸阅读

更多相关文章

2026/10/21 15:09:05

时域卷积网络TCN:从原理到实战的时间序列建模指南

1. 为什么我开始研究时域卷积网络1.1 序列建模中反复遇到的两类痛点前阵子做一个工业时序回归任务,数据是一台设备的秒级采样,一个小时就是3600个点,累积到几天长度接近十万步,还带着明显的周期性和偶发的阶跃漂移。我一开始图省事…

2026/10/21 15:03:50

agent-skills:把智能体能力沉淀为可复用、可编排的技能库

agent-skills:把智能体能干的活,沉淀成一套可复用、可编排的技能库做Agent项目时间长了,你会发现一个挺扎心的规律:单看一个智能体的Demo,跑通并不难,难的是让它稳定地干很多不同类型的活。今天聊的这个项目…

2026/10/21 16:05:34

ZigBee智能路灯控制系统:从方案选型到联网联调的全栈实践

1. 方案选型:为什么是ZigBee扛起路灯组网这面旗 做路灯控制系统,第一关不是写代码,而是选通信方式。我在做这个项目之前,其实先试过WiFi方案和蓝牙Mesh方案,最后才定下来用ZigBee。先说结论:ZigBee不是各方…

2026/10/21 16:05:34

51单片机胎压监测系统实战:从Proteus仿真到代码避坑

简介:这份资源面向电子信息、自动化及汽车电子方向的在校学生与单片机初学者,提供一套基于51单片机的汽车胎压监测报警系统完整设计资料,帮助读者理解从传感器采集到声光报警的整条实现链路。压缩包为zip格式,约9.87MB&#xff0c…

2026/10/21 16:05:34

Docker镜像构建实战:多阶段瘦身与buildx多架构交叉编译

Docker 玩到一定阶段,大家几乎都会遇到两个绕不开的事儿:一个是把镜像做干净、做稳定,另一个是让镜像在不同 CPU 架构上都能跑。前者是基本功,后者尤其在 ARM 设备、树莓派、异构服务器混布的场合里特别刚需。这次就从一个实际项目…

2026/10/21 16:05:34

C语言中函数的声明、定义及使用的入门教程

前言 初学 C 语言时,「声明」「定义」「调用」这三个词经常被混着用。有人把函数头加一个分号就叫定义,有人把头文件里的原型当成实现,还有人写了函数却忘了在调用处之前声明,靠编译器「猜」出一个返回 int 的版本。这些混淆在单个…

2026/10/21 16:05:34

知识工作插件:面向认知任务的轻量级自动化单元

1. 项目概述:这不是插件,而是一套知识工作者的“思维外挂”系统“knowledge-work-plugins”这个标题乍看像某个开源仓库名,但拆开来看——knowledge(知识)、work(工作)、plugins(插件…

2026/10/21 16:00:33

文件上传绕过实战:从日志包含到RCE的完整攻击链分析

1. 从"能上传"到"能利用":这道题真正考的是什么先说结论:这道CTF题作业2最坑人的地方,恰恰在于它看起来"太简单了"。很多人一看到文件上传,脑子里立刻蹦出三个字——"马"呢?然…

2026/10/21 4:53:08

金融AI落地指南:从调研报告到技术选型与工程实践

简介:这份PDF报告聚焦2025年金融服务业中国AI现状与趋势,面向金融科技从业者、AI战略规划人员及关注行业数字化转型的研究者,帮助读者把握生成式AI在银行、支付、交易等场景中的落地路径与投资方向。资源包内含1个PDF文件,大小约1…

2026/10/21 0:00:35

交通流仿真实战:IDM跟驰与MOBIL换道模型参数调优与避坑指南

简介:这份资源是面向交通工程学习者与Python开发者的微观交通流仿真项目,核心实现智能驾驶模型(IDM)下的车辆跟驰与换道行为,可用于理解速度、密度与流量之间的动态关系,适合具备Python基础、希望深入交通模…

2026/10/21 0:00:35

揭穿智能体表面顺从:用追踪代码重建任务执行确定性

1. 表面顺从不是智能体的“礼貌”,而是任务执行链路上的隐性断点最近在调试一个跨平台长周期任务调度系统时,我反复遇到一种令人困惑的现象:智能体在用户指令发出后,几乎秒级响应“已收到”“正在处理”“请稍候”,UI上…

2026/10/21 0:00:35

统一内存+量化:锐龙AI Max PRO 400如何本地跑320B大模型

这段时间硬件圈和AI圈都在传一个事:AMD锐龙AI Max PRO 400系列把最高192GB统一内存搬进了PC形态的产品里,按宣传口径,本地跑320B参数的大家伙不再是纸面概念。我第一反应倒不是“内存真大”,而是这话背后的含金量——它把过去只能…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑