Запуск компонентів вузла Kubernetes користувачем без прав root

СТАН ФУНКЦІОНАЛУ: Kubernetes v1.22 [alpha]

У цьому документі описано, як запустити компоненти вузла Kubernetes, такі як kubelet, CRI, OCI та CNI, без прав root, використовуючи простір імен користувача.

Ця техніка також відома як rootless mode.

Перш ніж ви розпочнете

Версія вашого Kubernetes сервера має бути не старішою ніж 1.22. Для перевірки версії введіть kubectl version.

Запуск Kubernetes в Rootless Docker або Rootless Podman

kind

kind підтримує запуск Kubernetes в середовищі Rootless Docker або Rootless Podman.

Див. Запуск kind з Rootless Docker.

minikube

minikube також підтримує запуск Kubernetes в середовищі Rootless Docker або Rootless Podman.

Див. документацію Minikube:

Запуск Kubernetes всередині непривілейованих контейнерів

sysbox

Sysbox — це відкрите програмне забезпечення для виконання контейнерів (подібне до "runc"), яке підтримує запуск робочих навантажень на рівні системи, таких як Docker та Kubernetes, всередині непривілейованих контейнерів, ізольованих за допомогою просторів користувачів Linux.

Дивіться Sysbox Quick Start Guide: Kubernetes-in-Docker для отримання додаткової інформації.

Sysbox підтримує запуск Kubernetes всередині непривілейованих контейнерів без потреби в Cgroup v2 і без використання KubeletInUserNamespace. Він досягає цього за допомогою розкриття спеціально створених файлових систем /proc та /sys всередині контейнера, а також кількох інших передових технік віртуалізації операційної системи.

Запуск Rootless Kubernetes безпосередньо на хості

K3s

K3s експериментально підтримує режим без root-прав.

Дивіться Запуск K3s у режимі Rootless для використання.

Usernetes

Usernetes — це референсний дистрибутив Kubernetes, який може бути встановлений у теці $HOME без привілеїв root.

Usernetes підтримує як containerd, так і CRI-O як середовище виконання контейнерів CRI. Usernetes підтримує багатовузлові кластери з використанням Flannel (VXLAN).

Дивіться репозиторій Usernetes для використання.

Ручне розгортання вузла, який використовує kubelet в просторі користувача

У цьому розділі надаються вказівки для запуску Kubernetes у просторі користувача вручну.

Створення простору користувача

Першим кроком є створення простору користувача.

Якщо ви намагаєтеся запустити Kubernetes в контейнері з простором користувача, такому як Rootless Docker/Podman або LXC/LXD, ви готові та можете перейти до наступного підрозділу.

Інакше вам доведеться створити простір користувача самостійно, викликавши unshare(2) з CLONE_NEWUSER.

Простір користувача також можна відокремити за допомогою інструментів командного рядка, таких як:

Після відокремлення простору користувача вам також доведеться відокремити інші простори імен, такі як простір імен монтування.

Вам не потрібно викликати chroot() або pivot_root() після відокремлення простору імен монтування, однак вам потрібно буде монтувати записувані файлові системи у кількох теках в просторі імен.

Принаймні, наступні теки повинні бути записуваними в просторі імен (не поза простором імен):

  • /etc
  • /run
  • /var/logs
  • /var/lib/kubelet
  • /var/lib/cni
  • /var/lib/containerd (для containerd)
  • /var/lib/containers (для CRI-O)

Створення делегованого дерева cgroup

Крім простору користувача, вам також потрібно мати записуване дерево cgroup з cgroup v2.

Якщо ви намагаєтеся запустити Kubernetes у Rootless Docker/Podman або LXC/LXD на хості на основі systemd, у вас все готове.

У противному вам доведеться створити службу systemd з властивістю Delegate=yes, щоб делегувати дерево cgroup з правами на запис.

На вашому вузлі система systemd вже повинна бути налаштована на дозвіл делегування; для отримання докладнішої інформації дивіться cgroup v2 в документації Rootless Containers.

Налаштування мережі

Простір імен мережі компонентів вузла повинен мати не-loopback інтерфейс, який, наприклад, може бути налаштований з використанням slirp4netns, VPNKit, або lxc-user-nic(1).

Простори імен мережі Podʼів можна налаштувати за допомогою звичайних втулків CNI. Для мережі з багатьма вузлами відомо, що Flannel (VXLAN, 8472/UDP) працює.

