资讯动态

深入解析 debian-installer:架构、preseed 自动安装与定制实践

发布时间:2026/10/22 19:33:36 来源:尧图企业网站定制
1. 为什么还要折腾 debian-installer很多人第一次接触 Debian 安装用的是官方提供的 ISO 镜像一路回车、选时区、分区、装 GRUB半小时搞定。这套流程背后真正干活的就是debian-installer下文简称 d-i。平时我们把它当成一个黑盒直到某天遇到一台老掉牙的机器、一块特殊的阵列卡、或者需要批量部署几十台同配置的服务器才会发现默认的安装流程不够用了必须钻进 d-i 内部去改点东西。这篇内容就是记录我自己从“只会点下一步”到“能改 d-i 配置、能定制 preseed、能排查安装卡死”的整个过程。核心关键词就三个debian-installer、preseed 自动安装、安装器组件结构。它解决的是“标准化、可复现地装 Debian”这个问题适合已经会装系统、但想进一步掌控安装流程的运维和嵌入式方向的朋友。哪怕你只是想搞明白安装界面背后发生了什么读下去也会有收获。d-i 本质上不是一个单一程序而是一堆udebmicro 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 的启动流程可以粗略分成几个阶段每个阶段都有对应的组件负责引导阶段BIOS/UEFI 加载引导器isolinux、grub-efi 等读取内核vmlinuz和初始内存盘initrd.gz。这个 initrd 里就包含了 d-i 的最小运行环境。initrd 阶段内核启动后执行/init挂载必要的文件系统启动busybox环境然后运行 d-i 的主入口。组件加载阶段anna这个程序负责从镜像或网络安装 udeb 组件。它会根据硬件检测结果和用户选择动态加载需要的模块比如网卡驱动、文件系统工具、分区工具。配置阶段debconf负责和用户交互把用户的选择记录下来供后续组件读取。分区、时区、用户账户、软件包选择都在这个阶段完成。基础系统安装阶段base-installer把基础系统解压到目标分区apt-install安装额外软件包最后grub-installer或lilo-installer写入引导器。收尾阶段卸载文件系统重启进入新系统。这个流程里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 uw /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 组件。配置片段示例DHCPsubnet 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/defaultdefault debian-installer label debian-installer kernel debian-installer/amd64/linux append initrddebian-installer/amd64/initrd.gz \ autotrue prioritycritical \ preseed/urlhttp://192.168.1.10/preseed.cfg \ localezh_CN.UTF-8 keymapus这个方案的优势是集中管理改一次 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 autotrue prioritycritical 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或者固件文件缺失。排查步骤切换到 d-i 的第二个控制台AltF2查看/var/log/syslog。用lspci -nn确认网卡型号。检查/lib/modules/下有没有对应的驱动模块。如果缺固件把固件文件放到 ISO 的firmware/目录或者通过 preseed 的hw-detect/load_firmware指定路径。我遇到过一次 Intel 网卡需要iwlwifi固件官方 netinst 里没带最后是把固件 deb 包解开把.ucode文件塞进 initrd 才解决。5.2 preseed 不生效的几种可能preseed 文件写了但没起作用通常有这几个原因现象可能原因解决方法仍然弹出交互界面preseed 路径不对检查preseed/file或preseed/url参数部分选项没生效优先级不够加prioritycritical或把选项改成seen报语法错误格式不对确认每行以d-i或tasksel开头值类型正确网络源不可用镜像地址错误用mirror/http/hostname指定可访问的源注意preseed 里的boolean类型只接受true或false写成yes或no会报错。这个坑我踩过不止一次。5.3 分区方案不按预期执行partman-auto的 recipe 选择很关键。atomic是单分区方案home是分离/homemulti是分离多个目录。如果选了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 就能立即测试效率高很多。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