☰
深入解析 debian-installer:架构、preseed 自动安装与定制实践
2026/10/22 19:33:31 网站建设 项目流程

1. 为什么还要折腾 debian-installer

很多人第一次接触 Debian 安装,用的是官方提供的 ISO 镜像,一路回车、选时区、分区、装 GRUB,半小时搞定。这套流程背后真正干活的,就是debian-installer(下文简称 d-i)。平时我们把它当成一个黑盒,直到某天遇到一台老掉牙的机器、一块特殊的阵列卡、或者需要批量部署几十台同配置的服务器,才会发现:默认的安装流程不够用了,必须钻进 d-i 内部去改点东西。

这篇内容就是记录我自己从“只会点下一步”到“能改 d-i 配置、能定制 preseed、能排查安装卡死”的整个过程。核心关键词就三个:debian-installer、preseed 自动安装、安装器组件结构。它解决的是“标准化、可复现地装 Debian”这个问题,适合已经会装系统、但想进一步掌控安装流程的运维和嵌入式方向的朋友。哪怕你只是想搞明白安装界面背后发生了什么,读下去也会有收获。

d-i 本质上不是一个单一程序,而是一堆udeb(micro deb,精简版 deb 包)拼起来的运行环境。它跑在一个临时构建的根文件系统里,这个根文件系统可能是从 ISO 加载的,也可能是通过网络引导(PXE)拉下来的。安装过程分阶段:先加载内核和 initrd,然后 d-i 的主程序anna去安装各个组件,apt-install装基础系统,最后base-installer把内核和引导器写进目标磁盘。理解这条链路,后面所有定制和排错都有了抓手。

我踩过的第一个坑,就是以为改/etc/apt/sources.list就能影响安装阶段。实际上安装阶段用的是 d-i 自己的源配置,在/etc/apt/sources.list之外还有一套逻辑。这个后面会细说。

2. debian-installer 的整体架构拆解

2.1 从引导到安装完成的分阶段流程

d-i 的启动流程可以粗略分成几个阶段,每个阶段都有对应的组件负责:

  1. 引导阶段:BIOS/UEFI 加载引导器(isolinux、grub-efi 等),读取内核vmlinuz和初始内存盘initrd.gz。这个 initrd 里就包含了 d-i 的最小运行环境。
  2. initrd 阶段:内核启动后执行/init,挂载必要的文件系统,启动busybox环境,然后运行 d-i 的主入口。
  3. 组件加载阶段:anna这个程序负责从镜像或网络安装 udeb 组件。它会根据硬件检测结果和用户选择,动态加载需要的模块,比如网卡驱动、文件系统工具、分区工具。
  4. 配置阶段:debconf负责和用户交互,把用户的选择记录下来,供后续组件读取。分区、时区、用户账户、软件包选择都在这个阶段完成。
  5. 基础系统安装阶段:base-installer把基础系统解压到目标分区,apt-install安装额外软件包,最后grub-installer或lilo-installer写入引导器。
  6. 收尾阶段:卸载文件系统,重启进入新系统。

这个流程里,udeb 的加载顺序非常关键。如果某个 udeb 依赖的库没被提前加载,安装就会卡住或者报错。我遇到过一次网卡驱动没被正确加载,导致网络安装源不可用,整个安装流程直接停在“检测网络硬件”那一步。

2.2 udeb 与 deb 的区别,以及为什么这样设计

udeb 是 deb 的精简版,去掉了文档、man page、非必要的依赖,只保留运行所需的最小文件。这样做的好处是:

  • 体积小:整个 d-i 运行环境可以塞进几十 MB 的 initrd 里。
  • 加载快:从 ISO 或网络加载 udeb 的速度远快于完整 deb。
  • 依赖可控:udeb 的依赖关系被严格限制,避免引入不必要的组件。

但代价是,udeb 的功能是裁剪过的。比如partman系列 udeb 只提供分区所需的最小功能,没有图形界面,也没有高级的 LVM 配置向导(除非额外加载对应的 udeb)。这就解释了为什么 d-i 的分区界面看起来比安装后的gparted简陋得多。

提示:如果你想在安装阶段使用某个工具,先确认它有没有对应的 udeb。没有的话,要么自己打包,要么在安装完成后通过 preseed 的 late_command 来装。

2.3 安装器与目标系统的边界

一个容易混淆的点是:d-i 运行的环境和最终装好的系统是两套东西。d-i 里的/etc、/usr都是临时根文件系统里的内容,安装完成后会被丢弃。目标系统的文件系统挂载在/target下,base-installer往/target里写东西。

这意味着:

  • 你在 d-i 里改的配置文件,不会自动带到目标系统。
  • 目标系统的配置需要通过 preseed 的late_command或者pkgsel/include来注入。
  • 安装日志在/var/log/installer/下,重启后就没了,需要提前收集。

我刚开始做自动化安装时,把一堆配置写进了 d-i 的/etc,结果装完系统发现全丢了,白忙活一场。这个边界一定要记牢。

