# Простори імен користувачів

LLMS index: [llms.txt](/llms.txt)

---

<!-- overview -->








  <div class="feature-state-notice feature-stable" title="Функціональна можливість: UserNamespacesSupport">
              <span class="feature-state-name">СТАН ФУНКЦІОНАЛУ:</span> 
              <code>Kubernetes v1.36 [stable]</code>(стандартно увімкнено)</div>


Ця сторінка пояснює, як використовуються простори імен користувачів у Podʼах Kubernetes. Простір імен користувача ізолює користувача, який працює всередині контейнера, від користувача на хості.

Процес, який працює як root в контейнері, може працювати як інший (не-root) користувач на хості; іншими словами, процес має повні привілеї для операцій всередині простору користувача, але не має привілеїв для операцій за його межами.

Ви можете використовувати цю функцію, щоб зменшити можливий збиток, який може заподіяти скомпрометований контейнер хосту або іншим Podʼам на тому ж вузлі. Є [кілька вразливостей безпеки][KEP-vulns], які оцінено як **ВИСОКІ** або **КРИТИЧНІ**, і які не можна було б використати при активних просторах користувачів. Передбачається, що простір користувачів також буде запобігати деяким майбутнім вразливостям.

[KEP-vulns]: https://github.com/kubernetes/enhancements/tree/217d790720c5aef09b8bd4d6ca96284a0affe6c2/keps/sig-node/127-user-namespaces#motivation

<!-- body -->

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

<div class="alert alert-secondary callout third-party-content" role="note"><strong>Примітка:</strong>&puncsp;Цей розділ містить посилання на проєкти сторонніх розробників, які надають функціонал, необхідний для Kubernetes. Автори проєкту Kubernetes не несуть відповідальності за ці проєкти. Проєкти вказано в алфавітному порядку. Щоб додати проєкт до цього списку, ознайомтеся з <a href="/uk/docs/contribute/style/content-guide/#third-party-content">посібником з контенту</a> перед надсиланням змін. <a href="#third-party-content-disclaimer">Докладніше.</a></div>


Це функція, доступна лише для Linux, і потребує підтримки в Linux для монтування idmap на використовуваних файлових системах. Це означає:

* На вузлі файлова система, яку ви використовуєте для `/var/lib/kubelet/pods/`, або спеціальна тека, яку ви конфігуруєте для цього, повинна підтримувати монтування idmap.
* Всі файлові системи, які використовуються в томах Podʼа, повинні підтримувати монтування idmap.

На практиці це означає, що вам потрібне ядро Linux принаймні версії 6.3, оскільки tmpfs почав підтримувати монтування idmap у цій версії. Це зазвичай потрібно, оскільки кілька функцій Kubernetes використовують tmpfs (токен службового облікового запису, який монтується типово, використовує tmpfs, аналогічно Secrets використовують tmpfs та інше).

Деякі популярні файлові системи, які підтримують монтування idmap в Linux 6.3, — це: btrfs, ext4, xfs, fat, tmpfs, overlayfs.

Крім того, середовище виконання контейнерів та його базове середовище OCI повинні підтримувати простори користувачів. Підтримку надають наступні середовища OCI:

