以非 root 用户身份运行 Kubernetes 节点组件

    这个文档描述了怎样不使用 root 特权,而是通过使用 用户命名空间 去运行 Kubernetes 节点组件(例如 kubelet、CRI、OCI、CNI)。

    这种技术也叫做 rootless 模式(Rootless mode)

    说明: 这个文档描述了怎么以非 root 用户身份运行 Kubernetes 节点组件以及 Pod。 如果你只是想了解如何以非 root 身份运行 Pod,请参阅 。

    你的 Kubernetes 服务器版本必须不低于版本 1.22. 要获知版本信息,请输入 kubectl version.

    使用 Rootless 模式的 Docker/Podman 运行 Kubernetes

    kind 支持使用 Rootless 模式的 Docker 或者 Podman 运行 Kubernetes。

    请参阅。

    minikube

    也支持使用 Rootless 模式的 Docker 或 Podman 运行 Kubernetes。

    请参阅 Minikube 文档:

    说明: 本部分链接到提供 Kubernetes 所需功能的第三方项目。Kubernetes 项目作者不负责这些项目。此页面遵循,按字母顺序列出项目。要将项目添加到此列表中,请在提交更改之前阅读内容指南

    sysbox

    Sysbox 是一个开源容器运行时 (类似于 “runc”),支持在 Linux 用户命名空间隔离的非特权容器内运行系统级工作负载, 比如 Docker 和 Kubernetes。

    查看 了解更多细节。

    Sysbox 支持在非特权容器内运行 Kubernetes, 而不需要 cgroup v2 和 “KubeletInUserNamespace” 特性门控。 Sysbox 通过在容器内暴露特定的 /proc/sys 文件系统, 以及其它一些先进的操作系统虚拟化技术来实现。

    直接在主机上运行 Rootless 模式的 Kubernetes

    说明: 本部分链接到提供 Kubernetes 所需功能的第三方项目。Kubernetes 项目作者不负责这些项目。此页面遵循,按字母顺序列出项目。要将项目添加到此列表中,请在提交更改之前阅读内容指南

    K3s 实验性支持了 Rootless 模式。

    请参阅 页面中的用法.

    Usernetes

    是 Kubernetes 的一个参考发行版, 它可以在不使用 root 特权的情况下安装在 $HOME 目录下。

    Usernetes 支持使用 containerd 和 CRI-O 作为 CRI 运行时。 Usernetes 支持配置了 Flannel (VXLAN)的多节点集群。

    本节提供在用户命名空间手动运行 Kubernetes 的注意事项。

    说明: 本节是面向 Kubernetes 发行版的开发者,而不是最终用户。

    创建用户命名空间

    第一步是创建一个 用户命名空间

    如果你正在尝试使用用户命名空间的容器(例如 Rootless 模式的 Docker/Podman 或 LXC/LXD) 运行 Kubernetes,那么你已经准备就绪,可以直接跳到下一小节。

    否则你需要通过传递参数 CLONE_NEWUSER 调用 unshare(2),自己创建一个命名空间。

    用户命名空间也可以通过如下所示的命令行工具取消共享:

    在取消命名空间的共享之后,你也必须对其它的命名空间例如 mount 命名空间取消共享。

    在取消 mount 命名空间的共享之后,你需要调用 chroot() 或者 pivot_root(), 但是你必须在这个命名空间内挂载可写的文件系统到几个目录上。

    请确保这个命名空间内(不是这个命名空间外部)至少以下几个目录是可写的:

    • /etc
    • /run
    • /var/logs
    • /var/lib/kubelet
    • /var/lib/containers (参照 CRI-O)

    除了用户命名空间,你也需要有一个版本为 cgroup v2 的可写 cgroup 树。

    说明: Kubernetes 需要 cgroup v2 才支持在用户命名空间运行节点组件。 cgroup v1 是不支持的。

    如果你在一个采用 systemd 机制的主机上使用用户命名空间的容器(例如 Rootless 模式的 Docker/Podman 或 LXC/LXD)来运行 Kubernetes,那么你已经准备就绪。

    否则你必须创建一个具有 Delegate=yes 属性的 systemd 单元,来委派一个具有可写权限的 cgroup 树。

    在你的节点上,systemd 必须已经配置为允许委派。更多细节请参阅 Rootless 容器文档的 部分。

    配置网络

    说明: 本部分链接到提供 Kubernetes 所需功能的第三方项目。Kubernetes 项目作者不负责这些项目。此页面遵循,按字母顺序列出项目。要将项目添加到此列表中,请在提交更改之前阅读内容指南

    节点组件的网络命名空间必须有一个非本地回路的网卡。它可以使用 、 VPNKit、 等工具进行配置。

    Pod 的网络命名空间可以使用常规的 CNI 插件配置。对于多节点的网络,已知 Flannel (VXLAN、8472/UDP) 可以正常工作。

    你可以使用 K3s 的端口转发器。更多细节请参阅 在 Rootless 模式下运行 K3s。 该实现可以在 k3s 的 中找到。

    配置 CRI

    kubelet 依赖于容器运行时。你需要部署一个容器运行时(例如 containerd 或 CRI-O), 并确保它在 kubelet 启动之前已经在用户命名空间内运行。

    containerd 1.4 开始支持在用户命名空间运行 containerd 的 CRI 插件。

    在用户命名空间运行 containerd 必须进行如下配置:

    配置文件的默认路径是 /etc/containerd/config.toml。 可以用 containerd -c /path/to/containerd/config.toml 来指定该路径。

    CRI-O 1.22 开始支持在用户命名空间运行 CRI-O。

    CRI-O 必须配置一个环境变量 _CRIO_ROOTLESS=1

    也推荐使用以下配置:

    配置文件的默认路径是 /etc/containerd/config.toml。 可以用 containerd -c /path/to/containerd/config.toml 来指定该路径。

    在用户命名空间运行 kubelet 必须进行如下配置:

    KubeletInUserNamespace 特性门控被启用时, kubelet 会忽略节点内由于配置如下几个 sysctl 参数值而可能产生的错误。

    • vm.overcommit_memory
    • vm.panic_on_oom
    • kernel.panic
    • kernel.keys.root_maxkeys
    • kernel.keys.root_maxbytes.

    在用户命名空间内, kubelet 也会忽略任何由于打开 /dev/kmsg 而产生的错误。 这个特性门控也允许 kube-proxy 忽略由于配置 RLIMIT_NOFILE 而产生的一个错误。

    KubeletInUserNamespace 特性门控从 Kubernetes v1.22 被引入, 标记为 “alpha” 状态。

    通过挂载特制的 proc 文件系统 (比如 Sysbox), 也可以在不使用这个特性门控的情况下在用户命名空间运行 kubelet,但这不受官方支持。

    配置 kube-proxy

    在用户命名空间运行 kube-proxy 需要进行以下配置:

    注意事项

    • 大部分“非本地”的卷驱动(例如 nfsiscsi)不能正常工作。 已知诸如 localhostPathemptyDirconfigMapsecretdownwardAPI 这些本地卷是能正常工作的。

    • 一些 CNI 插件可能不正常工作。已知 Flannel (VXLAN) 是能正常工作的。