专业的编程技术博客社区

网站首页 > 博客文章 正文

mkosi- OS images生成神器介绍1(dism++iso生成器)

baijin 2024-10-14 08:16:42 博客文章 10 ℃ 0 评论

该工具在构建OS方面很实用,特别在调试使用systemd很方便。文档引自mkosi — A Tool for Generating OS Images (0pointer.net)-2017,结合目前最新版本(20231119)进行的整理.

概述

mkosi:Make Operating System Image,是一款专注于开发人员构建操作系统映像的工具,不仅能用于测试和调试,还能生成带有加密保护的生产映像。mkosi 会在镜像中加入开发头文件和工具,在其中编译你的代码,运行你的测试套件,然后再次丢弃镜像,构建一个新的镜像,这次不含开发头文件和工具,并在其中安装你的构建工件。最终的镜像文件就是用于部署生产环境的,只包含你构建的程序和你配置的最小软件包集。

mkosi 面向的是当下的技术,将生成 GPT 分区表而不是 MBR/DOS 分区表。 mkosi生成的可启动映像使其可在 EFI 而非传统 BIOS 上启动。因此 /etc/fstab 可以保持未填充状态,systemd-nspawn 等工具可以自动剖析映像并从中启动。

生成的具体图像:

  1. 以 ext4 为根的raw GPT disk image
  2. btrfs 为根的raw GPT disk image
  3. 以 只读 squashfs为根的raw GPT disk image
  4. 磁盘上直接包含OS的普通目录
  5. 磁盘上的 btrfs 子卷,与普通目录类似
  6. 普通目录的压缩包

如果选择了上述任何 GPT 选项,还可以使用其他几个选项:

  1. 可添加swap分区
  2. 可在 EFI 系统上启动系统
  3. 可为 /home 和 /srv 添加独立分区
  4. 可使用 dm-verity 保护root分区,从而使生成的系统难以受到离线攻击

目前,mkosi可以构建基于以下 Linux 发行版的映像:fedora, debian, ubuntu, arch, opensuse, mageia, centos, rhel, rhel-ubi, openmandriva, rocky, alma, custom。

目前并非所有发行版都支持相同的功能。由于 mkosi 基于 dnf --installroot, debootstrap, pacstrap 和 zypper,而这些软件包并没有在所有发行版上普遍打包,因此可能无法在任意主机发行版上构建所有这些发行版的镜像。

GPT images不仅兼容 UEFI 系统,还兼容虚拟机和容器管理器。 mkosi初衷是构建单一的 GPT image,用于以下用途:

  1. 在裸机上启动
  2. 在虚拟机中启动
  3. 在 systemd-nspawn 容器中启动
  4. 使用 systemd 的 RootImage= 参数可以直接关闭 systemd service

在上述四种情况下,dm-verity 数据都会自动使用(如果有的话),以确保镜像未被篡改(如果镜像有 dm-verity,systemd-nspawn 和 systemd 的 RootImage= 设置都会自动执行)。

模式

mkosi 最简单的用法是不带参数直接调用:

// ubuntu
#sudo apt-get install mkosi
# mkdir mkosi_test & cd mkosi_test
#sudo mkosi

在不做任何配置的情况下,会生成一个image.raw的 GPT disk image,然后放到当前目录下。生成的发行版与主机运行的发行版相同。

在大多数情况下需要定制镜像,如选择软件包集、选择发行版、分区大小等。可以在命令行中指定,但建议在目录下创建几个 mkosi.$SOMETHING 文件和目录。只需切换到该目录并运行 mkosi,无需其他参数。该工具将在当前工作目录中查找这些文件和目录,并使用它们(类似于 make 查找 Makefile 的方式......)。每个文件/目录都是可选的,但如果它们存在,就会被使用。下面是 mkosi 当前查找的文件/目录列表:

  • mkosi.default - 主要是配置文件,可以配置镜像类型、发行版、软件包等;
  • mkosi.extra/ - 如果该目录存在,mkosi 会将其中的所有内容复制到生成的镜像中。可以在这里放置任意的目录层次结构,在发行版的软件包管理器将其打包后,它们将被复制到镜像中的任何内容之上。这是在镜像中添加静态文件或覆盖发行版提供的静态文件的最佳方式。
  • mkosi.build - 这个可执行文件是一个构建脚本。当它存在时,mkosi 会构建两个镜像文件:第一个版本是构建镜像文件,可能包含各种构建时依赖项,如编译器或开发头文件。然后,脚本应构建任何需要构建的内容,并将结果放入 $DESTDIR。它还可以运行测试套件。脚本完成后,会再次移除构建镜像,并构建第二个镜像(最终镜像)。这次不会再包含开发包,也不会再将构建脚本复制到镜像中,但会将第一次运行时的构建工件(即放置在 $DESTDIR 中的工件)复制到镜像中。
  • mkosi.postinst - 如果存在这个可执行脚本,它将在镜像内部被调用,并可在镜像准备过程的最后阶段随意调整镜像。如果存在 mkosi.build,即所使用的双阶段开发构建流程,那么该脚本将被调用两次。传递给脚本的第一个参数说明了脚本在哪个阶段运行。
  • mkosi.nspawn - 如果该文件存在,则应包含 systemd-nspawn 的容器配置文件,该配置文件应与最终镜像一起装运,并应包含在校验和计算中。
  • mkosi.cache/ - 如果该目录存在,它将被用作编译时的软件包缓存目录。为了加快构建镜像的速度,该目录实际上是在构建时绑定挂载到镜像中的。各种发行版的软件包安装程序会将它们的软件包文件放在这里,以便后续运行时可以重复使用。
  • mkosi.passphrase - 如果存在此文件,则应包含用于 LUKS 加密的口令(如果已为所构建的映像启用此功能)。其他用户不得读取此文件。
  • mkosi.secure-boot.crt 和 mkosi.secure-boot.key 应该是 X.509 密钥对,用于 UEFI SecureBoot 内核和 initrd 的签名(如果启用)。

