By xzllll

openSUSE MicroOS | 入门指南之 transactional-update

指南 | Guides 2025年8月15日

1. First | 序

书接上回

openSUSE MicroOS | (基于Cockpit)虚拟化安装指南
1. First | 序 本篇简单记录 openSUSE MicroOS 安装记录 openSUSE MicroOS 是一款专门针对容器化工作负载打造的超可靠、轻量级的操作系统 是不可变的 Real-Time OS 1.1. openSUSE MicroOS Features | 特征 * 只读根文件系统,防止对操作系统的意外修改 * Transactional Updates 技术利用 Btrfs 快照在不干扰正在运行的系统的情况下应用软件包更新 * health-checker 在更新后验证操作系统是否正常运行,若出现问题会自动回滚 * cloud-init 用于云环境首次启动时的系统初始配置(包括 OpenStack) * Combustion 和 Ignition 用于其他所有镜像在首次启动时的系统初始配置 * 设计与现有的 openSUSE 或 SUSE Linux Enterprise 环境无缝衔接 * 提供 Podman 容器运行时 * 滚动发行版:每个新的

此次学习管理 openSUSE MicroOS (以下统称 Micro) 的重要工具 transactional-update

1.1. OS Version

2. transactional-update

2.1. What is transactional-update | 什么是transactional-update

以下内容直接 Copy 至官方文档

为了保持基础操作系统的稳定性和一致性,SUSE Linux Micro 使用只读的根文件系统。因此,您无法直接对根文件系统执行更改操作,例如使用 zypper 命令。但是,SUSE Linux Micro 引入了事务更新功能,可让您对根文件系统应用一项或多项更改。

transactional-update 提供了一个应用程序和库,用于以事务方式更新 Linux 操作系统。也就是说,更新将在后台执行,同时系统仍保持正常运行。只有当更新整体成功时,系统才会启动到新的快照。

transactional-update 的默认行为是在每次更改发生后基于当前根文件系统创建新快照。要应用更改,就需要重引导主机。在不重引导的情况下,您无法多次运行 transactional-update 命令将其他更改添加到快照。此操作将创建独立的快照,其中不包含先前快照中的更改。

👇
补充说明
  1. zypper & transactional-update

    zypper 和 transactional-update 命令并不冲突

    以下子命令因为直接操作尝试修改根文件系统,需要添加、删除或更改 /usr 等目录下的文件,并更新系统的 RPM 数据库,这在只读的事务性系统中是不被允许的

    • zypper install
    • zypper remove
    • zypper dup
    • ......

    但以下命令只读操作 (Read-Only Operations)依然可以运行

    • zypper search
    • zypper info
    • ......

    命令类型 示例命令 是否需要 transactional-update? 原因
    写入/更改操作 install, remove, dup, addrepo 是 会修改只读的根文件系统
    只读操作 search, info, list-repos (lr), what-provides (wp) 否 仅查询信息,不修改系统

    也就是说 zypper & transactional-update 命令相辅相成

    事实上 transactional-update 也并不包含一些只读命令操作

    Package Commands:
    Defaults: (i) interactive command; (n) non-interactive command
    dist-upgrade, dup          Call 'zypper dup' (n)
    update, up                 Call 'zypper up' (n)
    patch                      Call 'zypper patch' (n)
    migration ...              Updates systems registered via SCC / SMT (i)
    pkg install|in ...         Install individual packages (i)
    pkg remove|rm ...          Remove individual packages (i)
    pkg update|up ...          Updates individual packages (i)
    register ...               Register system via SUSEConnect (implies -d)
    EXPERIMENTAL:
    apply-oci ...              Applies system layout based on OCI container (i)
    
  2. 何为原子性?

    原子(Atom)这个词源于希腊语,意为"不可分割"。在计算机科学中,原子性意味着一个操作是一个不可分割的单元,它只有两种最终状态:

    • 完全成功 (All):操作中的每一个步骤都成功完成。

    • 完全失败 (Nothing):如果操作中任何一个步骤失败,整个操作都将回滚,系统会恢复到操作开始之前的原始状态,就像什么都没发生过一样。

    绝对不会存在“部分成功”的中间状态。

  3. 事务性更新和传统更新之间的对比关系

    特性 事务性更新 (原子性) 传统更新 (非原子性)
    更新过程 在一个隔离的新快照上操作,不影响当前系统 直接在当前运行的系统上修改文件
    成功结果 系统重启后,整体切换到一个全新的、100%更新成功的状态 所有软件包被逐一更新
    失败结果 新快照被丢弃,系统完全回滚到更新前的状态,无任何影响 系统停留在半更新的损坏状态,极不稳定
    系统可靠性 极高。更新要么 100% 成功,要么 0% 影响 较低。更新过程中的任何中断都可能导致系统损坏

