Skip to content

Kubernetes v1.37:KubeletInUserNamespace 正式进入 Beta 阶段——Rootless Node 的安全范式跃迁

一句话摘要:Kubernetes v1.37 将 KubeletInUserNamespace(即“Rootless Node”模式)从 Alpha 升级为 Beta,标志着 kubelet、CRI/OCI 运行时、CNI 插件与 kube-proxy 全栈组件可在 Linux user namespace 中以非 root 用户身份运行——这不是容器内降权,而是节点控制平面自身的隔离重构;它不替代 Pod 级 user namespaces(UserNamespacesSupport),而是与之正交叠加,共同构成纵深防御的“嵌套可信边界”。


🔍 背景动机:为什么我们要让 kubelet “自己降权”?

过去十年,Kubernetes 的安全模型存在一个长期被低估的隐性假设:节点组件必须以 root 运行。kubelet 作为节点上的“上帝进程”,拥有 CAP_SYS_ADMINCAP_NET_ADMINCAP_DAC_OVERRIDE 等高危 capability,并直接操作 cgroups、procfs、sysfs、网络命名空间和容器运行时 socket。这种设计在云原生早期加速了落地,却也为攻击面埋下深根。

回顾近五年 CVE,几乎每起严重 host escape 漏洞都源于 root 权限的滥用链

  • CVE-2022-0811(cr8escape):CRI-O 在处理 sysctl 参数时未校验命名空间上下文,攻击者通过恶意 Pod 注入 kernel.core_pattern=/tmp/shell.sh|,触发 core dump 执行任意 root shell;
  • CVE-2023-27561:runc 在 volume mount race 条件下绕过 /proc masked paths,读取宿主机 /proc/1/environ 泄露敏感环境变量;
  • CVE-2024-10220gitRepo 卷(虽已弃用但存量集群仍存)允许执行 .git/hooks/post-checkout,直接以 kubelet 身份调用 sh -c
  • CVE-2025-31133:runc bind-mount 逻辑缺陷导致可向 /proc/sysrq-trigger 写入,触发 echo "c" > /proc/sysrq-trigger 致系统 panic;
  • CVE-2026-53488(v1.37 发布前披露):containerd 解析镜像 label 时未沙箱化 LABEL RUN /bin/sh -c 'rm -rf /',导致 kubelet 调用 ctr run 时继承 root 权限执行。

这些漏洞的共性在于:攻击者无需突破容器隔离,只需诱使 kubelet 或其下游组件(CRI、runc)执行一条受控路径的系统调用,即可获得完整 host root 权限。而 user namespace 是 Linux 内核提供的最轻量、最成熟、零虚拟化开销的隔离原语——它让 root UID 在 namespace 内映射为非特权 UID(如 1001),且默认禁用 CAP_SYS_ADMIN,从根本上切断 mount --bind / /mnt/hostwrite /proc/sys/xxx 等高危操作。

关键认知升级:Rootless Node ≠ Rootless Pod。前者是 node control plane 的隔离,后者是 workload runtime 的隔离。二者定位不同、互补而非互斥。


⚙️ 核心技术:如何启用并验证 Rootless Node?

1. 启用前提(必须满足)

  • Linux kernel ≥ 5.11(推荐 ≥ 5.15,修复多个 user_ns + overlayfs 边界问题);
  • CONFIG_USER_NS=y 已编译进内核(主流发行版默认开启);
  • 宿主机 sysctl user.max_user_namespaces=28633(默认值通常足够,生产建议设为 65536);
  • CRI 运行时需支持 rootless 模式:containerd v1.7+(启用 rootless: true)、CRI-O v1.27+(rootless: true)、或使用 podman system service 作为 CRI endpoint;
  • CNI 插件需适配:Cilium v1.15+ 原生支持;Calico v3.27+ 需启用 FELIX_ROOTLESSMODE=true;Flannel 当前不支持(因其依赖 host-local IPAM 直接写 /var/lib/cni/networks,需 root 权限)。

2. 启用方式(v1.37+)

在 kubelet 启动参数中添加:

bash
--feature-gates=KubeletInUserNamespace=true \
--root-dir=/home/k8s/.kubelet \
--cert-dir=/home/k8s/.kubelet/pki \
--container-runtime-endpoint=unix:///run/user/1001/containerd.sock

💡 注意:--root-dir--cert-dir 必须位于用户可写路径(如 /home/k8s/),不可指向 /var/lib/kubelet(root-only);container-runtime-endpoint 必须指向 rootless 运行时的 socket(如 containerd 的 containerd-rootless-setuptool.sh install 生成的路径)。

3. 验证是否生效

检查 kubelet 日志:

log
I0905 10:23:41.221782   12345 server.go:123] KubeletInUserNamespace enabled: running in user namespace uid=1001, gid=1001

检查进程命名空间:

bash
# 查看 kubelet 进程的 user ns inode
$ readlink /proc/$(pgrep kubelet)/ns/user
user:[4026533144]

# 对比 host root ns(应不同)
$ readlink /proc/1/ns/user
user:[4026531837]

检查 capability(应无 cap_sys_admin):

bash
$ capsh --print | grep cap_sys_admin
# 输出为空即成功

