Kured(KUbernetes REboot Daemon) with openSUSE MicroOS
1. First | 序
Kured(Kubernetes REboot Daemon)是一个 Kubernetes 守护进程集,当底层操作系统的软件包管理系统指示需要重启节点时,它会执行安全的自动节点重启
此篇记录不可变系统 openSUSE MicroOS 安装 Kured 指南
1.1. Environment | 环境
➜ ~ hostnamectl
Static hostname: K3S-00
Icon name: computer-vm
Chassis: vm 💽
Machine ID: 1eade3f7bfc845d0863698e6db8f50d0
Boot ID: 7b33f7cbe1204c9cb15d75f315729018
Product UUID: 1eade3f7-bfc8-45d0-8636-98e6db8f50d0
Virtualization: kvm
Operating System: openSUSE MicroOS
CPE OS Name: cpe:/o:opensuse:microos:20260531
Kernel: Linux 7.0.10-2-default
Architecture: x86-64
Hardware Vendor: QEMU
Hardware Model: Standard PC _Q35 + ICH9, 2009_
Hardware Version: pc-q35-9.2
Firmware Version: 3.20230228-4
Firmware Date: Tue 2023-06-06
Firmware Age: 2y 11month 4w
➜ ~ kubectl get nodes
NAME STATUS ROLES AGE VERSION
k3s-00 Ready control-plane,etcd 2d21h v1.35.5+k3s1
k3s-01 Ready control-plane,etcd 2d21h v1.35.5+k3s1
k3s-02 Ready control-plane,etcd 2d21h v1.35.5+k3s1
➜ ~ cilium status
/¯¯\
/¯¯\__/¯¯\ Cilium: OK
\__/¯¯\__/ Operator: OK
/¯¯\__/¯¯\ Envoy DaemonSet: OK
\__/¯¯\__/ Hubble Relay: disabled
\__/ ClusterMesh: disabled
DaemonSet cilium Desired: 3, Ready: 3/3, Available: 3/3
DaemonSet cilium-envoy Desired: 3, Ready: 3/3, Available: 3/3
Deployment cilium-operator Desired: 2, Ready: 2/2, Available: 2/2
Containers: cilium Running: 3
cilium-envoy Running: 3
cilium-operator Running: 2
clustermesh-apiserver
hubble-relay
Cluster Pods: 57/57 managed by Cilium
Helm chart version: 1.19.4
Image versions cilium quay.io/cilium/cilium:v1.19.4@sha256:2eb67991eaa9368ba199c2fac2c573cb0ffdeb79184533344f42fc9a7ff6af3c: 3
cilium-envoy quay.io/cilium/cilium-envoy:v1.36.6-1778235340-b87d1e32f522b33bd51701c6476d199326f01496@sha256:71d4fa0ec45e8d546dbd5604e169dc77fe92be63b799313bff031d00d89762e3: 3
cilium-operator quay.io/cilium/operator-generic:v1.19.4@sha256:1aa2b62735e7d8ab49ee840ae59c346932024c88901579121395c1271b435f71: 2
1.2. Notes | 须知
1.2.1. Transactional Update

