以非 Root 使用者身分執行 Kubernetes 節點元件
Kubernetes v1.22 [alpha]
本文件說明如何透過使用使用者命名空間,以非 root 權限執行 Kubernetes 節點元件,例如 kubelet、CRI、OCI 和 CNI。
此技術也稱為無 Root 模式。
開始之前
您的 Kubernetes 伺服器必須為 1.22 版或更新版本。若要檢查版本,請輸入 kubectl version
。
- 啟用 Cgroup v2
- 啟用具有使用者工作階段的 systemd
- 根據主機 Linux 發行版本配置數個 sysctl 值
- 確保您的非特權使用者已列在
/etc/subuid
和/etc/subgid
中 - 啟用
KubeletInUserNamespace
功能閘道
在無 Root Docker/Podman 內執行 Kubernetes
kind
kind 支援在無 Root Docker 或無 Root Podman 內執行 Kubernetes。
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 的提示。
注意
本節旨在供 Kubernetes 發行版本的開發人員閱讀,而非終端使用者。建立使用者命名空間
第一步是建立使用者命名空間。
如果您嘗試在使用者命名空間容器(例如 Rootless Docker/Podman 或 LXC/LXD)中執行 Kubernetes,則一切就緒,您可以跳到下一個小節。
否則,您必須透過呼叫帶有 CLONE_NEWUSER
的 unshare(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 樹狀結構。
注意
Kubernetes 支援在使用者命名空間中執行節點元件需要 cgroup v2。不支援 Cgroup v1。如果您嘗試在基於 systemd 的主機上的 Rootless Docker/Podman 或 LXC/LXD 中執行 Kubernetes,則一切就緒。
否則,您必須建立具有 Delegate=yes
屬性的 systemd 單元,以委派具有可寫入權限的 cgroup 樹狀結構。
在您的節點上,systemd 必須已設定為允許委派;如需更多詳細資訊,請參閱 Rootless Containers 文件中的 cgroup v2。
設定網路
節點元件的網路命名空間必須具有非迴路介面,例如可以使用 slirp4netns、VPNKit 或 lxc-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
注意事項
大多數「非本機」磁碟區驅動程式(例如
nfs
和iscsi
)都無法運作。已知本機磁碟區(例如local
、hostPath
、emptyDir
、configMap
、secret
和downwardAPI
)可以運作。某些 CNI 外掛程式可能無法運作。已知 Flannel (VXLAN) 可以運作。
如需更多資訊,請參閱 rootlesscontaine.rs 網站上的注意事項和未來工作頁面。
另請參閱
此頁面上的項目參考提供 Kubernetes 所需功能的協力廠商產品或專案。Kubernetes 專案作者不對這些協力廠商產品或專案負責。如需更多詳細資訊,請參閱 CNCF 網站指南。
在建議新增額外的協力廠商連結的變更之前,您應該閱讀內容指南。