2.2. transactional-update 的工作原理

以下内容直接 Copy 至官方文档

每次调用 transactional-update 命令来更改系统时(无论是安装软件包、执行更新还是应用补丁),系统都会执行以下操作:

  1. 基于当前的根文件系统或您指定的快照创建新的读写快照。

  2. 应用所有更改(执行更新、修补操作或安装软件包)。

  3. 将快照切换回只读模式。

  4. 如果所有更改都成功应用,则将新的根文件系统快照设为默认快照。

  5. 重引导之后,系统引导进入新的快照。

2.3. transactional-update 命令的用法

transactional-update 以原子的方式应用或去除更新

只有所有更新都能成功安装,才会应用此更新

transactional-update 命令的语法如下:

transactional-update [option] [general_command] [package_command] standalone_command

👇
详细参数和帮助如下所示

    Syntax: transactional-update [option...] [general-command...] [package-command]
        transactional-update [option...] standalone-command

    Applies package updates to a new snapshot without touching the running
    system.

    General Commands:
    apply                      Switch into default snapshot without reboot
    cleanup                    Mark unused snapshots for snapper removal
    grub.cfg                   Regenerate grub.cfg
    bootloader                 Reinstall the bootloader
    initrd                     Regenerate initrd
    kdump                      Regenerate kdump initrd
    shell                      Open rw shell in new snapshot before exiting
    reboot                     Reboot after update
    run <cmd>                  Run a command in a new snapshot
    setup-fips                 Install and enable FIPS pattern package
    setup-kdump [--crashkernel=<low>[,<high>]]  Configure and enable kdump
    setup-selinux              Install targeted SELinux policy and enable it

    Package Commands:
    Defaults: (i) interactive command; (n) non-interactive command
    dist-upgrade, dup          Call 'zypper dup' (n)
    update, up                 Call 'zypper up' (n)
    patch                      Call 'zypper patch' (n)
    migration ...              Updates systems registered via SCC / SMT (i)
    pkg install|in ...         Install individual packages (i)
    pkg remove|rm ...          Remove individual packages (i)
    pkg update|up ...          Updates individual packages (i)
    register ...               Register system via SUSEConnect (implies -d)
    EXPERIMENTAL:
    apply-oci ...              Applies system layout based on OCI container (i)

    Standalone Commands:
    rollback [<number>]        Set the current or given snapshot as default snapshot
    rollback last              Set the last working snapshot as default snapshot

    Options:
    --interactive, -i          Use interactive mode for package command
    --non-interactive, -n      Use non-interactive mode for package command
    --continue [<number>], -c  Use latest or given snapshot as base
    --no-selfupdate            Skip checking for newer version
    --drop-if-no-change, -d    Drop the snapshot if there is no change
    --quiet                    Don't print warnings and infos to stdout
    --help, -h                 Display this help and exit
    --version                  Display version and exit

2.4. transactional-update 在不重引导的情况下应用多项更改

2.4.1. 前言

