以非 Root 使用者身分執行 Kubernetes 節點元件

功能狀態: Kubernetes v1.22 [alpha]

本文件說明如何透過使用使用者命名空間,以非 root 權限執行 Kubernetes 節點元件,例如 kubelet、CRI、OCI 和 CNI。

此技術也稱為無 Root 模式

開始之前

您的 Kubernetes 伺服器必須為 1.22 版或更新版本。若要檢查版本,請輸入 kubectl version

在無 Root Docker/Podman 內執行 Kubernetes

kind

kind 支援在無 Root Docker 或無 Root Podman 內執行 Kubernetes。

請參閱使用無 Root Docker 執行 kind

minikube

minikube 也支援在無 Root Docker 或無 Root Podman 內執行 Kubernetes。

請參閱 Minikube 文件

在非特權容器內執行 Kubernetes

sysbox

Sysbox 是一個開放原始碼容器執行期 (類似於 "runc"),支援在透過 Linux 使用者命名空間隔離的非特權容器內執行系統層級工作負載,例如 Docker 和 Kubernetes。

請參閱Sysbox 快速入門指南:Docker 中的 Kubernetes 以取得更多資訊。

Sysbox 支援在非特權容器內執行 Kubernetes,而無需 Cgroup v2,也無需 KubeletInUserNamespace 功能閘道。它透過在容器內公開特別製作的 /proc/sys 檔案系統以及其他幾種進階的作業系統虛擬化技術來實現此目的。

直接在主機上執行無 Root Kubernetes

K3s

K3s 實驗性地支援無 root 模式。

請參閱以無 Root 模式執行 K3s 以取得用法。

Usernetes

Usernetes 是 Kubernetes 的參考發行版本,可以在沒有 root 權限的情況下安裝在 $HOME 目錄下。

Usernetes 支援 containerd 和 CRI-O 作為 CRI 執行階段。Usernetes 支援使用 Flannel (VXLAN) 的多節點叢集。

請參閱Usernetes 儲存庫以了解用法。

手動部署在使用者命名空間中執行 kubelet 的節點

本節提供手動在使用者命名空間中執行 Kubernetes 的提示。

建立使用者命名空間

第一步是建立使用者命名空間

如果您嘗試在使用者命名空間容器(例如 Rootless Docker/Podman 或 LXC/LXD)中執行 Kubernetes,則一切就緒,您可以跳到下一個小節。

否則,您必須透過呼叫帶有 CLONE_NEWUSERunshare(2) 來自行建立使用者命名空間。

也可以使用命令列工具(例如)來解除共用使用者命名空間

在解除共用使用者命名空間後,您還必須解除共用其他命名空間,例如掛載命名空間。

在解除共用掛載命名空間後,您 *不* 需要呼叫 chroot()pivot_root(),但是,您必須在命名空間 *內* 的幾個目錄上掛載可寫入的檔案系統。

至少,以下目錄需要在命名空間 *內* (而不是命名空間 *外*) 可寫入

  • /etc
  • /run
  • /var/logs
  • /var/lib/kubelet
  • /var/lib/cni
  • /var/lib/containerd (適用於 containerd)
  • /var/lib/containers (適用於 CRI-O)

建立委派的 cgroup 樹狀結構

除了使用者命名空間之外,您還需要具有 cgroup v2 的可寫入 cgroup 樹狀結構。

如果您嘗試在基於 systemd 的主機上的 Rootless Docker/Podman 或 LXC/LXD 中執行 Kubernetes,則一切就緒。

否則,您必須建立具有 Delegate=yes 屬性的 systemd 單元,以委派具有可寫入權限的 cgroup 樹狀結構。

在您的節點上,systemd 必須已設定為允許委派;如需更多詳細資訊,請參閱 Rootless Containers 文件中的 cgroup v2

設定網路

節點元件的網路命名空間必須具有非迴路介面,例如可以使用 slirp4netnsVPNKitlxc-user-nic(1) 進行設定。

Pod 的網路命名空間可以使用常規 CNI 外掛程式進行設定。對於多節點網路,已知 Flannel (VXLAN, 8472/UDP) 可以運作。

諸如 kubelet 埠 (10250/TCP) 和 NodePort 服務埠等埠必須使用外部埠轉發器(例如 RootlessKit、slirp4netns 或 socat(1))從節點網路命名空間公開到主機。

