Redian新闻
>
使用 mkosi 构建 RHEL 和 RHEL UBI 镜像 | Linux 中国

使用 mkosi 构建 RHEL 和 RHEL UBI 镜像 | Linux 中国

科技
 
导读:mkosi 是一个轻量级工具,用于从发行版软件包构建镜像。                           
本文字数:9035,阅读时长大约:11分钟

mkosi 是一个轻量级工具,用于从发行版软件包构建镜像。本文介绍如何使用 mkosi 从 RHEL 和 RHEL 通用基础镜像uapi-group.org(Universal Base Image)(UBI)的软件包构建镜像。RHEL UBI 是 RHEL 的一个子集,可以在没有订阅的情况下免费使用。

mkosi 特性

mkosi 支持一些输出格式,但最重要的是 可发现磁盘镜像uapi-group.org(Discoverable Disk Images)(DDI)。同一个 DDI 可用于引导容器、或运行在虚拟机、抑或是复制到 U 盘以引导真实物理机,然后从 U 盘复制到磁盘以引导系统。该镜像具有标准化的布局和描述其用途的元数据。

mkosi 依赖其他工具来完成大部分工作:使用 systemd-repart 在磁盘镜像上创建分区,使用 mkfs.btrfs / mkfs.ext4 / mkfs.xfs 等创建文件系统,并使用 dnf / apt / pacman / zypper 下载和解压包。

mkosi 支持一系列发行版:Debian 和 Ubuntu、Arch Linux、openSUSE,当然还包括 Fedora、CentOS Stream 及其衍生版本,以及最近的 RHEL UBI 和 RHEL 。由于实际的“重活”是由其他工具完成的,mkosi 可以进行交叉构建。这意味着可以使用一个发行版构建各种其他发行版的镜像。唯一的要求是主机上安装了相应的工具。Fedora 有原生的 aptpacman 和 zypper,因此它为使用 mkosi 构建任何其他发行版提供了良好的基础。

它还有一些有趣的功能:镜像可以由非特权用户创建,或者在没有设备文件的容器中创建,特别是没有对回环设备的访问权限。它还可以在没有特权的情况下将这些镜像启动为虚拟机(使用 qemu)。

配置是声明性的,非常容易创建。使用 systemd-repart 创建磁盘分区,并使用 repart.d 配置文件定义应该如何完成此操作。

有关更多详细信息,请参见 Daan DeMeyer 在 All Systems Go 大会上的两个演讲:《systemd-repart: Building Discoverable Disk Imagesmedia.ccc.de》 和 《mkosi: Building Bespoke Operating System Imagesmedia.ccc.de》。

项目目标

mkosi 的一个目标是允许对软件项目进行针对不同发行版的测试。它将为一个发行版创建一个镜像(使用该发行版的软件包),然后将软件项目编译并安装到该镜像中,插入不属于软件包的额外文件。但是,首个阶段,即从软件包创建镜像的过程,本身就是有用的。这是我们将首先展示的内容。

我们 [1] 最近添加了对 RHEL 和 RHEL UBI 的支持。让我们从 RHEL UBI 开始,利用发行版软件包创建镜像。

请注意,下面的示例要求 mkosi 19,而且不适用于更早的版本。

带有 Shell 的基本 RHEL UBI 镜像

  1. $ mkdir -p mkosi.cache
  2. $ mkosi \
  3. -d rhel-ubi \
  4. -t directory \
  5. -p bash,coreutils,util-linux,systemd,rpm \
  6. --autologin

上面的命令指定了发行版 rhel-ubi,输出格式 directory,并请求安装软件包 bashcoreutils、…、rpmrpm 通常不需要放到镜像内部,但在这里用于内省会很有用。我们还启用了以 root 用户自动登录。

在启动构建之前,我们创建了缓存目录 mkosi.cache。当存在缓存目录时,mkosi 会自动使用它来持久化下载的 RPM 包。这将使相同软件包集合的后续调用速度更快。