3. 定制 debian-installer 的几种路径

3.1 直接改 ISO:适合快速验证

最直接的定制方式是把官方 ISO 解开,修改里面的文件,再重新打包。步骤大致如下:

# 挂载或解压 ISO mkdir -p /mnt/iso mount -o loop debian-12.x-amd64-netinst.iso /mnt/iso # 复制到工作目录 mkdir -p /work/iso cp -r /mnt/iso/* /work/iso/ chmod -R u+w /work/iso # 修改 isolinux 配置或 preseed 文件 # ... # 重新生成 md5 校验 cd /work/iso md5sum $(find . -type f) > md5sum.txt # 重新打包 genisoimage -o custom-debian.iso -r -J -no-emul-boot \ -boot-load-size 4 -boot-info-table \ -b isolinux/isolinux.bin -c isolinux/boot.cat \ -eltorito-alt-boot -e boot/grub/efi.img -no-emul-boot \ /work/iso

这个方法的优点是快,改完就能测试。缺点是每次改都要重新打包,而且 ISO 体积大,传输和存储都不方便。适合验证 preseed 文件是否正确、引导参数是否生效。

注意:重新打包时-b和-e参数必须和原 ISO 一致,否则 UEFI 或 BIOS 引导会失败。我试过漏掉-eltorito-alt-boot,结果 UEFI 机器根本认不出启动盘。

3.2 搭建 PXE 网络引导:适合批量部署

当需要装几十台机器时,PXE 是更合理的选择。核心组件包括:

  • DHCP 服务器:分配 IP,并告知客户端 TFTP 服务器地址和引导文件名。
  • TFTP 服务器:提供pxelinux.0、内核、initrd 和 preseed 文件。
  • HTTP 服务器:提供 Debian 软件包仓库和 udeb 组件。

配置片段示例(DHCP):

subnet 192.168.1.0 netmask 255.255.255.0 { range 192.168.1.100 192.168.1.200; option routers 192.168.1.1; next-server 192.168.1.10; filename "pxelinux.0"; }

PXE 引导的配置文件放在 TFTP 根目录的pxelinux.cfg/default:

default debian-installer label debian-installer kernel debian-installer/amd64/linux append initrd=debian-installer/amd64/initrd.gz \ auto=true priority=critical \ preseed/url=http://192.168.1.10/preseed.cfg \ locale=zh_CN.UTF-8 keymap=us

这个方案的优势是集中管理,改一次 preseed 文件,所有机器下次启动就生效。缺点是搭建和维护成本高,需要保证网络环境稳定。

3.3 用 preseed 做无人值守:最实用的自动化手段

preseed 是 d-i 的自动化应答文件,格式类似 debconf 的模板。它把安装过程中所有需要用户输入的问题,提前用答案填好。一个最小的 preseed 文件长这样:

# 语言和地区 d-i debian-installer/locale string zh_CN.UTF-8 d-i keyboard-configuration/xkb-keymap select us # 网络配置 d-i netcfg/choose_interface select auto d-i netcfg/get_hostname string debian-node d-i netcfg/get_domain string local # 镜像源 d-i mirror/country string manual d-i mirror/http/hostname string mirrors.example.com d-i mirror/http/directory string /debian d-i mirror/http/proxy string # 时钟和时区 d-i clock-setup/utc boolean true d-i time/zone string Asia/Shanghai # 分区 d-i partman-auto/method string regular d-i partman-auto/choose_recipe select atomic d-i partman-partitioning/confirm_write_new_label boolean true d-i partman/confirm boolean true d-i partman/confirm_nooverwrite boolean true # 用户账户 d-i passwd/root-login boolean false d-i passwd/user-fullname string deploy d-i passwd/username string deploy d-i passwd/user-password password insecure d-i passwd/user-password-again password insecure # 软件包 tasksel tasksel/first multiselect standard, ssh-server d-i pkgsel/include string openssh-server vim curl # GRUB d-i grub-installer/only_debian boolean true d-i grub-installer/with_other_os boolean true # 收尾 d-i finish-install/reboot_in_progress note

这个文件覆盖了大部分常见场景。实际使用时,我会把它拆成几个片段,按功能分组,方便维护。

提示:preseed 里的密码是明文,生产环境一定要配合加密或者安装后立即改密。我一般用late_command调用chpasswd来设置加密后的密码。

4. 实操:从零构建一个定制安装镜像

4.1 准备工作与目录结构

先规划好工作目录,避免文件散落各处:

mkdir -p /work/d-i/{iso,extract,preseed,scripts} cd /work/d-i

下载官方 netinst ISO 和对应的校验文件:

wget https://cdimage.debian.org/debian-cd/current/amd64/iso-cd/debian-12.5.0-amd64-netinst.iso wget https://cdimage.debian.org/debian-cd/current/amd64/iso-cd/SHA256SUMS sha256sum -c SHA256SUMS --ignore-missing

校验通过后再解压,避免用到损坏的镜像。

4.2 修改引导参数与 preseed 注入