您可以使用來自 K3s 的埠轉發器。請參閱以 Rootless 模式執行 K3s 以取得更多詳細資訊。實作可以在 k3s 的 pkg/rootlessports 套件中找到。

設定 CRI

kubelet 依賴容器執行階段。您應該部署容器執行階段 (例如 containerd 或 CRI-O),並確保它在 kubelet 啟動之前在使用者命名空間內執行。

自 containerd 1.4 起,支援在使用者命名空間中執行 containerd 的 CRI 外掛程式。

在使用者命名空間中執行 containerd 需要以下設定。

version = 2

[plugins."io.containerd.grpc.v1.cri"]
# Disable AppArmor
  disable_apparmor = true
# Ignore an error during setting oom_score_adj
  restrict_oom_score_adj = true
# Disable hugetlb cgroup v2 controller (because systemd does not support delegating hugetlb controller)
  disable_hugetlb_controller = true

[plugins."io.containerd.grpc.v1.cri".containerd]
# Using non-fuse overlayfs is also possible for kernel >= 5.11, but requires SELinux to be disabled
  snapshotter = "fuse-overlayfs"

[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
# We use cgroupfs that is delegated by systemd, so we do not use SystemdCgroup driver
# (unless you run another systemd in the namespace)
  SystemdCgroup = false

設定檔的預設路徑為 /etc/containerd/config.toml。路徑可以使用 containerd -c /path/to/containerd/config.toml 指定。

自 CRI-O 1.22 起,支援在使用者命名空間中執行 CRI-O。

CRI-O 需要設定環境變數 _CRIO_ROOTLESS=1

也建議以下設定

[crio]
  storage_driver = "overlay"
# Using non-fuse overlayfs is also possible for kernel >= 5.11, but requires SELinux to be disabled
  storage_option = ["overlay.mount_program=/usr/local/bin/fuse-overlayfs"]

[crio.runtime]
# We use cgroupfs that is delegated by systemd, so we do not use "systemd" driver
# (unless you run another systemd in the namespace)
  cgroup_manager = "cgroupfs"

設定檔的預設路徑為 /etc/crio/crio.conf。路徑可以使用 crio --config /path/to/crio/crio.conf 指定。

設定 kubelet

在使用者命名空間中執行 kubelet 需要以下設定

apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
featureGates:
  KubeletInUserNamespace: true
# We use cgroupfs that is delegated by systemd, so we do not use "systemd" driver
# (unless you run another systemd in the namespace)
cgroupDriver: "cgroupfs"

當啟用 KubeletInUserNamespace 功能閘道時,kubelet 會忽略在節點上設定以下 sysctl 值期間可能發生的錯誤。

  • vm.overcommit_memory
  • vm.panic_on_oom
  • kernel.panic
  • kernel.panic_on_oops
  • 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 需要以下設定

apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
mode: "iptables" # or "userspace"
conntrack:
# Skip setting sysctl value "net.netfilter.nf_conntrack_max"
  maxPerCore: 0
# Skip setting "net.netfilter.nf_conntrack_tcp_timeout_established"
  tcpEstablishedTimeout: 0s
# Skip setting "net.netfilter.nf_conntrack_tcp_timeout_close"
  tcpCloseWaitTimeout: 0s

注意事項

  • 大多數「非本機」磁碟區驅動程式(例如 nfsiscsi)都無法運作。已知本機磁碟區(例如 localhostPathemptyDirconfigMapsecretdownwardAPI)可以運作。

  • 某些 CNI 外掛程式可能無法運作。已知 Flannel (VXLAN) 可以運作。

如需更多資訊,請參閱 rootlesscontaine.rs 網站上的注意事項和未來工作頁面。

另請參閱

此頁面上的項目參考提供 Kubernetes 所需功能的協力廠商產品或專案。Kubernetes 專案作者不對這些協力廠商產品或專案負責。如需更多詳細資訊,請參閱 CNCF 網站指南

在建議新增額外的協力廠商連結的變更之前,您應該閱讀內容指南

上次修改時間:2023 年 1 月 11 日上午 11:12 PST:更新 /tasks/administer-cluster 區段中的頁面權重 (b1202c78ff)