Порти, такі як порт kubelet (10250/TCP) і порти служби NodePort, повинні бути викриті з простору імен мережі вузла на хост зовнішнім перенаправлювачем портів, таким як RootlessKit, slirp4netns, або socat(1).

Ви можете використовувати перенаправлювач портів від K3s. Див. Запуск K3s в режимі без root-прав для отримання докладнішої інформації. Реалізацію можна знайти в пакунку pkg/rootlessports k3s.

Налаштування CRI

Kubelet покладається на середовище виконання контейнерів. Ви повинні розгорнути середовище виконання контейнерів, таке як containerd або CRI-O, і переконатися, що воно працює у просторі користувача до запуску kubelet.

Запуск CRI втулка containerd в просторі користувача підтримується з версії containerd 1.4.

Запуск containerd у просторі користувача вимагає наступних налаштувань.

version = 2

[plugins."io.containerd.grpc.v1.cri"]
# Вимкнути AppArmor
  disable_apparmor = true
# Ігнорувати помилку під час встановлення oom_score_adj
  restrict_oom_score_adj = true
# Вимкнути контролер hugetlb cgroup v2 (тому що systemd не підтримує делегування контролера hugetlb)
  disable_hugetlb_controller = true

[plugins."io.containerd.grpc.v1.cri".containerd]
# Можливий також використання non-fuse overlayfs для ядра >= 5.11, але потребує вимкненого SELinux
  snapshotter = "fuse-overlayfs"

[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
# Ми використовуємо cgroupfs, який делегується системою systemd, тому ми не використовуємо драйвер SystemdCgroup
# (якщо ви не запускаєте іншу систему systemd у просторі імен)
  SystemdCgroup = false

Типовий шлях конфігураційного файлу — /etc/containerd/config.toml. Шлях можна вказати з containerd -c /шлях/до/конфігураційного/файлу.toml.

Запуск CRI-O у просторі користувача підтримується з версії CRI-O 1.22.

CRI-O вимагає, щоб була встановлена змінна середовища _CRIO_ROOTLESS=1.

Також рекомендуються наступні налаштування:

[crio]
  storage_driver = "overlay"
# Можливий також використання non-fuse overlayfs для ядра >= 5.11, але потребує вимкненого SELinux
  storage_option = ["overlay.mount_program=/usr/local/bin/fuse-overlayfs"]

[crio.runtime]
# Ми використовуємо cgroupfs, який делегується системою systemd, тому ми не використовуємо драйвер "systemd"
# (якщо ви не запускаєте іншу систему systemd у просторі імен)
  cgroup_manager = "cgroupfs"

Типовий шлях конфігураційного файлу — /etc/crio/crio.conf. Шлях можна вказати з crio --config /шлях/до/конфігураційного/файлу/crio.conf.

Налаштування kubelet

Запуск kubelet у просторі користувача вимагає наступної конфігурації:

apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
featureGates:
  KubeletInUserNamespace: true
# Ми використовуємо cgroupfs, який делегується системою systemd, тому ми не використовуємо драйвер "systemd"
# (якщо ви не запускаєте іншу систему systemd у просторі імен)
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. Цей feature gate також дозволяє kube-proxy ігнорувати помилку під час встановлення RLIMIT_NOFILE.

KubeletInUserNamespace був введений у Kubernetes v1.22 зі статусом "alpha".

Запуск kubelet у просторі користувача без використання цього feature gate також можливий, шляхом монтування спеціально створеного файлової системи proc (як це робить Sysbox), але це не є офіційно підтримуваним.

Налаштування kube-proxy

Запуск kube-proxy у просторі користувача вимагає наступної конфігурації:

apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
mode: "iptables" # або "userspace"
conntrack:
# Пропустити встановлення значення sysctl "net.netfilter.nf_conntrack_max"
  maxPerCore: 0
# Пропустити встановлення "net.netfilter.nf_conntrack_tcp_timeout_established"
  tcpEstablishedTimeout: 0s
# Пропустити встановлення "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 для отримання докладної інформації.

Ознайомтесь з посібником з контенту перед тим, як пропонувати додавання посилання на стороні компоненти.

Змінено August 15, 2024 at 4:40 PM PST: upstream sync (6ec9cfeefc)