Запуск компонентів вузла Kubernetes користувачем без прав root
Kubernetes v1.22 [alpha]
У цьому документі описано, як запустити компоненти вузла Kubernetes, такі як kubelet, CRI, OCI та CNI, без прав root, використовуючи простір імен користувача.
Ця техніка також відома як rootless mode.
Примітка:
У цьому документі описано, як запустити компоненти вузла Kubernetes (і відповідно Podʼи), як не-root користувач.
Якщо ви шукаєте лише як запустити Pod як не-root користувача, див. SecurityContext.
Перш ніж ви розпочнете
Версія вашого Kubernetes сервера має бути не старішою ніж 1.22.
Для перевірки версії введіть kubectl version
.
- Увімкніть Cgroup v2
- Увімкніть systemd з сеансом користувача
- Налаштуйте кілька значень sysctl, залежно від розподілу Linux хосту
- Переконайтеся, що ваш не привілейований користувач вказаний у
/etc/subuid
та/etc/subgid
- Увімкніть функціональну можливість
KubeletInUserNamespace
Запуск 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, а не кінцевими користувачами.Створення простору користувача
Першим кроком є створення простору користувача.
Якщо ви намагаєтеся запустити 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 для запуску компонентів вузла у просторах користувача передбачає використання cgroup v2. Cgroup v1 не підтримується.Якщо ви намагаєтеся запустити 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 для отримання докладної інформації.
Ознайомтесь з посібником з контенту перед тим, як пропонувати додавання посилання на стороні компоненти.