transactional-update 默认行为是在每次更改发生后基于当前根文件系统创建新快照,然后重引导以应用更改

如果要在不重引导的情况下对根文件系统进行多项更改并且不太明白transactional-update的情况下这样会带来一些问题

例如:

  1. 你使用 transactional-update pkg install ncdu 安装 ncdu 但并未重启 (此时系统根据当前根文件系统创建了快照A)

  2. 10 min 后你又使用 transactional-update pkg install htop 安装 htop (此时系统又根据当前根文件系统创建了快照B)

  3. 此时你 reboot 后惊奇的发现 ncdu 不存在,原因就在于 transactional-update 默认行为是在每次更改发生后基于当前根文件系统创建新快照

  4. 并且 Micro 还会贴心的告知你

    WARNING: This snapshot has been created from a different base (10)
         than the previous default snapshot (11) and does not
         contain the changes from the latter.
    
    New default snapshot is #12 (/.snapshots/12/snapshot).
    transactional-update finished
    

目前 Micro 给了三种解决方案分别为

  1. transactional-update --continue
  2. transactional-update run
  3. transactional-update shell

我们一一来看

2.4.2. transactional-update --continue

这种方式很像平常用到的 >> 追加

即: 将当前更改追加到 上一个未生效的快照基础上 继续应用新的更改,并生成一个“更新版”的快照。这个过程可以一直持续下去。

仍按照之前的例子举例:

  1. 你使用 transactional-update pkg install ncdu 安装 ncdu 但并未重启 (此时系统根据当前根文件系统创建了快照A)

  2. 10 min 后你又使用 transactional-update --continue pkg install htop 安装 htop (此时系统会以快照A为基础创建了B)

  3. 此时你 reboot 后惊奇的发现 更新追加成功

所有这些更改都被合并到了最后一个快照(快照 B)中。只需要在所有操作完成后重引导一次,系统就会切换到这个包含了所有更改的最终快照。

2.4.3. transactional-update run

这种方法可以理解为 一次性运行一个脚本

  • 工作方式:它允许你在一个单独的事务性会话中,执行一条或多条预先定义好的命令。如果您想执行多条命令,需要用一种方式把它们“串”起来,最常见的就是通过 bash -c '...' 的方式。

  • 关键点:

    • 这是一个非交互式的方法。您把要执行的命令一次性告诉它,然后它会自动完成。

    • 所有在 run 命令中执行的操作,都会被记录到日志文件 /var/log/transactional-update.log 中,方便你排查问题。

    • 它和 shell 命令有同样的限制(下面会讲)。

适用场景:非常适合自动化脚本。当您有一系列明确的命令需要执行时,可以把它们写成一个单行命令,交给 transactional-update run 来执行。

2.4.4. transactional-update shell

这种方法可以理解为 进入一个临时的可写环境

当你输入 transactional-update shell 后,Micro会为你打开一个特殊的、临时的 Shell(命令行界面)。在这个 Shell 里,原本只读的根文件系统变成了可写状态

此时你可以对系统进行输入任何 Linux 命令来对文件系统进行更改。

更改完成使用 exit 退出时,系统会将你在此 shell 环境中做的一切更改打包为一个快照,你只需reboot 即可应用

⚠️
重要

同时它有一些限制

  1. 不记录命令:你在这个 Shell 里输入的具体命令不会被记入日志。
  2. 无法控制服务:不能使用 systemd 命令(如 systemctl start/stop)来管理服务。
  3. /var 分区不可修改:因为 /var 是独立挂载且可写的,所以它不属于事务性更新的一部分。

2.4.5. 总结

特性 transactional-update --continue transactional-update run transactional-update shell
交互方式 非交互式(每次一个命令) 非交互式(一次性执行多命令) 交互式
操作过程 分步、多次执行命令 一次性提交所有命令 进入临时环境,自由操作
快照数量 每一次 --continue 都会生成新快照 所有操作合并在一个新快照中 所有操作合并在一个新快照中
命令日志 记录每次 transactional-update 命令 记录 run 中执行的所有命令 不记录在 Shell 中输入的命令
适用场景 分批次、不连续的更改 自动化脚本、执行预设的命令序列 复杂的手动操作、需要探索和调试的更改

