16.3. 通过使用容器文件集成驱动程序
通过使用多级容器文件集成自定义驱动程序。这将构建工具和依赖项与最终生产映像分离,并确保只有运行时驱动程序保留在最终可引导容器映像中。
先决条件
-
您已使用容器引擎(如
Podman)初始化了映像模式开发环境,并且您可以访问容器注册表。 -
您的构建主机上有驱动程序源代码和有效的
.spec文件。 -
RPM 包包括一个
%post脚本,该脚本在构建过程中自动运行depmod以处理容器映像内部的依赖映射。 -
如果需要显式模块参数或显式启动加载,相应的配置文件(如
/usr/lib/modules-load.d/hello.conf)将包含在 RPM 或容器构建上下文中,以便在系统启动时自动加载驱动程序。
流程
在构建主机上创建多级
容器文件,以将驱动程序编译并安装到操作系统映像中:# --- STAGE 1: Build Environment --- FROM registry.redhat.io/rhel10/rhel-bootc:latest AS builder # Install build tools and kernel development headers for the image kernel RUN dnf install -y make gcc kernel-devel && \ dnf clean all # Copy driver source and spec file into the builder stage COPY src/ /build/src/ COPY SPECS/hello.spec /build/SPECS/ # Build the driver RPM package inside the container context WORKDIR /build RUN rpmbuild --define "_topdir /build" -ba SPECS/hello.spec # --- STAGE 2: Final Production Image --- FROM registry.redhat.io/rhel10/rhel-bootc:latest # Copy only the generated RPM from the builder stage COPY --from=builder /build/RPMS/x86_64/hello-1.0-1.el10.x86_64.rpm /tmp/ # Install the RPM. The internal %post script automatically triggers 'depmod'. RUN dnf install -y /tmp/hello-1.0-1.el10.x86_64.rpm && \ dnf clean all && \ rm /tmp/hello-1.0-1.el10.x86_64.rpm构建
引导容器镜像:$ podman build -t registry.example.com/bootc-images/rhel-hello:latest .将完成的映像推送到您的目标容器注册表:
$ podman push registry.example.com/bootc-images/rhel-hello:latest通过使用适合您的系统状态的适当方法将映像部署到目标系统:
-
对于新安装: 使用
bootc-image-builder生成使用此容器引用预配置的可引导 ISO 或磁盘映像。 对于现有系统: 在目标主机上执行就地参考开关:
$ sudo bootc switch registry.example.com/bootc-images/rhel-hello:latest
-
对于新安装: 使用
验证
重新启动目标系统以引导到包含驱动程序的新部署的容器映像:
$ sudo reboot通过检查内核环缓冲区和实时模块,确认驱动程序在系统启动过程中自动加载:
$ journalctl -b -k | grep -i hello$ lsmod | grep '^hello' hello 12288 0如果模块没有自动加载,请验证是否存在适当的硬件别名,或者配置文件是否驻留在
/usr/lib/modules-load.d/目录中。确认模块文件存在于与正在运行的内核匹配的正确不可变目录结构中:
$ sudo uname -r10.0.0-example.el10.x86_64$ sudo ls -l /usr/lib/modules/$(uname -r)/extra/total 12 -rwxr-xr-x. 1 root root 8512 Jan 1 1970 hello.ko通过卸载和重新加载模块来测试手动生命周期操作:
$ sudo rmmod hello$ sudo modprobe hello检查内核环缓冲区日志以验证正确的初始化和清理行为:
$ sudo dmesg | tail -n 5[ 84.738633] hello: loading out-of-tree module taints kernel. [ 84.738684] hello: module verification failed: signature and/or required key missing -tainting kernel. [ 84.740548] Hello, world! [ 138.206978] Goodbye!注意-
加载尚未使用可信安全启动密钥签名的自定义树外模块时,会出现
模块验证失败消息和内核污染警告。这些警告并不妨碍模块成功执行。 - 当禁用统一可扩展固件接口 (UEFI) 安全引导且内核模块签名实施未激活时,未签名的树外模块将成功加载。内核会报告签名验证警告并注册受污染的状态,但不阻止执行。
- 启用 UEFI 安全引导后,内核将拒绝未签名的树外模块或使用不可信密钥签名的模块。对于安全引导环境,请使用目标系统固件或机器所有者密钥 (MOK) 数据库信任的公钥对模块进行签名。
-
加载尚未使用可信安全启动密钥签名的自定义树外模块时,会出现
检查目标系统上的安全启动状态:
$ mokutil --sb-state