* [crun](https://github.com/containers/crun) версії 1.9 або вище (рекомендована версія 1.13+).
* [runc](https://github.com/opencontainers/runc) версії 1.2 або вище.

Для використання просторів користувачів з Kubernetes також потрібно використовувати CRI <a class='glossary-tooltip' title='Середовище виконання контейнера — це програмне забезпечення, яке відповідає за запуск та виконання контейнерів.' data-bs-toggle='tooltip' data-bs-placement='top' href='/uk/docs/setup/production-environment/container-runtimes' target='_blank' aria-label='середовища виконання контейнерів'>середовища виконання контейнерів</a>, щоб мати можливість використовувати цю функцію з Podʼами Kubernetes:

* containerd: версія 2.0 (і новіші) підтримує користувацькі простори імен для контейнерів.
* CRI-O: версія 1.25 (і пізніше) підтримує простори користувачів для контейнерів.

Стан підтримки просторів користувачів в cri-dockerd відстежується у [тікеті][CRI-dockerd-issue] на GitHub.

[CRI-dockerd-issue]: https://github.com/Mirantis/cri-dockerd/issues/74

## Вступ {#introduction}

Простори користувачів — це функція Linux, яка дозволяє зіставляти користувачів у контейнері з користувачами на хості. Крім того, можливості, надані Pod в просторі користувача, є дійсними лише в просторі та не виходять за його межі.

Pod може обрати використовувати простори користувачів, встановивши поле `pod.spec.hostUsers` в `false`.

Kubelet вибере host UID/GID, до якого зіставлено Pod, і зробить це так, щоб гарантувати, що жоден з Podʼів на одному вузлі не використовує те саме зіставлення.

Поля `runAsUser`, `runAsGroup`, `fsGroup` тощо в `pod.spec` завжди посилаються на користувача всередині контейнера. Ці користувачі використовуватимуться для монтування томів (вказаних у `pod.spec.volumes`), і тому UID/GID хосту не матиме жодного впливу на запис/читання з томів, які може монтувати Pod. Іншими словами, inode, створені/зчитані у томах, змонтованих podʼом, будуть такими ж, як би pod не використовував простори імен користувачів.

Таким чином, pod може легко вмикати та вимикати простори імен користувачів (не впливаючи на права власності на файли тома), а також надавати спільний доступ до томів з podʼами без просторів імен користувачів, просто вказавши відповідних користувачів всередині контейнера (`RunAsUser`, `RunAsGroup`, `fsGroup` і т.д.). Це стосується будь-якого тому, який може бути змонтовано в pod, включно з `hostPath` (якщо podʼу дозволено монтувати томи `hostPath`).

Стандартно, дійсні UID/GID, коли ця функція активована, є у діапазоні 0-65535. Це стосується файлів та процесів (`runAsUser`, `runAsGroup` і т. д.).

Файли з UID/GID за межами цього діапазону будуть вважатися належними переповненню ID, яке зазвичай дорівнює 65534 (налаштовано в `/proc/sys/kernel/overflowuid` та `/proc/sys/kernel/overflowgid`). Однак їх неможливо змінити, навіть якщо запущено як user/group 65534.

Якщо діапазон 0-65535 розширено за допомогою  налаштування, вищезазначені обмеження застосовуються до розширеного діапазону.

Більшість застосунків, які потребують запуску з правами root, але не мають доступу до інших просторів імен хоста чи ресурсів, повинні продовжувати працювати без змін, якщо простори користувачів активовано.

## Розуміння просторів користувачів для Podʼів {#pods-and-userns}

Кілька середовищ виконання контейнерів із їхньою типовою конфігурацією (таких як Docker Engine, containerd, CRI-O) використовують простори імен Linux для ізоляції. Існують інші технології, які також можна використовувати з цими середовищами (наприклад, Kata Containers використовує віртуальні машини замість просторів імен Linux). Ця стосується середовищ виконання контейнерів, які використовують простори імен Linux для ізоляції.

При стандартному створенні Podʼа використовуються різні нові простори імен для ізоляції: мережевий простір імен для ізоляції мережі контейнера, простір імен PID для ізоляції виду процесів і т.д. Якщо використовується простір користувачів, це ізолює користувачів у контейнері від користувачів на вузлі.

Це означає, що контейнери можуть працювати як root та зіставлятись з не-root користувачами на хості. Всередині контейнера процес буде вважати себе root (і, отже, інструменти типу `apt`, `yum`, ін. працюватимуть нормально), тоді як насправді процес не має привілеїв на хості. Ви можете перевірити це, наприклад, якщо ви перевірите, як користувач запущений у контейнері, виконавши `ps aux` з хосту. Користувач, якого показує `ps`, не той самий, що і користувач, якого ви бачите, якщо ви виконаєте команду `id` всередині контейнера.

Ця абстракція обмежує те, що може трапитися, наприклад, якщо контейнеру вдасться втекти на хост. Оскільки контейнер працює як непривілейований користувач на хості, обмежено те, що він може зробити на хості.

Крім того, оскільки користувачі в кожному Podʼі будуть зіставлені з різними користувачами на хості, обмежено те, що вони можуть зробити з іншими Podʼами.

Можливості, надані Podʼа, також обмежуються простором користувача Podʼа і в основному є недійсними поза межами його простору, а деякі навіть абсолютно нечинні. Ось два приклади:

* `CAP_SYS_MODULE` не має жодного ефекту, якщо зіставлено в Podʼі з використанням просторів користувачів, Pod не може завантажити модулі ядра.
* `CAP_SYS_ADMIN` обмежений простором користувача Podʼа та є недійсним поза його межами.

Без використання просторів користувачів контейнер, який працює як root, у разі втечі контейнера, має привілеї root на вузлі. І якщо контейнеру надано деякі можливості, ці можливості є дійсними на хості. Цього не відбувається, коли ми використовуємо простори користувачів.

Якщо ви хочете дізнатися більше подробиць про те, що змінюється при використанні просторів користувачів, дивіться `man 7 user_namespaces`.

## Налаштування вузла для підтримки просторів користувачів {#set-up-a-node-to-support-user-namespaces}

Типово kubelet призначає UID/GID Podʼам вище діапазону 0-65535, ґрунтуючись на припущенні, що файли та процеси хоста використовують UID/GID у цьому діапазоні, що є стандартним для більшості дистрибутивів Linux. Цей підхід запобігає будь-якому перекриттю між UID/GID хостом та UID/GID Podʼів.

Уникнення перекриття є важливим для помʼякшення впливу вразливостей, таких як [CVE-2021-25741][CVE-2021-25741], де потенційно Pod може читати довільні файли на хості. Якщо UID/GID Podʼа та хосту не перекриваються, те, що може робити Pod, обмежено: UID/GID Podʼа не буде відповідати власнику/групі файлів хосту.

kubelet може використовувати власний діапазон для ідентифікаторів користувачів та груп для Podʼів. Для налаштування власного діапазону, вузол повинен мати:

* Користувача `kubelet` в системі (ви не можете використовувати інше імʼя користувача тут)
* Встановлений бінарний файл `getsubids` (частина [shadow-utils][shadow-utils]) та `PATH` для бінарного файлу kubelet.
* Конфігурацію допоміжних UID/GID для користувача `kubelet` (див. [`man 5 subuid`](https://man7.org/linux/man-pages/man5/subuid.5.html) та [`man 5 subgid`](https://man7.org/linux/man-pages/man5/subgid.5.html)).

Цей параметр лише збирає конфігурацію діапазону UID/GID та не змінює користувача, який виконує `kubelet`.

Вам потрібно дотримуватися деяких обмежень для допоміжного діапазону ID, який ви призначаєте користувачу `kubelet`:

* Допоміжний ідентифікатор користувача, який визначає початок діапазону UID для Podʼів, **має** бути кратним 65536 і також повинен бути більшим або рівним 65536. Іншими словами, ви не можете використовувати жодний ідентифікатор з діапазону 0-65535 для Podʼів; kubelet накладає це обмеження, щоб ускладнити створення ненавмисно незахищеної конфігурації.

* Кількість допоміжних ID повинна бути кратною 65536.

* Кількість допоміжних ID повинна бути щонайменше `65536 x <maxPods>`, де `<maxPods>` — максимальна кількість Podʼів, які можуть запускатися на вузлі.

* Ви повинні призначити однаковий діапазон як для ідентифікаторів користувача, так і для ідентифікаторів груп. Не має значення, які інші користувачі мають діапазони ідентифікаторів користувача, які не збігаються з діапазонами ідентифікаторів груп.

* Жоден з призначених діапазонів не повинен перекриватися з будь-яким іншим призначенням.

* Конфігурація допоміжних ID повинна бути лише одним рядком. Іншими словами, ви не можете мати кілька діапазонів.

Наприклад, ви можете визначити `/etc/subuid` та `/etc/subgid`, щоб обидва мали такі записи для користувача `kubelet`:

```none
# Формат такий
#   імʼя:першийID:кількість ідентифікаторів
# де
# - першийID - 65536 (мінімально можливе значення)
# - кількість ідентифікаторів - 110 (стандартний ліміт кількості) * 65536
kubelet:65536:7208960
```

[CVE-2021-25741]: https://github.com/kubernetes/kubernetes/issues/104980
[shadow-utils]: https://github.com/shadow-maint/shadow

## Обрахунок ID для кожного Podʼа {#id-count-for-each-of-pods}

Починаючи з Kubernetes v1.33 можна встановити обрахунок ID для кожного Podʼа в [`KubeletConfiguration`](/docs/reference/config-api/kubelet-config.v1beta1/).

```yaml
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
userNamespaces:
  idsPerPod: 1048576
```

Значення `idsPerPod` (uint32) має бути кратним 65536. Стандартне значення — 65536. Це значення застосовується лише до контейнерів, створених після запуску kubelet з цією `KubeletConfiguration`. На запущені контейнери ця конфігурація не впливає.

У версіях Kubernetes до v1.33 кількість ідентифікаторів для кожного контейнера була жорстко встановлена на рівні 65536.

## Інтеграція з перевіркою допуску безпеки Podʼів {#integration-with-pod-security-admission-checks}

Для Podʼів Linux, які увімкнули простори користувачів, Kubernetes послаблює застосування [Стандартів безпеки Podʼа](/docs/concepts/security/pod-security-standards) контрольованим способом.

Якщо ви створите Pod, який використовує простори користувачів, наступні поля не будуть обмежені навіть в контекстах, які застосовують _Baseline_ чи _Restricted_ Podʼа. Це не становить проблему безпеки, оскільки `root` всередині Podʼа з просторами користувачів фактично посилається на користувача всередині контейнера, який ніколи не зіставляється з привілейованим користувачем на хості. Ось список полів, які **не** перевіряються для Podʼів в цих обставинах:

* `spec.securityContext.runAsNonRoot`
* `spec.containers[*].securityContext.runAsNonRoot`
* `spec.initContainers[*].securityContext.runAsNonRoot`
* `spec.ephemeralContainers[*].securityContext.runAsNonRoot`
* `spec.securityContext.runAsUser`
* `spec.containers[*].securityContext.runAsUser`
* `spec.initContainers[*].securityContext.runAsUser`
* `spec.ephemeralContainers[*].securityContext.runAsUser`

Крім того, якщо под знаходиться в контексті зі стандартом безпеки подів _Baseline_, перевірка наступних полів також буде помʼякшена:

* `spec.containers[*].securityContext.procMount`
* `spec.initContainers[*].securityContext.procMount`
* `spec.ephemeralContainers[*].securityContext.procMount`

Зі стандартом безпеки подів _Restricted_ под все одно повинен стандартно використовувати лише ProcMount або порожній ProcMount.

## Обмеження {#limitations}

При використанні просторів користувачів для Podʼа заборонено використовувати інші простори імен хосту. Зокрема, якщо ви встановите `hostUsers: false`, ви не маєте права встановлювати будь-яке з наступного:

* `hostNetwork: true`
* `hostIPC: true`
* `hostPID: true`

Жоден контейнер також не може використовувати `volumeDevices` (блокові томи raw, такі як /dev/sda). Це стосується всіх масивів контейнерів у специфікації pod:

* `containers`
* `initContainers`
* `ephemeralContainers`

### Підтримка файлової системи {#filesystem-support}

Podʼи, які використовують простір імен користувачів, потребують, щоб файлова система підтримувала монтування idmap. Деякі файлові системи не підтримують монтування idmap, і тому не можуть використовуватися з просторами користувачів. У таких випадках будуть згенеровані наступні події. Зверніть увагу, що деталі попередження залежать від середовища виконання контейнерів, яке ви використовуєте.

```none
Warning  Failed 1s kubelet Error: failed to create containerd task: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: error during container init: failed to fulfil mount request: failed to set MOUNT_ATTR_IDMAP on ${your mount path} invalid argument (maybe the filesystem used doesn't support idmap mounts on this kernel?): unknown
```

NFS томи не можуть бути змонтовані в Pod з простором імен користувачів, оскільки клієнт Linux NFS ще не підтримує монтування idmap. Для поточного списку підтримуваних файлових систем дивіться сторінку керівництва Linux [`mount_setattr(2)`](https://man7.org/linux/man-pages/man2/mount_setattr.2.html).

## Метрики та спостережуваність {#metrics-and-observability}

Kubelet експортує дві метрики prometheus, специфічні для просторів користувачів:

* `started_user_namespaced_pods_total`: лічильник, який відстежує кількість спроб створення Podʼів з просторами користувачів.
* `started_user_namespaced_pods_errors_total`: лічильник, який відстежує кількість помилок при створенні Podʼів з просторами користувачів.

## Що далі

* Подивіться [Використання простору користувача в Podʼах](/docs/tasks/configure-pod-container/user-namespaces/)