2.5. soft-reboot 配置

2.5.1 What is soft-reboot ? | 什么是 soft-reboot

首先来了解一下关于重启的几个级别

  1. 硬件重引导 (Hardware Reboot):

    • 这是我们最熟悉的重启方式,相当于按下电脑的重启按钮。
    • 它会完全关闭再启动整个计算机硬件,重新加载 BIOS/UEFI,引导加载程序 (GRUB2),然后加载操作系统内核,最后启动所有系统服务和程序。
    • 特点:最彻底,但也是最慢的。
  2. 内核重引导 (kexec):

    • 这是一种更快的重启方式。它跳过了硬件自检和 GRUB2 加载的步骤。
    • 它直接在当前运行的内核的内存中加载一个新的内核,然后无缝切换过去。
    • 特点:比硬件重启快很多,适用于只需要更新内核(比如打了安全补丁)而不需要重启硬件的场景。
  3. 用户空间重引导 (soft-reboot):

    • 这是最快、最轻量级的重启方式。
    • 它保持硬件和内核持续运行,完全不重启它们。
    • 它只重启操作系统的“用户空间”部分,也就是在内核之上运行的所有服务和应用程序(例如 systemd 服务管理器、dbus 消息总线、桌面环境等)。
    • 特点:速度极快,几乎是瞬时的。适用于那些只影响用户空间程序的更新。

重引导类型 重启范围 速度 适用更新场景
硬件重引导 (reboot) 硬件、内核、用户空间 最慢 固件、部分底层驱动更新
内核重引导 (kexec) 内核、用户空间 较快 内核 (kernel) 包更新
用户空间重引导 (soft-reboot) 仅用户空间的服务与程序 最快 核心库 (如 glibc)、系统服务 (如 dbus) 更新

😶
那么如何让 Soft-Reboot 跑起来?

为了让 soft-reboot 工作,需要做两件事:

  1. 打开总开关:在 /etc/tukit.conf.d/soft-reboot.conf 中允许 soft-reboot。

  2. 定义规则:在 /etc/zypp/zypp-boot-plugin.conf 中,将那些适合 soft-reboot 的软件包(如 glibc)添加到 soft-reboot 列表中。

当您下次运行 transactional-update 更新了一个被标记为 soft-reboot 的包后,系统将执行一次极快的用户空间重启,而不是漫长的硬件重启,从而大大节省您的时间

接下来一一说明

2.5.2. 启用/禁用 soft-reboot

如果需要启用 Soft-Reboot, 请执行下列步骤:

  1. 创建目录 /etc/tukit.conf.d/

    sudo mkdir /etc/tukit.conf.d/
    
  2. 创建包含以下内容的文件 /etc/tukit.conf.d/soft-reboot.conf

    REBOOT_ALLOW_SOFT_REBOOT=true
    

    例如:

    sudo echo "REBOOT_ALLOW_SOFT_REBOOT=true" > /etc/tukit.conf.d/soft-reboot.conf
    

禁用 Soft-Reboot 只需将文件中的 REBOOT_ALLOW_SOFT_REBOOT=true 修改为 REBOOT_ALLOW_SOFT_REBOOT=false

2.5.3. soft-reboot 的具体配置 (规则集)

这部分内容是用来定义什么更新应该触发哪种重启的详细规则。

首先我们需要将 /usr/etc/zypp/zypp-boot-plugin.conf 文件复制到 /etc/zypp/zypp-boot-plugin.conf

cp /usr/etc/zypp/zypp-boot-plugin.conf /etc/zypp/zypp-boot-plugin.conf

