Kubernetes v1.37 переводить функціональну можливість KubeletInUserNamespace в бета. Коли ця функціональна можливість увімкнена, всі компоненти вузла (kubelet, CRI та OCI середовища виконання контейнерів, CNI втулки та kube-proxy) можуть працювати як non-root користувач на хості, використовуючи Linux user namespace (простір імен користувача). Цей підхід також відомий як rootless mode. Робота почалася як експеримент у 2018 році, і була обʼєднана в Kubernetes v1.22 (2021) як альфа-функція (Kubernetes Enhancement Proposal KEP-2033).
Цю функцію не слід плутати з user namespaces для Podʼів (hostUsers: false з функціональною можливістю UserNamespacesSupport, GA з v1.36), що розміщує Podʼи в user namespaces, але все ще запускає компоненти вузла як root. Ці дві функції не конфліктують. Крім того, їх можна поєднати для вкладення Kubernetes у Kubernetes без необхідності повного privileged: true.
Тому що компоненти вузла історично мали вразливості прориву контейнера (container-breakout vulnerabilities), які могли скомпрометувати повні root привілеї на хості.
Приклади таких вразливостей включають:
kernel.core_pattern, що призводило до довільного виконання коду як root на хостіgitRepo (gitRepo томи мали схожу вразливість, CVE-2018-11235, ще у 2018 році)/proc/sysrq-trigger та /proc/sys/kernel/core_patternЗапускаючи компоненти вузла в user namespace, потенційна шкода обмежується обліковим записом non-root користувача. Зокрема, атакуючий не може приховати своє втручання, модифікуючи ядро, завантажувач або прошивку.
Слід все ж зазначити, що user namespaces не ефективні для помʼякшення вразливостей у самому ядрі. User namespaces слід використовувати в поєднанні з традиційними заходами зміцнення безпеки, такими як seccomp для запобігання виклику контейнерами непотрібних системних викликів.
hostUsers: false), ізолюючи робочі навантаження суворіше, ніж Kubernetes API namespaces.Ядро Linux — user namespace відображає non-root користувача рівня хосту (напр., UID 1000) на користувача fake root всередині простору імен. Привілеї UID 0 обмежені внутрішньою частиною простору імен. Fake root достатній для більшості задач компонентів вузла: монтування томів, створення cgroups та налаштування мережевих просторів імен Podʼів. Він все ще йде з деякими застереженнями, які можуть ламати сумісність з певними CNI та CSI драйверами.
User namespace має бути створений поза Kubernetes. Наприклад, Rootless Docker можна використати для підготовки user namespace, в якому запускається Kubernetes.
Сама функціональна можливість KubeletInUserNamespace досить проста: по суті, вона просто дозволяє kubelet ігнорувати помилки дозволів, що виникають при встановленні деяких значень sysctl (напр., vm.overcommit_memory та kernel.panic) та при спостереженні за повідомленнями ядра через /dev/kmsg.
Дивіться Running Kubernetes Node Components as a Non-root User для додаткової інформації.
KubeletInUserNamespace тепер стандартно увімкнена. Її увімкнення автоматично не розміщує kubelet у user namespace, тому нічого не змінюється для наявних «rootful» кластерів.kubectl get nodes -o yaml тепер повідомляє, чи запущені вузли в user namespace через властивість runningInUserNamespace. Адміністратор кластера може використати цю властивість для встановлення міток або taints на вузлах, щоб уникнути планування робочих навантажень, що потребують реальних root привілеїв (напр., деякі інсталятори CNI втулків) на rootless вузлах.Деякі повʼязані покращення також відбулися поза просуванням цієї функціональної можливості:
UserNamespacesSupport стандартно увімкнено, дозволяючи створювати Podʼи з user namespace (hostUsers: false) без додаткової конфігурації.Завдяки цим покращенням, Kubernetes-кластер з KubeletInUserNamespace тепер також може бути вкладеним усередині Kubernetes Podʼа з hostUsers: false (UserNamespacesSupport).
Найпростіший спосіб — використати kind (проєкт Kubernetes SIG Testing) для запуску Kubernetes-кластера в rootless Docker, rootless nerdctl або rootless Podman:
# Приклад з Docker
dockerd-rootless-setuptool.sh install
kind create cluster
Залежно від конфігурації хоста, вам може знадобитися додаткова конфігурація для systemd, модулів ядра, sysctl тощо.
Дивіться документацію Docker та документацію kind для додаткової інформації.
minikube (проєкт Kubernetes SIG Cluster Lifecycle) також підтримує запуск Kubernetes-кластера в rootless Docker або rootless Podman:
dockerd-rootless-setuptool.sh install
minikube start --driver=docker
Дивіться документацію minikube для додаткової інформації.
Usernetes (сторонній проєкт) є дистрибутивом rootless Kubernetes, що підтримується автором цієї статті. Проєкт почався у 2018 році, і саме звідси початково прийшла функціональна можливість KubeletInUserNamespace.
На відміну від kind та minikube, Usernetes підтримує створення кластера з кількома rootless вузлами Docker / Podman / nerdctl, зʼєднаними через VXLAN за допомогою Flannel CNI плагіна.
Usernetes також експериментально підтримує режим Kubernetes-in-Kubernetes.
k3s (проєкт CNCF Sandbox) також підтримує rootless mode. На відміну від kind, minikube та поточного покоління Usernetes, rootless k3s не покладається на зовнішнє середовище виконання контейнерів, таке як rootless Docker.
Залежно від відгуків та впровадження, проєкт Kubernetes планує просунути цю функцію до General Availability (GA) у майбутньому релізі. Якщо у вас є відгук щодо цієї функції, будь ласка, створіть тікет в репозиторії kubernetes/kubernetes.
Проєкт також обговорює кілька Kubernetes Enhancement Proposals, які можуть сприяти спрощенню Kubernetes-in-Kubernetes з цією функцією:
Ми завжди вітаємо нових учасників. Якщо ви хочете приєднатися, ви можете приєднатися до Node Special Interest Group (SIG Node).
Якщо ви хочете поділитися відгуком, ви можете це зробити на нашому публічному Slack-каналі (відвідайте https://slack.k8s.io/ для запрошення, якщо потрібне).
Щира подяка всім, хто допоміг спроєктувати та реалізувати цю функцію, включно з (в алфавітному порядку):