然后,我们可以使用 systemd-nspawn 将此镜像作为容器启动:

  1. $ sudo mkosi \
  2. -d rhel-ubi \
  3. -t directory \
  4. boot
  1. systemd 252-14.el9_2.3 running in system mode (+PAM +AUDIT +SELINUX -APPARMOR +IMA +SMACK +SECCOMP +GCRYPT +GNUTLS +OPENSSL +ACL +BLKID +CURL +ELFUTILS -FIDO2 +IDN2 -IDN -IPTC +KMOD +LIBCRYPTSETUP +LIBFDISK +PCRE2 -PWQUALITY +P11KIT -QRENCODE +TPM2 +BZIP2 +LZ4 +XZ +ZLIB +ZSTD -BPF_FRAMEWORK +XKBCOMMON +UTMP +SYSVINIT default-hierarchy=unified)
  2. Detected virtualization systemd-nspawn.
  3. Detected architecture x86-64.
  4. Detected first boot.
  5. Red Hat Enterprise Linux 9.2 (Plow)
  6. ...
  7. [ OK ] Created slice Slice /system/getty.
  8. [ OK ] Created slice Slice /system/modprobe.
  9. [ OK ] Created slice User and Session Slice.
  10. ...
  11. [ OK ] Started User Login Management.
  12. [ OK ] Reached target Multi-User System.
  13. Red Hat Enterprise Linux 9.2 (Plow)
  14. Kernel 6.5.6-300.fc39.x86_64 on an x86_64
  15. image login: root (automatic login)
  16. [root@image ~]# rpm -q rpm systemd
  17. rpm-4.16.1.3-22.el9.x86_64
  18. systemd-252-14.el9_2.3.x86_64

正如前面提到的,此镜像可以用于启动虚拟机。但在此设置下,这是不可能的 —— 我们的镜像没有内核。事实上,RHEL UBI 根本不提供内核,因此我们无法使用它进行引导(无论是在虚拟机上还是在裸机上)。

创建镜像

我一开始说是要创建镜像,但到目前为止我们只有一个目录。让我们开始实际创建一个镜像:

  1. $ mkosi \
  2. -d rhel-ubi \
  3. -t disk \
  4. -p bash,coreutils,util-linux,systemd,rpm \
  5. --autologin

这将生成 image.raw,一个带有 GPT 分区表和单个根分区(用于本机架构)的磁盘镜像。

  1. $ sudo systemd-dissect image.raw
  2. Name: image.raw
  3. Size: 301.0M
  4. Sec. Size: 512
  5. Arch.: x86-64
  6. Image UUID: dcbd6499-409e-4b62-b251-e0dd15e446d5
  7. OS Release: NAME=Red Hat Enterprise Linux
  8. VERSION=9.2 (Plow)
  9. ID=rhel
  10. ID_LIKE=fedora
  11. VERSION_ID=9.2
  12. PLATFORM_ID=platform:el9
  13. PRETTY_NAME=Red Hat Enterprise Linux 9.2 (Plow)
  14. ANSI_COLOR=0;31
  15. LOGO=fedora-logo-icon
  16. CPE_NAME=cpe:/o:redhat:enterprise_linux:9::baseos
  17. HOME_URL=https://www.redhat.com/
  18. DOCUMENTATION_URL=https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/9
  19. BUG_REPORT_URL=https://bugzilla.redhat.com/
  20. REDHAT_BUGZILLA_PRODUCT=Red Hat Enterprise Linux 9
  21. REDHAT_BUGZILLA_PRODUCT_VERSION=9.2
  22. REDHAT_SUPPORT_PRODUCT=Red Hat Enterprise Linux
  23. REDHAT_SUPPORT_PRODUCT_VERSION=9.2
  24. Use As: bootable system for UEFI
  25. bootable system for container
  26. portable service
  27. initrd
  28. sysext extension for system
  29. sysext extension for initrd
  30. sysext extension for portable service
  31. RW DESIGNATOR PARTITION UUID PARTITION LABEL FSTYPE ARCHITECTURE VERITY GROWFS NODE PARTNO
  32. rw root 1236e211-4729-4561-a6fc-9ef8f18b828f root-x86-64 xfs x86-64 no yes /dev/loop0p1 1