解压 ISO 后,找到isolinux/isolinux.cfg和boot/grub/grub.cfg,在默认启动项里加上 preseed 参数:

append auto=true priority=critical preseed/file=/cdrom/preseed/custom.cfg

然后把写好的 preseed 文件放到 ISO 的preseed/目录下。注意路径要和参数一致。

如果是 UEFI 引导,还要改boot/grub/grub.cfg里对应的菜单项。我遇到过只改了 isolinux 配置,结果 UEFI 机器启动后还是走交互式安装,排查了半天才发现是 grub 配置没同步。

4.3 重新打包与校验

打包命令前面提过,这里补充几个细节:

  • -no-emul-boot和-boot-load-size 4是 BIOS 引导必需的。
  • -eltorito-alt-boot后面跟的是 EFI 引导镜像,路径要对。
  • 打包完成后用isohybrid处理一下,让 ISO 可以直接写入 U 盘:
isohybrid --uefi custom-debian.iso

最后用虚拟机测试,分别验证 BIOS 和 UEFI 两种引导方式。我一般用 QEMU 快速跑一遍:

qemu-system-x86_64 -m 2048 -cdrom custom-debian.iso -boot d

如果安装过程能自动走完并重启进入系统,说明 preseed 生效了。

5. 常见问题与排查技巧实录

5.1 安装卡在“检测网络硬件”

这是最常见的问题之一。原因通常是网卡驱动没有对应的 udeb,或者固件文件缺失。排查步骤:

  1. 切换到 d-i 的第二个控制台(Alt+F2),查看/var/log/syslog。
  2. 用lspci -nn确认网卡型号。
  3. 检查/lib/modules/下有没有对应的驱动模块。
  4. 如果缺固件,把固件文件放到 ISO 的firmware/目录,或者通过 preseed 的hw-detect/load_firmware指定路径。

我遇到过一次 Intel 网卡需要iwlwifi固件,官方 netinst 里没带,最后是把固件 deb 包解开,把.ucode文件塞进 initrd 才解决。

5.2 preseed 不生效的几种可能

preseed 文件写了但没起作用,通常有这几个原因:

现象可能原因解决方法
仍然弹出交互界面preseed 路径不对检查preseed/file或preseed/url参数
部分选项没生效优先级不够加priority=critical,或把选项改成seen
报语法错误格式不对确认每行以d-i或tasksel开头,值类型正确
网络源不可用镜像地址错误用mirror/http/hostname指定可访问的源

注意:preseed 里的boolean类型只接受true或false,写成yes或no会报错。这个坑我踩过不止一次。

5.3 分区方案不按预期执行

partman-auto的 recipe 选择很关键。atomic是单分区方案,home是分离/home,multi是分离多个目录。如果选了atomic但期望有独立/home,那肯定不对。

自定义分区可以用partman-auto/expert_recipe,格式如下:

d-i partman-auto/expert_recipe string \ custom :: \ 1024 1024 1024 ext4 \ $primary{ } $bootable{ } \ method{ format } format{ } \ use_filesystem{ } filesystem{ ext4 } \ mountpoint{ /boot } \ . \ 2048 2048 -1 ext4 \ method{ format } format{ } \ use_filesystem{ } filesystem{ ext4 } \ mountpoint{ / } \ .

这个 recipe 定义了两个分区:1GB 的/boot和剩余空间的/。数字含义是“最小 优先 最大”,单位 MB,-1表示不限制。

5.4 安装日志的收集与分析

d-i 的日志在/var/log/installer/下,包括syslog、partman、apt等。安装完成后这些日志会被复制到目标系统的/var/log/installer/,但如果是失败退出,日志就留在内存里,重启就没了。

我的做法是在 preseed 里加一个late_command,把日志打包发到远程服务器:

d-i preseed/late_command string \ in-target tar czf /tmp/installer-logs.tar.gz /var/log/installer; \ in-target curl -X POST -F "file=@/tmp/installer-logs.tar.gz" http://log.example.com/upload

这样即使安装失败,也能拿到日志分析原因。

6. 一些个人体会和后续可扩展的方向

折腾 d-i 这段时间,最大的感受是:它的设计哲学是“最小化、模块化、可组合”,所以定制起来灵活,但门槛也高。官方文档虽然全,但很多细节散落在各个 udeb 的 README 和源码里,需要耐心翻。

如果后续要继续深入,我会从这几个方向入手:

  • 自己打包 udeb:把常用的工具做成 udeb,塞进 initrd,这样安装阶段就能用。
  • 结合配置管理工具:preseed 负责装系统,Ansible 或 SaltStack 负责装完后的配置,形成完整流水线。
  • 研究 d-i 的源码:特别是anna和partman的实现,理解组件加载和分区逻辑的细节。

最后分享一个小技巧:测试 preseed 时,不用每次都重新打包 ISO。可以用 QEMU 的-kernel和-initrd参数直接引导 d-i 的内核和 initrd,然后通过preseed/url指向本地的 HTTP 服务器。这样改一次 preseed 就能立即测试,效率高很多。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询