/etc/zypp/zypp-boot-plugin.conf 可写且不会被更新覆盖且优先级更高

/etc/zypp/zypp-boot-plugin.conf 文件中的 [main] 部分下,有三个重引导选项:

reboot
此处用于指定在更改时需要重引导硬件的软件包。

kexec
提供更改时需要重引导内核的软件包列表。不过,这些更改不会要求重引导硬件,也不会触发 GRUB2。

soft-reboot
指定更改时只需要重引导用户空间的软件包。


有以下两种配置方式

  1. 用逗号分隔软件包名称

    soft-reboot = glibc, dbus-broker
    
  2. 使用 provides 语句

    soft-reboot = provides: dbus
    

    它不关心具体的软件包叫什么名字,而是关心这个包提供了什么功能。
    这个例子意味着,任何提供了 dbus 功能的包(无论是 dbus-broker 还是其他实现)被更新时,都适用 soft-reboot 规则。

👩‍🏫
关于 provides

provides 是 RPM 包管理系统(SUSE, openSUSE, Fedora, CentOS 等都在使用)的一个基础特性。

它允许一个软件包声明自己能扮演某个角色或提供某种虚拟能力。

在 Micro 中,我们可以使用 zypper info --provides 来查看某个软件包是否声明其 provides

示例如下 👇

2.5.4. 如何触发 soft-reboot

2.5.4.1. systemctl soft-reboot

系统管理员可以使用以下命令立即触发软重启

systemctl soft-reboot 

2.5.4.2. transactional-update reboot

实际上 transactional-update reboot 无法强制执行软重启操作

其操作类似于 预约重启

当你运行 transactional-update reboot 在经过必要的动作后它会将重启任务交给 rebootmgr

接下来 rebootmgr 会寻找它认为合适的时机完成 soft-reboot

transactional-update reboot 回显如下 👇


Checking for newer version.
transactional-update 5.0.7 started
Options: reboot
Separate /var detected.
transactional-update finished
2025-08-15 16:42:57 tukit 5.0.7 started
2025-08-15 16:42:57 Options: reboot auto
2025-08-15 16:42:57 Requesting reboot using rebootmgr (soft-reboot required).
2025-08-15 16:42:57 Found plugin "/usr/lib/tukit/plugins/10-sdbootutil.tukit"
2025-08-15 16:42:57 Transaction completed

👩‍🏫
那么什么时候是 rebootmgr 认为的合适时间呢?

可以使用以下命令查询

rebootmgrctl status

回显如下 👇

Status: Soft-reboot requested, waiting for maintenance window
Scheduled for: Sat 2025-08-16 04:29:43 CST

rebootmgrctl 命令补充如下 👇

Usage:
        rebootmgrctl --help|--version
        rebootmgrctl is-active [--quiet]
        rebootmgrctl reboot [now]
        rebootmgrctl soft-reboot [now]
        rebootmgrctl cancel
        rebootmgrctl status [--full|--quiet]
        rebootmgrctl set-strategy best-effort|maint-window|instantly|off|on
        rebootmgrctl get-strategy
        rebootmgrctl set-window <time> <duration>
        rebootmgrctl get-window
        rebootmgrctl dump-config

rebootmgr 可选的重启策略 👇

  • instantly- 信号到达时立即重启。
  • maint-window- 仅在指定的维护时段内重启。如果未指定时段,则立即重启。
  • best-effort- 这是默认值。如果指定了维护时段,请使用maint-window。如果未指定维护时段,则立即重启(instantly)。
  • off-rebootmgr 继续运行,但忽略所有重启信号。将策略设置为off不会清除维护窗口。如果再次启用 Rebootmgr,它将继续使用之前指定的维护窗口。
👩‍🏫
如何配置rebootmgr?

rebootmgr 的配置文件默认路径为 /etc/rebootmgr/rebootmgr.conf.d/

路径中存在一个默认的 50-strategy.conf