4. 配置示例:rootless containerd + kubelet

/etc/containerd/config.toml(rootless 模式):

toml
version = 2
[plugins."io.containerd.grpc.v1.cri".containerd]
  default_runtime_name = "runc"
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
  runtime_type = "io.containerd.runc.v2"
  [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
    BinaryName = "/usr/bin/runc"
    Root = "/home/k8s/.local/share/containers/storage"

启动命令:

bash
# 切换到非 root 用户(如 k8s)
$ su - k8s
$ containerd-rootless-setuptool.sh install
$ systemctl --user start containerd
$ kubelet --feature-gates=KubeletInUserNamespace=true \
          --root-dir=/home/k8s/.kubelet \
          --container-runtime-endpoint=unix:///run/user/1001/containerd.sock \
          --node-ip=192.168.1.100 \
          --cloud-provider=external \
          --register-with-taints=node.kubernetes.io/not-ready:NoSchedule

⚠️ 重要限制:当前 Beta 版本不支持 hostNetwork: truehostPID: truehostIPC: true 的 Pod;hostPath 卷仅支持 type: DirectoryOrCreate 且路径必须在用户 home 下(如 /home/k8s/data);DevicePlugin(GPU/NPU)需运行时显式支持 rootless(如 NVIDIA Container Toolkit v1.14+ 提供 nvidia-container-runtime --rootless 模式)。


🛠️ 运维建议:Beta 阶段的落地策略

场景建议风险提示
新集群部署✅ 强烈推荐默认启用。结合 UserNamespacesSupport=true(v1.36+ GA),实现 node + pod 双层 user namespace 嵌套,可运行 kindk3s 嵌套集群用于 CI/测试,无需 privileged: trueFlannel 用户需立即迁移至 Cilium 或 Calico;注意监控 containerd-rootless-setuptool.sh 的 systemd user unit 生命周期
存量集群升级⚠️ 暂不建议灰度。因 CNI/CRI 适配不一,且 kube-proxy 在 user ns 中需改用 iptables-legacynftables 不支持 rootless);建议先在非生产节点验证 kubectl get nodes -o wide 是否显示 ReadyInternalIP 正常kube-proxy 若失败,节点将无法转发 Service 流量;务必提前备份 /etc/kubernetes/manifests/kube-proxy.yaml 并替换为 --proxy-mode=iptables 版本
AI/ML 工作负载(vLLM、Triton)✅ 可行但需验证。vLLM v0.5+ 支持 --host 绑定非 localhost;NVIDIA GPU device plugin rootless 模式需确认 nvidia-smi 在 user ns 中可见(依赖 nvidia-container-cli --rootless 初始化)当前 device-pluginNode Allocatable 计算可能不准,建议配合 ExtendedResourceToleration 手动打 taint/toleration 控制调度
安全合规审计✅ 直接降低 CIS Kubernetes Benchmark 第 4.1.1、4.1.2 条款风险(“kubelet 运行于 root”、“未最小化 capability”);输出 audit.logprocess.capabilities 字段将不再包含 cap_sys_admin注意:seccomp profile 仍需配置,user namespace 不替代 syscall 过滤

📌 SRE 实操口诀
“三查一备” —— 查 kernel user_ns 支持、查 CRI/CNI rootless 兼容性、查所有 hostPathhostNetwork 使用点;备回滚方案(保留 root kubelet static pod manifest)。


📚 延伸阅读:不止于 Beta

  • 📘 深度原理:Linux User Namespace 的 12 个子系统映射(/proc/[pid]/uid_map, gid_map, setgroups)如何协同实现 capability 剥离?推荐阅读 LWN: User namespaces: the full story(2024 年更新版)。
  • 🧪 实验场kind v0.22+ 已内置 rootless 支持,一行命令启动全栈 rootless 集群:
    bash
    kind create cluster --image=kindest/node:v1.37.0-rootless
  • 🚀 未来演进(v1.38+ Roadmap)
    • 支持 rootless kube-proxy + nftables(需内核 6.3+);
    • KubeletInUserNamespaceNodeSwap(v1.36 GA)联动,实现 swap 分区在 user ns 中安全挂载;
    • CSI driver rootless 模式标准化(当前需 vendor 自行实现 NodeStageVolume 的用户态 mount)。
  • 🌐 生态对齐:Podman v4.9+、Buildah v1.35+ 已将 rootless 作为默认模式;Red Hat OpenShift 4.16 将提供 Tech Preview 的 rootless worker node;AWS Bottlerocket OS 正在评估集成。

Rootless Node 不是功能补丁,而是 Kubernetes 向“最小权限原则”迈出的决定性一步。当 kubelet 不再是那个手握万能钥匙的守门人,而成为被严格约束的协作者时,我们才真正开始构建可信的云原生基础设施。v1.37 的 Beta,是终点,更是起点。

最后提醒:Beta ≠ Production Ready。请务必在 staging 环境完成全链路验证(包括滚动升级、节点驱逐、Pod 重建、CNI 网络连通性、metrics-server 抓取),再推向核心业务集群。安全没有银弹,只有纵深防御的每一层都更坚实一分。