Photo by Growtika / Unsplash

Kured(KUbernetes REboot Daemon) with openSUSE MicroOS

指南 | Guides 2026年6月3日

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

openSUSE MicroOS | 入门指南之 transactional-update
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
  • 解耦「更新」与「重启」 : MicroOS 负责原子的事务性更新(Transactional Update),而将重启的控制权、节点排空(Drain)以及并发控制完全交由 Kured 管理
👇
默认 transactional-update.conf 配置如下所示
➜  ~ 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

⚠️
注意:如果在你的物理服务器(或虚拟机)的 BIOS 中开启了 UEFI Secure Boot,系统会默认禁止未签名或未认证的 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

zypp-boot-plugin(8) — zypp-boot-plugin
Kured - Kubernetes Reboot Daemon
Kured (KUbernetes REboot Daemon) is a Kubernetes daemonset that performs safe automatic node reboots when the need to do so is indicated by the package management system of the underlying OS.
transactional-update 命令的用法和用例。
使用 transactional-update 命令管理 SLE Micro。
openSUSE MicroOS
Learn about the openSUSE distributions and download them for free
The Transactional Update Guide
This is the documentation for transactional-update and is intended for users, administrators and packagers. It describes how transactional-update with Btrfs works by giving an overview of the design, what an administrator needs to know about setting up and operating such a system and what a packager needs to know for creating compatible packages. For specific usage see the transactional-update man page or the list of Kubic related commands.
transactional-update.conf(5) — transactional-update
Manpages of transactional-update

标签

xzllll

三分钟热度三分钟收获