用法

生成image,容器启动,下面是个简单的demo.

# mkosi
# systemd-nspawn -bi image.raw

接下来可以定制一些简单的参数:

# mkosi -t raw_btrfs --bootable -o foobar.raw
# systemd-nspawn -bi foobar.raw

做了三处改动:有 GPT + ext4改为GPT + btrfs,该系统可在 UEFI 系统上启动,镜像名为foobar.raw。

由于该系统可在 UEFI 系统上启动,因此我们可以在 KVM 中运行它:

# kvm -m 512 -smp 2 -bios /usr/share/OVMF/OVMF_CODE.fd -drive format=raw,file=foobar.raw

使用的环境为ubuntu,需要安装qemu、qemu-kvm。与 systemd-nspawn 的调用非常相似,只不过使用的是完全虚拟机虚拟化而非容器虚拟化。

使用 mkosi 并不全是raw GPT disk images。普通的目录映像:

# mkosi  -t directory -o quux
# systemd-nspawn -bD quux

生成的纯目录镜像不能在裸机上启动,也不能在虚拟机中运行。

接下来举例个复杂些demo

mkosi -t raw_squashfs --checksum --xz --package=git --package=vim

在这种模式下, mkosi 生成带有root squashfs 的 GPT 压缩镜像(xz压缩),并生成一个包含哈希值的 SHA256SUMS 文件。软件包将包含git和vim编辑器。

以上的方式都是采用追加参数定制OS,接下来使用各种 mkosi.$SOMETHING 文件。假设开发某个基于 Automake 的项目,并希望能轻松地在开发树上生成一个磁盘镜像,其中包含你正在开发的版本。创建一个配置文件:

//  mkosi.default
[Distribution]
Distribution=ubuntu

[Output]
Format=raw_btrfs
Bootable=yes

[Packages]
# The packages to appear in both the build and the final image
Packages=git vim
# The packages to appear in the build image, but absent from the final image
BuildPackages=make gcc libcurl-devel

创建编译脚本

// mkosi.build
#!/bin/sh
./autogen.sh
./configure --prefix=/usr
make -j `nproc`
make install
# chmod +x mkosi.build
# mkosi

注: 如果在同一个目录下编译提示:image.raw exists already,可以加f参数进行强制编译:mkosi -f

构建images可能会相当慢,会严重影响你的工作效率,使用运行之间共享的软件包缓存:

# mkdir mkosi.cache

软件包现在只需下载一次并重复使用。发现解压所有这些软件包和其他工作仍然相当缓慢,只需使用 mkosi 的增量构建功能。在这种模式下,mkosi 会在放入构建源代码之前,立即复制一份构建镜像和最终镜像,这样构建镜像就会变得更快:构建工作不再总是完全从头开始,而是会重用之前运行的所有可以重用的东西,并立即开始构建源代码,而不是在构建镜像中构建源代码。使用参数-i启用增量构建功能:

# mkosi -i

请注意,如果使用该选项,发行版服务器上的软件包列表将不再更新,因为缓存副本是在所有软件包安装完成后创建的。

如果已经编译过,不会覆盖已经存在的生成镜像文件。可以使用mkosi -f 删除。如果 mkosi 不仅要删除任何此类已存在的图像,还要删除增量功能的任何缓存副本,方法是使用两次 -f。

# mkosi -i -f && systemd-nspawn -bi image.raw
或
# mkosi -i -f -f && systemd-nspawn -bi image.raw

后者只有在我想根据 Fedora 提供的最新 RPM 而不是缓存快照重新生成一切时才会使用。

mkosi最初创建的目的是为了调试systemd,systemd 源码中包含:mkosi.default 和 mkosi.build。任何想用当前 systemd git 快速测试的开发人员,或者想在此基础上编写补丁并进行测试的开发人员,都可以查看 systemd 仓库,然后在其中运行 mkosi,几分钟后就能得到一个可启动镜像,可以在 systemd-nspawn 或 KVM 中进行测试。

其他特性

  1. mkosi 支持 UEFI SecureBoot。要使用该功能,请将 X.509 密钥对放入两个文件 mkosi.secureboot.crt 和 mkosi.secureboot.key,并设置 SecureBoot= 或 --secure-boot。mkosi 就会在构建过程中sign kernel/initrd/kernel-cmdline组合。如果使用这种模式,还应该使用 Verity=/--verity=,否则设置只能起到部分作用。mkosi 不会实际注册 UEFI BIOS 中使用的密钥。
  2. mkosi 对 GIT checkouts的支持极少:当它识别到在 git checkouts中运行,并使用 mkosi.build 脚本时,源代码树将被复制到构建镜像中,但会删除所有被 .gitignore 排除在外的文件。
  3. 创建映像时可删除所有文档。
  4. 可为生成的映像配置 root user password和其他内核命令行参数。(调试关键特性)

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表