openSUSE MicroOS | 入门指南之 transactional-update
1. First | 序
书接上回

此次学习管理 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 命令将其他更改添加到快照。此操作将创建独立的快照,其中不包含先前快照中的更改。
-
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) -
何为原子性?
原子(Atom)这个词源于希腊语,意为"不可分割"。在计算机科学中,原子性意味着一个操作是一个不可分割的单元,它只有两种最终状态:
-
完全成功 (All):操作中的每一个步骤都成功完成。
-
完全失败 (Nothing):如果操作中任何一个步骤失败,整个操作都将回滚,系统会恢复到操作开始之前的原始状态,就像什么都没发生过一样。
绝对不会存在“部分成功”的中间状态。
-
-
事务性更新和传统更新之间的对比关系
特性 事务性更新 (原子性) 传统更新 (非原子性) 更新过程 在一个隔离的新快照上操作,不影响当前系统 直接在当前运行的系统上修改文件 成功结果 系统重启后,整体切换到一个全新的、100%更新成功的状态 所有软件包被逐一更新 失败结果 新快照被丢弃,系统完全回滚到更新前的状态,无任何影响 系统停留在半更新的损坏状态,极不稳定 系统可靠性 极高。更新要么 100% 成功,要么 0% 影响 较低。更新过程中的任何中断都可能导致系统损坏
2.2. transactional-update 的工作原理
以下内容直接 Copy 至官方文档
每次调用 transactional-update 命令来更改系统时(无论是安装软件包、执行更新还是应用补丁),系统都会执行以下操作:
-
基于当前的根文件系统或您指定的快照创建新的读写快照。
-
应用所有更改(执行更新、修补操作或安装软件包)。
-
将快照切换回只读模式。
-
如果所有更改都成功应用,则将新的根文件系统快照设为默认快照。
-
重引导之后,系统引导进入新的快照。
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的情况下这样会带来一些问题
例如:
-
你使用
transactional-update pkg install ncdu安装 ncdu 但并未重启 (此时系统根据当前根文件系统创建了快照A) -
10 min 后你又使用
transactional-update pkg install htop安装 htop (此时系统又根据当前根文件系统创建了快照B) -
此时你
reboot后惊奇的发现ncdu不存在,原因就在于 transactional-update 默认行为是在每次更改发生后基于当前根文件系统创建新快照 -
并且 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 给了三种解决方案分别为
- transactional-update --continue
- transactional-update run
- transactional-update shell
我们一一来看
2.4.2. transactional-update --continue
这种方式很像平常用到的 >> 追加
即: 将当前更改追加到 上一个未生效的快照基础上 继续应用新的更改,并生成一个“更新版”的快照。这个过程可以一直持续下去。
仍按照之前的例子举例:
-
你使用
transactional-update pkg install ncdu安装 ncdu 但并未重启 (此时系统根据当前根文件系统创建了快照A) -
10 min 后你又使用
transactional-update --continue pkg install htop安装 htop (此时系统会以快照A为基础创建了B) -
此时你
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 即可应用
同时它有一些限制
- 不记录命令:你在这个 Shell 里输入的具体命令不会被记入日志。
- 无法控制服务:不能使用 systemd 命令(如 systemctl start/stop)来管理服务。
- /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
首先来了解一下关于重启的几个级别
-
硬件重引导 (Hardware Reboot):
- 这是我们最熟悉的重启方式,相当于按下电脑的重启按钮。
- 它会完全关闭再启动整个计算机硬件,重新加载 BIOS/UEFI,引导加载程序 (GRUB2),然后加载操作系统内核,最后启动所有系统服务和程序。
- 特点:最彻底,但也是最慢的。
-
内核重引导 (kexec):
- 这是一种更快的重启方式。它跳过了硬件自检和 GRUB2 加载的步骤。
- 它直接在当前运行的内核的内存中加载一个新的内核,然后无缝切换过去。
- 特点:比硬件重启快很多,适用于只需要更新内核(比如打了安全补丁)而不需要重启硬件的场景。
-
用户空间重引导 (soft-reboot):
- 这是最快、最轻量级的重启方式。
- 它保持硬件和内核持续运行,完全不重启它们。
- 它只重启操作系统的“用户空间”部分,也就是在内核之上运行的所有服务和应用程序(例如
systemd服务管理器、dbus消息总线、桌面环境等)。 - 特点:速度极快,几乎是瞬时的。适用于那些只影响用户空间程序的更新。
| 重引导类型 | 重启范围 | 速度 | 适用更新场景 |
|---|---|---|---|
| 硬件重引导 (reboot) | 硬件、内核、用户空间 | 最慢 | 固件、部分底层驱动更新 |
| 内核重引导 (kexec) | 内核、用户空间 | 较快 | 内核 (kernel) 包更新 |
| 用户空间重引导 (soft-reboot) | 仅用户空间的服务与程序 | 最快 | 核心库 (如 glibc)、系统服务 (如 dbus) 更新 |
为了让 soft-reboot 工作,需要做两件事:
-
打开总开关:在
/etc/tukit.conf.d/soft-reboot.conf中允许soft-reboot。 -
定义规则:在
/etc/zypp/zypp-boot-plugin.conf中,将那些适合soft-reboot的软件包(如 glibc)添加到 soft-reboot 列表中。
当您下次运行 transactional-update 更新了一个被标记为 soft-reboot 的包后,系统将执行一次极快的用户空间重启,而不是漫长的硬件重启,从而大大节省您的时间
接下来一一说明
2.5.2. 启用/禁用 soft-reboot
如果需要启用 Soft-Reboot, 请执行下列步骤:
-
创建目录 /etc/tukit.conf.d/
sudo mkdir /etc/tukit.conf.d/ -
创建包含以下内容的文件 /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
指定更改时只需要重引导用户空间的软件包。
有以下两种配置方式
-
用逗号分隔软件包名称
soft-reboot = glibc, dbus-broker -
使用 provides 语句
soft-reboot = provides: dbus它不关心具体的软件包叫什么名字,而是关心这个包提供了什么功能。
这个例子意味着,任何提供了 dbus 功能的包(无论是 dbus-broker 还是其他实现)被更新时,都适用 soft-reboot 规则。
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
可以使用以下命令查询
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 的配置文件默认路径为 /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 都做了什么?
-
关闭所有正在运行的服务。
-
切换到一个新的根文件系统 (这是与 transactional-update 结合的关键!)。
-
重新执行 systemd 主进程。
-
重新启动所有服务。
3. transactional-update 实践
第二节介绍了 Transactional Update 某些特性
那么该如何安全且优雅的在 MicroOS 上安装/更新软件包呢
以安装 ncdu 软件包为例做个演示
3.1. soft-reboot 之前
3.2. soft-reboot 之后
3.3. 总结
在以上安装 ncdu 软件包时,系统做了哪些工作?
我们一一分析
-
首先我们得知目前环境
- ncdu 包未安装
- rebootmgrctl 重启策略为 instantly
- /run/reboot-needed 文件未生成
-
安装 ncdu 软件包后
- 新的快照生成
- 系统调用 zypp-boot-plugin 插件评估包安装/更新后是否需要重启以及重启的方式
- 插件首先查找管理员自定义的 /etc/zypp/zypp-boot-plugin.conf 文件,若无果会采纳软件包开发者通过 installhint 提供的分布式建议
- zypp-boot-plugin 得到的结果为需要重启,重启方式为 soft-reboot,并将结果写入 /run/reboot-needed 文件
-
运行 transactional-update reboot 后
- transactional-update 进行初步检查后调用了后端工具 tukit
- tukit 接管工作,根据zypp-boot-plugin回馈的结果向 rebootmgr 服务发送了一个请求,这个请求的内容是:“系统有待处理的更新,根据分析需要进行一次软重启 (soft-reboot),请你在合适的时候处理一下。”
- rebootmgr 收到请求,检查当前系统配置的重启策略
- 当前系统的重启策略为 instantly ,即收到信号后立即进行重启,本次重启类型为软重启(soft-reboot)
- 立刻以软重启(soft-reboot)的方式重启系统
-
soft-reboot 结束后
- 新的快照已被应用
- /run/reboot-needed 已被删除
- last 记录此次重启类型为 s-reboot
- zypp-boot-plugin 最终的重启决策遵循木桶最短板原则的逆向思维——重启需求的最强板。哪怕更新了 100 个只需要 soft-reboot 的小工具,但只要其中混入了一个需要 reboot 的底层驱动,那么最终整个系统都需要进行一次最严格的硬件重启。即 reboot > kexec > soft-reboot
Thanks & Copy
Github - transactional-update
Github - rebootmgr

Kexec 和 Kdump
SL Micro Release Notes

SUSE Linux Micro 6.1 Documentation
Arch Linux - systemd-soft-reboot

Introduction of soft-reboot
zypp-boot-plugin