好的,我们现在有一个镜像,镜像中包含了一些来自 RHEL UBI 软件包的内容。我们如何在其上加点我们自己的东西呢?

使用自己的文件扩展镜像

有几种方法可以扩展镜像,包括从头开始编译某些东西。但在那之前,让我们做一些更简单的事情,将一个现成的文件系统注入到镜像中:

  1. $ mkdir -p mkosi.extra/srv/www/content
  2. $ cat >mkosi.extra/srv/www/content/index.html <<'EOF'
  3. <h1>Hello, World!</h1>
  4. EOF

现在,该镜像将包含 /srv/www/content/index.html

这种方法用于注入额外的配置或简单的程序。

从源代码构建

现在让我们过一遍完整流程,从源代码构建一些东西。例如,一个简单的 Meson 项目,有一个单独的 C 文件:

  1. $ cat >hello.c <<'EOF'
  2. #include <stdio.h>
  3. int main(int argc, char **argv) {
  4. char buf[1024];
  5. FILE *f = fopen("/srv/www/content/index.html", "re");
  6. size_t n = fread(buf, 1, sizeof buf, f);
  7. fwrite(buf, 1, n, stdout);
  8. fclose(f);
  9. return 0;
  10. }
  11. EOF
  12. $ cat >meson.build <<'EOF'
  13. project('hello', 'c')
  14. executable('hello', 'hello.c',
  15. install: true)
  16. EOF
  1. $ cat >mkosi.build <<'EOF'
  2. set -ex
  3. mkosi-as-caller rm -rf "$BUILDDIR/build"
  4. mkosi-as-caller meson setup "$BUILDDIR/build" "$SRCDIR"
  5. mkosi-as-caller meson compile -C "$BUILDDIR/build"
  6. meson install -C "$BUILDDIR/build" --no-rebuild
  7. EOF
  8. $ chmod +x mkosi.build

总结一下:我们有一些源代码(hello.c),一个构建系统配置文件(meson.build),以及一个由 mkosi 调用的胶水脚本(mkosi.build)。对于实际的项目,也会有相同的元素,只是更加复杂。

这个脚本需要一些解释。mkosi 在创建镜像时使用用户命名空间。这允许包管理器(例如 dnf)安装由不同用户拥有的文件,即使它是由一个普通非特权用户调用的。我们使用 mkosi-as-caller 切换回调用者以进行编译。这样,在 $BUILDDIR 下编译期间创建的文件将由调用者拥有。

现在让我们使用我们的程序构建镜像。与之前的调用相比,我们需要额外的软件包:mesongcc。由于我们现在有了构建脚本,mkosi 将执行两个构建阶段:首先创建一个构建镜像,并在其中调用构建脚本,将安装产物存储在一个临时目录中,然后构建最终镜像,并将安装产物注入其中。(mkosi 设置 $DESTDIRmeson install 自动使用 $DESTDIR,因此并不需要我们明确指定。)

  1. $ mkosi \
  2. -d rhel-ubi \
  3. -t disk \
  4. -p bash,coreutils,util-linux,systemd,rpm \
  5. --autologin \
  6. --build-package=meson,gcc \
  7. --build-dir=mkosi.builddir \
  8. --build-script=mkosi.build \
  9. -f

此时,我们有了带有自定义载荷的镜像 image.raw。我们可以启动我们新创建的可执行文件作为 shell 命令:

  1. $ sudo mkosi -d rhel-ubi -t directory shell hello
  2. <h1>Hello, World!</h1>

获取 RHEL 的开发者订阅

RHEL UBI 主要用作容器构建的基础层。它提供了有限的软件包(约 1500 个)。现在让我们切换到完整的 RHEL 安装。

