Kubernetes v1.35: Деталізоване управління допоміжними групами переходить в стан загальної доступності (GA)
Від імені Kubernetes SIG Node, ми раді оголосити про перехід деталізованого управління допоміжними групами до загальної доступності (GA) у Kubernetes v1.35!
Нове поле Pod supplementalGroupsPolicy було введено як opt-in альфа-функція для Kubernetes v1.31, а потім перейшло до бета у v1.33. Тепер ця функція є загальнодоступною. Ця функція дозволяє реалізувати більш точний контроль над допоміжними групами в контейнерах Linux, що може зміцнити позицію безпеки, особливо при доступі до томів. Крім того, вона також покращує прозорість деталей UID/GID у контейнерах, забезпечуючи покращений нагляд за безпекою.
Якщо ви плануєте оновити свій кластер з v1.32 або більш ранньої версії, будь ласка, зверніть увагу, що деякі зміни поведінки, що порушують сумісність, були введені з бета (v1.33). Для отримання додаткової інформації дивіться розділи змін поведінки, введених у бета та розгляди оновлення у попередньому блозі про перехід до бета.
Мотивація: Неявні членства в групах, визначені в /etc/group в образі контейнера
Навіть якщо більшість адміністраторів/користувачів кластерів Kubernetes можуть не бути обізнаними з цим, за звичай Kubernetes обʼєднує інформацію про групи з Podʼа з інформацією, визначеною в /etc/group в образі контейнера.
Ось приклад; маніфест Podʼа, який вказує spec.securityContext.runAsUser: 1000, spec.securityContext.runAsGroup: 3000 та spec.securityContext.supplementalGroups: 4000 як частину контексту безпеки Podʼа.
apiVersion: v1
kind: Pod
metadata:
name: implicit-groups-example
spec:
securityContext:
runAsUser: 1000
runAsGroup: 3000
supplementalGroups: [4000]
containers:
- name: example-container
image: registry.k8s.io/e2e-test-images/agnhost:2.45
command: [ "sh", "-c", "sleep 1h" ]
securityContext:
allowPrivilegeEscalation: false
Який результат команди id в контейнері example-container? Вихідні дані повинні бути схожими на це:
uid=1000 gid=3000 groups=3000,4000,50000
Звідки в групі допоміжних ідентифікаторів (groups поле) зʼявився ідентифікатор групи 50000, навіть якщо 50000 взагалі не визначено в маніфесті Podʼа? Відповідь — файл /etc/group в образі контейнера.
Перевірка вмісту файлу /etc/group в образі контейнера містить щось подібне до наступного:
user-defined-in-image:x:1000:
group-defined-in-image:x:50000:user-defined-in-image
Це показує, що первинний користувач контейнера 1000 належить до групи 50000 в останньому записі.
Таким чином, членство в групі, визначене в /etc/group в образі контейнера для первинного користувача контейнера, неявно обʼєднується з інформацією з Podʼа. Будь ласка, зверніть увагу, що це було дизайнерським рішенням, яке поточні реалізації CRI успадкували від Docker, і спільнота насправді ніколи не переосмислювала це до теперішнього часу.
Що з цим не так?
Неявно обʼєднана інформація про групи з /etc/group в образі контейнера становить ризик для безпеки. Ці неявні GID не можуть бути виявлені або перевірені механізмами політики, оскільки немає запису про них у маніфесті Podʼа. Це може призвести до несподіваних проблем з контролем доступу, особливо при доступі до томів (див. kubernetes/kubernetes#112879 для деталей), оскільки дозволи файлів контролюються UID/GIDs в Linux.
Деталізоване управління допоміжними групами в Pod: supplementaryGroupsPolicy
Щоб вирішити цю проблему, .spec.securityContext Pod тепер включає поле supplementalGroupsPolicy.
Це поле дозволяє вам контролювати, як Kubernetes обчислює допоміжні групи для процесів контейнера всередині Podʼа. Доступні політики:
Merge: Інформація про членство в групі, визначена в
/etc/groupдля первинного користувача контейнера, буде обʼєднана. Якщо не вказано, ця політика буде застосована (тобто типова поведінка для зворотної сумісності).Strict: Тільки ідентифікатори груп, вказані в
fsGroup,supplementalGroupsабоrunAsGroup, прикріплюються як допоміжні групи до процесів контейнера. Членства в групах, визначені в/etc/groupдля первинного користувача контейнера, ігноруються.
Я поясню, як працює політика Strict. Наступний маніфест Podʼа вказує supplementalGroupsPolicy: Strict:
apiVersion: v1
kind: Pod
metadata:
name: strict-supplementalgroups-policy-example
spec:
securityContext:
runAsUser: 1000
runAsGroup: 3000
supplementalGroups: [4000]
supplementalGroupsPolicy: Strict
containers:
- name: example-container
image: registry.k8s.io/e2e-test-images/agnhost:2.45
command: [ "sh", "-c", "sleep 1h" ]
securityContext:
allowPrivilegeEscalation: false
Результат команди id в контейнері example-container повинен бути схожим на це:
uid=1000 gid=3000 groups=3000,4000
Ви можете побачити, що політика Strict може виключити групу 50000 з groups!
Таким чином, забезпечення supplementalGroupsPolicy: Strict (забезпечене якимось механізмом політики) допомагає запобігти неявним допоміжним групам у Podʼі.
Примітка:
Контейнер з достатніми привілеями може змінити ідентичність процесу. supplementalGroupsPolicy впливає лише на початкову ідентичність процесу.
Читайте далі для отримання додаткової інформації.
Приєднана ідентичність процесу в статусі Podʼа
Ця функція також відкриває ідентичність процесу, прикріплену до першого процесу контейнера через поле .status.containerStatuses[].user.linux. Це буде корисно, щоб побачити, чи прикріплені неявні ідентифікатори груп.
...
status:
containerStatuses:
- name: ctr
user:
linux:
gid: 3000
supplementalGroups:
- 3000
- 4000
uid: 1000
...
Примітка:
Будь ласка, зверніть увагу, що значення в полі status.containerStatuses[].user.linux є спочатку приєднаною ідентичністю процесу до першого процесу контейнера в контейнері. Якщо контейнер має достатні привілеї для виклику системних викликів, повʼязаних з ідентичністю процесу (наприклад, setuid(2), setgid(2) або setgroups(2) тощо), процес контейнера може змінити свою ідентичність. Таким чином, фактична ідентичність процесу буде динамічною.
Існує кілька способів обмежити ці дозволи в контейнерах. Ми пропонуємо наступні як прості рішення:
- встановлення
privilege: falseтаallowPrivilegeEscalation: falseуsecurityContextвашого контейнера, або - приведення вашого pod у відповідність до
Restrictedполітики в Pod Security Standard.
Крім того, kubelet не має видимості у втулку NRI або внутрішній роботі середовища виконання контейнера. Адміністратор кластера, що налаштовує вузли або високо привілейовані робочі навантаження з дозволу локального адміністратора, може змінити допоміжні групи для будь-якого пода. Однак це поза сферою контролю Kubernetes і не повинно бути проблемою для вузлів з посиленою безпекою.
Політика Strict вимагає оновлених середовищ виконання контейнерів
Високорівневе середовище виконання контейнера (наприклад, containerd, CRI-O) відіграє ключову роль у обчисленні допоміжних ідентифікаторів груп, які будуть прикріплені до контейнерів. Таким чином, supplementalGroupsPolicy: Strict вимагає CRI-середовища, яке підтримує цю функцію. Стара поведінка (supplementalGroupsPolicy: Merge) може працювати з CRI-середовищем, яке не підтримує цю функцію, тому що ця політика є повністю зворотно сумісною.
Ось кілька CRI-середовищ, які підтримують цю функцію, і версії, які вам потрібно використовувати:
- containerd: v2.0 або новіше
- CRI-O: v1.31 або новіше
І ви можете побачити, чи підтримується ця функція в полі .status.features.supplementalGroupsPolicy вузла. Будь ласка, зверніть увагу, що це поле відрізняється від status.declaredFeatures, введеного в KEP-5328: Node Declared Features(formerly Node Capabilities).
apiVersion: v1
kind: Node
...
status:
features:
supplementalGroupsPolicy: true
Оскільки середовища виконання контейнерів універсально підтримують цю функцію, різні політики безпеки можуть почати забезпечувати поведінку Strict як більш безпечну. Найкраща практика — переконатися, що ваші Podʼи готові до цієї вимоги, і всі допоміжні групи прозоро оголошені в специфікації Podʼа, а не в образах.
Як долучитись
Це вдосконалення було ініційовано спільнотою SIG Node. Будь ласка, приєднуйтесь до нас, щоб звʼязатися зі спільнотою та поділитися своїми ідеями та відгуками щодо вищезазначеної функції та не тільки. Ми з нетерпінням чекаємо на ваші відгуки!
Як дізнатися більше?
- Налаштування контексту безпеки для Podʼа або контейнера
для отримання додаткової інформації про
supplementalGroupsPolicy - KEP-3619: Fine-grained SupplementalGroups control