- 解耦「更新」与「重启」 : MicroOS 负责原子的事务性更新(Transactional Update),而将重启的控制权、节点排空(Drain)以及并发控制完全交由 Kured 管理
➜ ~ cat /usr/etc/transactional-update.conf
# Configuration file for transactional-update
# See transactional-update.conf(5) for details
# Reboot method
# Valid values: auto rebootmgr notify systemd kured none
# Deprecated: kexec
#REBOOT_METHOD=auto
# Default zypper update method
# Valid values: dup up
UPDATE_METHOD=dup
# Import new repository GPG keys automatically
# Valid values: 0 1
#ZYPPER_AUTO_IMPORT_KEYS=0
1.2.2. zypp-boot-plugin
zypp-boot-plugin 是一个与软件包管理器(本篇特指transactional-update)集成的实用程序,可自动确定系统更新或安装是否需要重启,以及具体需要哪种类型的重启。(例如soft-reboot、kexec或完整reboot)。
它会生成一个标志文件来指定所需的重启行为
其默认配置文件如下所示
## Configuration file for zypp-boot-plugin plugin.
## /usr/etc/zypp/zypp-boot-plugin.conf
##
## This configuration file defines packages for which a reboot
## is needed after they have been installed/updated.
##
## The package name can also be defined by regex expressions.
## This is needed for e.g. libraries with package names like
## libopenssl1_1, libopenssl3, ...
##
[main]
##
## Packages for which a hard reboot is needed after they have been
## installed or updated.
##
## Packages are selected either by name, or by provides. In the later case
## the string must start with "provides:" immediately followed by the capability.
##
## Example:
## foo - just packages with name 'foo'
## provides:bar - all packages providing 'bar'
##
## Valid values:
## Comma separated list of packages.
##
## Default value:
## empty
##
reboot = grub2,selinux-policy,systemd-boot
##
## Packages for which a kexec call is needed at least after they have been
## installed or updated.
##
## Packages are selected either by name, or by provides. In the later case
## the string must start with "provides:" immediately followed by the capability.
##
## Example:
## foo - just packages with name 'foo'
## provides:bar - all packages providing 'bar'
##
## Valid values:
## Comma separated list of packages.
##
## Default value:
## empty
##
kexec = provides:multiversion(kernel)
##
## Packages for which a soft reboot is needed at least after they have been
## installed or updated.
##
## Packages are selected either by name, or by provides. In the later case
## the string must start with "provides:" immediately followed by the capability.
##
## Example:
## foo - just packages with name 'foo'
## provides:bar - all packages providing 'bar'
##
## Valid values:
## Comma separated list of packages.
##
## Default value:
## empty
##
soft-reboot = glibc, dbus-broker, dbus-1-daemon, libopenssl[0-9]?_?[0-9]?_?[0-9]?, libopenssl[0-9]?_?[0-9]?_?[0-9]?-32bit
2. Procedure | 步骤
2.1. 宿主机端(openSUSE MicroOS)配置
默认情况下,MicroOS 会在更新后通过 rebootmgr 立即或在策略窗口内重启,这会绕过 K3s 的感知。我们需要关闭此行为,并通知系统改用 Kured 信号。
2.1.1 修改事务性更新配置:
在每台 MicroOS 宿主机上,编辑(或创建)/etc/transactional-update.conf,将重启方法指定为 kured:
REBOOT_METHOD=kured
2.1.2. 禁用并停止 rebootmgr:
完全移交重启控制权,防止宿主机自主强行重启:
sudo systemctl disable --now rebootmgr.service
2.2. 集群端(K3s & Kured)部署
Kured 作为 DaemonSet 运行在 K3s 集群中。它通过分布式锁(利用 Kubernetes API 的 Lease 或 Annotation)来确保全局唯一性——即同一时间整个集群有且仅有一台节点能获取重启锁。
本篇使用 Helm 部署 Kured :
# 添加并更新 Helm 仓库
helm repo add kubereboot https://kubereboot.github.io/charts
helm repo update
# 创建命名空间并部署 Kured
kubectl create namespace kured
helm install kured kubereboot/kured \
--namespace kured \
--set configuration.rebootSentinel=/run/reboot-required \
--set configuration.period=15m \
--set configuration.lockAnnotation=reboot.weave.works/lock \
--set configuration.concurrency=1
参数解析:
configuration.rebootSentinel=/run/reboot-required:让 Kured 容器去检测 MicroOS 生成的重启标记文件(由于现代 Linux 的/var/run实际软链接到/run,此处配置/run/...或/var/run/...均可,但需确保容器挂载了宿主机的对应目录)。configuration.lockAnnotation:激活集群全局排他锁。Kured 会在争抢到该锁后才开始排空节点,天然保证了同时只有一台服务器进入更新重启流程。
🔄 工作流 (Workflow)
当系统运行起来后,三节点的滚动更新将按照以下原子化流水线执行:
[MicroOS 定时触发更新]
│
▼
[生成新 Btrfs 快照] ──> [写入 /run/reboot-required]
│
▼
[Kured 监测到标记文件]
│
▼
[集群全局锁争抢 (Lock)] ──> (仅允许1台成功)
│
▼
[K3s 节点排空 (Cordon & Drain)] ──> (Pod 安全迁移)
│
▼
[Kured 触发宿主机重启] ──> (MicroOS 载入新快照)
│
▼
[节点恢复 Ready] ──> [释放全局锁] ──> (轮转下一台)
3. Ex | 拓展
3.1. K3s 控制平面高可用(HA)保障
请确保你的 K3s 集群是基于嵌入式 ETCD(或外部高可用数据库)建立的 HA 架构。2 个节点依然可以维持 ETCD 的法定人数(Quorum),若非 HA 架构,控制平面可能会短暂离线。
3.2. 设置维护窗口(可选):
如果不希望 MicroOS 的更新打乱白天的正常业务,可以通过 Kured 参数限制重启发生的时间段(例如仅允许在凌晨 2 点到 5 点重启):
--set configuration.startTime=02:00
--set configuration.endTime=05:00
--set configuration.timeZone=Asia/Shanghai
3.3. 配置 Pod 干扰预算(PDB):
为了配合 Kured 的安全排空(Drain),强烈建议为核心业务配置 PodDisruptionBudget。这样可以防止在排空节点时,因其余节点压力过大或副本数不足而导致业务真正中断。
3.3. About Soft-Reboot
当前 Kured 官方原生(Out-of-the-box)目前并不支持、也不感知 soft-reboot
但我们可以借助 transactional-update (实际调用 zypp-boot-plugin 组件) 生成的/run/reboot-needed 文件并结合 Kured 提供的一个自定义参数 --reboot-command (在 Helm 中对应 configuration.rebootCommand) 来判断此次 boot levels
There are different boot levels which will be stored in the /run/reboot-needed as an normal ASCII string:
reboot
Hard reboot
kexec
Booting a new kernel without initializing hardware and without using any bootloader like Grub2.
soft-reboot
Soft reboot done by E.G. *systemctl soft-reboot*
使用 helm upgrade 更新 Kured 配置,注入这段动态判断逻辑
helm upgrade kured kubereboot/kured \
--namespace kured \
--reuse-values \
--set configuration.rebootCommand="nsenter -t 1 -m -u -i -n -p sh -c 'if [ \"\$(cat /run/reboot-needed 2>/dev/null)\" = \"soft-reboot\" ]; then echo \"[Kured] Triggering MicroOS Soft-Reboot...\"; /usr/bin/systemctl soft-reboot; else echo \"[Kured] Triggering Standard Hard-Reboot...\"; /usr/bin/systemctl reboot; fi'"
upgrade 更新完成后验证 Kured values
➜ /run helm get values kured -n kured
USER-SUPPLIED VALUES:
configuration:
concurrency: 1
endTime: "05:00"
lockAnnotation: reboot.weave.works/lock
period: 15m
rebootCommand: nsenter -t 1 -m -u -i -n -p sh -c 'if [ "$(cat /run/reboot-needed
2>/dev/null)" = "soft-reboot" ]; then echo "[Kured] Triggering MicroOS Soft-Reboot...";
/usr/bin/systemctl soft-reboot; else echo "[Kured] Triggering Standard Hard-Reboot...";
/usr/bin/systemctl reboot; fi'
rebootSentinel: /run/reboot-required
startTime: "02:00"
timeZone: Asia/Shanghai
3.4. About kexec
理论上你仍可以使用上述操作触发 /usr/bin/systemctl kexec
kexec 行为,Linux 内核会进入 Lockdown(锁定)模式。使用 helm upgrade 更新 Kured 配置,注入这段动态判断逻辑
helm upgrade kured kubereboot/kured \
--namespace kured \
--reuse-values \
--set configuration.rebootCommand="nsenter -t 1 -m -u -i -n -p sh -c 'LVL=\"\$(cat /run/reboot-needed 2>/dev/null)\"; if [ \"\$LVL\" = \"soft-reboot\" ]; then echo \"[Kured] Triggering MicroOS Soft-Reboot...\"; /usr/bin/systemctl soft-reboot; elif [ \"\$LVL\" = \"kexec\" ]; then echo \"[Kured] Triggering MicroOS Kexec-Reboot...\"; /usr/bin/systemctl kexec; else echo \"[Kured] Triggering Standard Hard-Reboot...\"; /usr/bin/systemctl reboot; fi'"
upgrade 更新完成后验证 Kured values
➜ ~ helm get values kured -n kured
USER-SUPPLIED VALUES:
configuration:
concurrency: 1
endTime: "05:00"
lockAnnotation: reboot.weave.works/lock
period: 15m
rebootCommand: nsenter -t 1 -m -u -i -n -p sh -c 'LVL="$(cat /run/reboot-needed
2>/dev/null)"; if [ "$LVL" = "soft-reboot" ]; then echo "[Kured] Triggering MicroOS
Soft-Reboot..."; /usr/bin/systemctl soft-reboot; elif [ "$LVL" = "kexec" ]; then
echo "[Kured] Triggering MicroOS Kexec-Reboot..."; /usr/bin/systemctl kexec; else
echo "[Kured] Triggering Standard Hard-Reboot..."; /usr/bin/systemctl reboot;
fi'
rebootSentinel: /run/reboot-required
startTime: "02:00"
timeZone: Asia/Shanghai
3.5. Logs | 日志
time="2026-06-04T18:25:32Z" level=info msg="Kubernetes Reboot Daemon: 1.22.0"
time="2026-06-04T18:25:32Z" level=info msg="Node ID: k3s-00"
time="2026-06-04T18:25:32Z" level=info msg="PreferNoSchedule taint: "
time="2026-06-04T18:25:32Z" level=info msg="Blocking Pod Selectors: []"
time="2026-06-04T18:25:32Z" level=info msg="Reboot period 15m0s"
time="2026-06-04T18:25:32Z" level=info msg="Concurrency: 1"
time="2026-06-04T18:25:32Z" level=info msg="Reboot schedule: SunMonTueWedThuFriSat between 02:00 and 05:00 Asia/Shanghai"
time="2026-06-04T18:25:32Z" level=info msg="Reboot method: command"
time="2026-06-04T18:25:32Z" level=info msg="Reboot command: nsenter -t 1 -m -u -i -n -p sh -c 'if [ \"$(cat /run/reboot-needed 2>/dev/null)\" = \"soft-reboot\" ]; then echo \"[Kured] Triggering MicroOS Soft-Reboot...\"; /usr/bin/systemctl soft-reboot; else echo \"[Kured] Triggering Standard Hard-Reboot...\"; /usr/bin/systemctl reboot; fi'"
time="2026-06-04T18:25:32Z" level=info msg="Sentinel checker is (unprivileged) testing for the presence of: /sentinel/reboot-required"
time="2026-06-04T18:25:32Z" level=info msg="Lock Annotation: kured/kured:reboot.weave.works/lock"
time="2026-06-04T18:25:32Z" level=info msg="Lock TTL not set, lock will remain until being released"
time="2026-06-04T18:25:32Z" level=info msg="Lock release delay not set, lock will be released immediately after rebooting"
time="2026-06-04T18:27:03Z" level=info msg="Uncordoning node k3s-00"
time="2026-06-04T18:41:07Z" level=info msg="Reboot not required"
time="2026-06-04T18:56:07Z" level=info msg="Reboot not required"
time="2026-06-04T19:11:07Z" level=info msg="Reboot not required"
time="2026-06-04T19:26:07Z" level=info msg="Reboot not required"
time="2026-06-04T19:41:07Z" level=info msg="Reboot not required"
time="2026-06-04T19:56:07Z" level=info msg="Reboot not required"
time="2026-06-04T20:11:07Z" level=info msg="Reboot not required"
time="2026-06-04T20:26:07Z" level=info msg="Reboot not required"
time="2026-06-04T20:41:07Z" level=info msg="Reboot not required"
time="2026-06-04T20:56:07Z" level=info msg="Reboot not required"
time="2026-06-04T19:24:26Z" level=info msg="Kubernetes Reboot Daemon: 1.22.0"
time="2026-06-04T19:24:26Z" level=info msg="Node ID: k3s-02"
time="2026-06-04T19:24:26Z" level=info msg="PreferNoSchedule taint: "
time="2026-06-04T19:24:26Z" level=info msg="Blocking Pod Selectors: []"
time="2026-06-04T19:24:26Z" level=info msg="Reboot period 15m0s"
time="2026-06-04T19:24:26Z" level=info msg="Concurrency: 1"
time="2026-06-04T19:24:26Z" level=info msg="Reboot schedule: SunMonTueWedThuFriSat between 02:00 and 05:00 Asia/Shanghai"
time="2026-06-04T19:24:26Z" level=info msg="Reboot method: command"
time="2026-06-04T19:24:26Z" level=info msg="Reboot command: nsenter -t 1 -m -u -i -n -p sh -c 'if [ \"$(cat /run/reboot-needed 2>/dev/null)\" = \"soft-reboot\" ]; then echo \"[Kured] Triggering MicroOS Soft-Reboot...\"; /usr/bin/systemctl soft-reboot; else echo \"[Kured] Triggering Standard Hard-Reboot...\"; /usr/bin/systemctl reboot; fi'"
time="2026-06-04T19:24:26Z" level=info msg="Sentinel checker is (unprivileged) testing for the presence of: /sentinel/reboot-required"
time="2026-06-04T19:24:26Z" level=info msg="Lock Annotation: kured/kured:reboot.weave.works/lock"
time="2026-06-04T19:24:26Z" level=info msg="Lock TTL not set, lock will remain until being released"
time="2026-06-04T19:24:26Z" level=info msg="Lock release delay not set, lock will be released immediately after rebooting"
time="2026-06-04T19:25:08Z" level=info msg="Uncordoning node k3s-02"
time="2026-06-04T19:41:31Z" level=info msg="Reboot not required"
time="2026-06-04T19:56:31Z" level=info msg="Reboot not required"
time="2026-06-04T20:11:31Z" level=info msg="Reboot not required"
time="2026-06-04T20:26:31Z" level=info msg="Reboot not required"
time="2026-06-04T20:41:31Z" level=info msg="Reboot not required"
time="2026-06-04T20:56:31Z" level=info msg="Reboot not required"
time="2026-06-04T19:07:19Z" level=info msg="Kubernetes Reboot Daemon: 1.22.0"
time="2026-06-04T19:07:19Z" level=info msg="Node ID: k3s-01"
time="2026-06-04T19:07:19Z" level=info msg="PreferNoSchedule taint: "
time="2026-06-04T19:07:19Z" level=info msg="Blocking Pod Selectors: []"
time="2026-06-04T19:07:19Z" level=info msg="Reboot period 15m0s"
time="2026-06-04T19:07:19Z" level=info msg="Concurrency: 1"
time="2026-06-04T19:07:19Z" level=info msg="Reboot schedule: SunMonTueWedThuFriSat between 02:00 and 05:00 Asia/Shanghai"
time="2026-06-04T19:07:19Z" level=info msg="Reboot method: command"
time="2026-06-04T19:07:19Z" level=info msg="Reboot command: nsenter -t 1 -m -u -i -n -p sh -c 'if [ \"$(cat /run/reboot-needed 2>/dev/null)\" = \"soft-reboot\" ]; then echo \"[Kured] Triggering MicroOS Soft-Reboot...\"; /usr/bin/systemctl soft-reboot; else echo \"[Kured] Triggering Standard Hard-Reboot...\"; /usr/bin/systemctl reboot; fi'"
time="2026-06-04T19:07:19Z" level=info msg="Sentinel checker is (unprivileged) testing for the presence of: /sentinel/reboot-required"
time="2026-06-04T19:07:19Z" level=info msg="Lock Annotation: kured/kured:reboot.weave.works/lock"
time="2026-06-04T19:07:19Z" level=info msg="Lock TTL not set, lock will remain until being released"
time="2026-06-04T19:07:19Z" level=info msg="Lock release delay not set, lock will be released immediately after rebooting"
time="2026-06-04T19:08:17Z" level=info msg="Uncordoning node k3s-01"
time="2026-06-04T19:17:51Z" level=info msg="Reboot not required"
time="2026-06-04T19:32:51Z" level=info msg="Reboot not required"
time="2026-06-04T19:47:51Z" level=info msg="Reboot not required"
time="2026-06-04T20:02:51Z" level=info msg="Reboot not required"
time="2026-06-04T20:17:51Z" level=info msg="Reboot not required"
time="2026-06-04T20:32:51Z" level=info msg="Reboot not required"
time="2026-06-04T20:47:51Z" level=info msg="Reboot not required"
Thanks & Copy