获取 RHEL 的最简单方法是使用 开发者许可证developers.redhat.com。它提供了权限注册 16 个运行 RHEL 的物理或虚拟节点,并提供自助式支持。

首先,创建一个账户developers.redhat.com。然后,转到 管理页面access.redhat.com 并确保启用了“用于 Red Hat 订阅管理的简化内容访问”。接下来,创建一个新的激活密钥access.redhat.com,选择 “Red Hat 个人开发者订阅”。记下显示的组织 ID。在下面,我们将使用密钥名称和组织 ID 分别表示为 $KEY_NAME 和 $ORGANIZATION_ID

现在,我们准备使用 RHEL 内容:

  1. $ sudo dnf install subscription-manager
  2. $ sudo subscription-manager register \
  3. --org $ORGANIZATION_ID --activationkey $KEY_NAME

使用 RHEL 构建镜像

在之前的示例中,我们通过参数开关指定了所有配置。这对于快速开发很友好,但可能在情况复杂时变得难以处理。RHEL 是一个严肃的发行版,所以让我们改为使用配置文件:

  1. $ cat >mkosi.conf <<'EOF'
  2. [Output]
  3. Format=directory
  4. Output=rhel-directory
  5. [Distribution]
  6. Distribution=rhel
  7. [Content]
  8. Packages=
  9. bash
  10. coreutils
  11. util-linux
  12. systemd
  13. systemd-boot
  14. systemd-udev
  15. kernel-core
  16. Bootable=yes
  17. Bootloader=uki
  18. Autologin=yes
  19. WithDocs=no
  20. EOF

首先,让我们检查一下一切是否正常:

  1. $ mkosi summary

现在让我们构建镜像(呃,或者说,目录):

  1. $ mkosi build
  2. $ mkosi qemu
  1. Welcome to Red Hat Enterprise Linux 9.2 (Plow)!
  2. [ OK ] Created slice Slice /system/modprobe.
  3. [ OK ] Reached target Initrd Root Device.
  4. [ OK ] Reached target Initrd /usr File System.
  5. [ OK ] Reached target Local Integrity Protected Volumes.
  6. [ OK ] Reached target Local File Systems.
  7. [ OK ] Reached target Path Units.
  8. [ OK ] Reached target Remote Encrypted Volumes.
  9. [ OK ] Reached target Remote Verity Protected Volumes.
  10. [ OK ] Reached target Slice Units.
  11. [ OK ] Reached target Swaps.
  12. ...
  13. [ OK ] Listening on Journal Socket.
  14. [ OK ] Listening on udev Control Socket.
  15. [ OK ] Listening on udev Kernel Socket.
  16. ...
  17. Red Hat Enterprise Linux 9.2 (Plow)
  18. Kernel 5.14.0-284.30.1.el9_2.x86_64 on an x86_64
  19. localhost login: root (automatic login)
  20. [root@localhost ~]#

很好,我们将“镜像”构建为一个带有文件系统树的目录,并在虚拟机中引导了它。

在引导的虚拟机中,findmnt / 显示根文件系统是 virtiofs。这是一个虚拟文件系统,将主机的目录暴露给客户机。我们其实也可以构建一个更传统的镜像,其中包含文件系统和文件内的分区表,但“目录 + virtiofs” 对于开发来说更快且更友好。

我们刚刚引导的镜像未注册。要允许从镜像“内部”下载更新,我们必须将 yum 、subscription-manager 和 NetworkManager 添加到软件包列表,并在下载任何更新之前以与上述相同的方式调用 subscription-manager。在这之后,我们在基本仓库中就有大约 4500 个软件包可用,并且还有一些包含更多专业软件包的额外仓库。

最后

今天就是这些了。如果您有问题,可以在 Matrix 上找到我们,地址为 #mkosi:matrix.orgmatrix.to,或者在 systemd 邮件列表lists.freedesktop.org 上找到我们。

(题图:MJ/a6e60316-ed03-4e23-b8b4-22332a0f5bfa)