你可以自定义 40-strategy.conf 文件

内容如下所示

[rebootmgr]
strategy=maint-window
window-start=05:00
window-duration=1h30m

之后别忘了重启 rebootmgr 服务

2.5.5. soft-reboot 都做了什么?

  1. 关闭所有正在运行的服务。

  2. 切换到一个新的根文件系统 (这是与 transactional-update 结合的关键!)。

  3. 重新执行 systemd 主进程。

  4. 重新启动所有服务。

3. transactional-update 实践

第二节介绍了 Transactional Update 某些特性

那么该如何安全且优雅的在 MicroOS 上安装/更新软件包呢

以安装 ncdu 软件包为例做个演示

3.1. soft-reboot 之前

3.2. soft-reboot 之后

3.3. 总结

在以上安装 ncdu 软件包时,系统做了哪些工作?

我们一一分析

  1. 首先我们得知目前环境

    • ncdu 包未安装
    • rebootmgrctl 重启策略为 instantly
    • /run/reboot-needed 文件未生成
  2. 安装 ncdu 软件包后

    • 新的快照生成
    • 系统调用 zypp-boot-plugin 插件评估包安装/更新后是否需要重启以及重启的方式
    • 插件首先查找管理员自定义的 /etc/zypp/zypp-boot-plugin.conf 文件,若无果会采纳软件包开发者通过 installhint 提供的分布式建议
    • zypp-boot-plugin 得到的结果为需要重启,重启方式为 soft-reboot,并将结果写入 /run/reboot-needed 文件
  3. 运行 transactional-update reboot 后

    • transactional-update 进行初步检查后调用了后端工具 tukit
    • tukit 接管工作,根据zypp-boot-plugin回馈的结果向 rebootmgr 服务发送了一个请求,这个请求的内容是:“系统有待处理的更新,根据分析需要进行一次软重启 (soft-reboot),请你在合适的时候处理一下。”
    • rebootmgr 收到请求,检查当前系统配置的重启策略
    • 当前系统的重启策略为 instantly ,即收到信号后立即进行重启,本次重启类型为软重启(soft-reboot)
    • 立刻以软重启(soft-reboot)的方式重启系统
  4. soft-reboot 结束后

    1. 新的快照已被应用
    2. /run/reboot-needed 已被删除
    3. last 记录此次重启类型为 s-reboot
⚠️
注意
  • zypp-boot-plugin 最终的重启决策遵循木桶最短板原则的逆向思维——重启需求的最强板。哪怕更新了 100 个只需要 soft-reboot 的小工具,但只要其中混入了一个需要 reboot 的底层驱动,那么最终整个系统都需要进行一次最严格的硬件重启。即 reboot > kexec > soft-reboot

Thanks & Copy


GitHub - openSUSE/transactional-update: Atomic updates for Linux operating systems
Atomic updates for Linux operating systems. Contribute to openSUSE/transactional-update development by creating an account on GitHub.

Github - transactional-update


GitHub - SUSE/rebootmgr
Contribute to SUSE/rebootmgr development by creating an account on GitHub.

Github - rebootmgr


系统分析和微调指南
分析和调整 SLES 系统

Kexec 和 Kdump


SL Micro Release Notes | SL Micro Release Notes 6.1
These Release Notes are identical across all architectures, and the most recent version is always available online at https:…

SL Micro Release Notes


SUSE - 面向 Enterprise Server、云的开放源代码解决方案
利用 SUSE Linux Enterprise Server、用于 IaaS 的云技术以及 SUSE…

SUSE Linux Micro 6.1 Documentation


systemd-soft-reboot.service(8) — Arch manual pages

Arch Linux - systemd-soft-reboot


Introduction of soft-reboot
Intro

Introduction of soft-reboot


zypp-boot-plugin(8) — zypp-boot-plugin

zypp-boot-plugin

标签

xzllll

三分钟热度三分钟收获