1. Daan DeMeyer、Lukáš Nykrýn、Michal Sekletár、Zbigiew Jędrzejewski-Szmek ↩︎

via: https://fedoramagazine.org/create-images-directly-from-rhel-and-rhel-ubi-package-using-mkosi/

作者:Zbigniew Jędrzejewski-Szmek 选题:lujun9972 译者:GlassFoxowo 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

LCTT 译者 :GlassFoxowo
🌟
翻译: 1.0 篇
|
贡献: 2 天
2023-11-24
2023-11-25
https://linux.cn/lctt/GlassFoxowo-Dev
欢迎遵照 CC-BY-SA 协议规定转载,
如需转载,请在文章下留言 “转载:公众号名称”,
我们将为您添加白名单,授权“转载文章时可以修改”。


微信扫码关注该文公众号作者

戳这里提交新闻线索和高质量文章给我们。
相关阅读
Linux 内核动手编译实用指南 | Linux 中国Ubuntu 与 Kubuntu:哪一个更适合你? | Linux 中国游纽芬兰散记:奇特的绿角地质景观终端基础:Linux 终端中的目录切换 | Linux 中国硬核观察 #1174 OpenELA 发布用于构建 RHEL 8/9 衍生版的源代码Zorin OS 17 正在重新定义 Linux 发行版的视觉体验 | Linux 中国68 奔赴南疆AlmaLinux 正开发成为不包含 RHEL 代码但兼容 RHEL 的发行版本PeerTube 发布第 6 版,获得比 YouTube 更好的功能 | Linux 中国Bazzite:专为 Steam Deck 和 PC 上的 Linux 游戏打造的发行版 | Linux 中国使用 dialog 和 jq 在 Linux 上编写高效终端 TUI | Linux 中国使用 Btrfs 快照方便升级 Fedora Linux 且易于回退 | Linux 中国原来我们一直都活在梦中在 Arch Linux 上安装 Brave | Linux 中国备受欢迎的数字音频工作站 Studio One 新增了对 Linux 的支持 | Linux 中国可外加磁场的无限时连续300mK极低温测量!mK级多功能超稳定极低温系统顺利落户两著名实验室Wolfi:改进云软件供应链的 Linux “非”发行版 | Linux 中国Linux 爱好者线下沙龙:LLUG 2023·相聚成都 | Linux 中国Vojtux:针对视力障碍用户改造 Linux | Linux 中国任务中心:一款流畅的 Linux 系统监控应用 | Linux 中国修复 Arch Linux 中的 “Bash: man command not found” 错误 | Linux 中国Linux 黑话解释:Linux 中的 Super 键是什么? | Linux 中国Linux 爱好者线下沙龙:LLUG 2023·蓉城热辣相聚 | Linux 中国首款 Linux 游戏本?!Tuxedo 推出 Linux 游戏本 Sirius 16Linux 游戏的下一个秘密武器:Bottles Next | Linux 中国梦境记录在 Arch Linux 上安装和使用 Yay | Linux 中国Overskride:刚刚出现的一款有趣的 Linux 蓝牙应用! | Linux 中国Linus Torvalds:Linux 内核中的 Rust、AI 和疲劳的维护者 | Linux 中国黑鹰博物馆Blackhawk museum (下)Canonical 推出超小型容器镜像 Chiselled UbuntuLinux 中的 ls 命令使用教程 | Linux 中国AlmaLinux不使用 “红帽代码”,如何保持兼容RHELLinux Mint 21.2 Edge:为更新的硬件提供支持 | Linux 中国如何制作一个 Linux Mint 立付 USB | Linux 中国
logo
联系我们隐私协议©2024 redian.news
Redian新闻
Redian.news刊载任何文章,不代表同意其说法或描述,仅为提供更多信息,也不构成任何建议。文章信息的合法性及真实性由其作者负责,与Redian.news及其运营公司无关。欢迎投稿,如发现稿件侵权,或作者不愿在本网发表文章,请版权拥有者通知本网处理。