Модуль 4.2: Pod Security Admission (PSA)
Складність:
[СЕРЕДНЯ]— основна навичка CKSЧас на проходження: 40-45 хвилин
Передумови: Модуль 4.1 (Контексти безпеки), основи просторів імен
Що ви зможете зробити
Розділ «Що ви зможете зробити»Після завершення цього модуля ви зможете:
- Налаштовувати мітки простору імен для Pod Security Admission з режимами enforce, audit, warn та закріпленням версії для кластерів Kubernetes 1.35+.
- Порівнювати стандарти Pod Security — privileged, baseline та restricted — і обирати правильний профіль для кожного класу робочих навантажень.
- Діагностувати повідомлення про відхилення PSA та виправляти специфікації Pod’ів за допомогою запуску не від імені root, відкидання можливостей, seccomp та контролю підвищення привілеїв.
- Проєктувати стратегію міграції з PSP на PSA, що використовує поетапне впровадження за просторами імен, загальнокластерні значення за замовчуванням, винятки та опційні політики Kyverno чи Gatekeeper.
Чому цей модуль важливий
Розділ «Чому цей модуль важливий»Гіпотетичний сценарій: платформенна команда готує оновлення Kubernetes до версії 1.35 для кластера, який досі несе звички епохи PodSecurityPolicy. У більшості просторів імен застосунків працюють звичайні вебсервіси, у кількох просторах імен спостережуваності — агенти на нодах, а в деяких просторах імен розробки лежать старі налагоджувальні Pod’и, які ніхто не переглядав місяцями. Саме оновлення — не найстрашніша частина. Справжній ризик — виявити надто пізно, що в кластері немає узгодженої межі допуску між звичайним деплойментом і Pod’ом, який просить простори імен хоста, широкі можливості Linux або запуск від імені root.
Pod Security Admission вирішує вужчу проблему, ніж багато хто очікує, і ця вузькість — його сила. Він не намагається стати повноцінною мовою політик, мутувати робочі навантаження, валідувати образи чи нав’язувати специфічні для бізнесу правила іменування. Він застосовує стандарти Pod Security з апстріму на етапі допуску, зазвичай через мітки простору імен, тож команди можуть блокувати або спостерігати специфікації Pod’ів, що порушують профіль privileged, baseline або restricted. Це робить PSA легким для осмислення під час іспиту CKS і достатньо надійним, щоб стати першим рівнем посилення безпеки виробничих навантажень.
Операційна навичка — це не запам’ятовування одного ідеального маніфесту. Операційна навичка — це прочитати повідомлення про відхилення, зіставити його з точним полем Pod’а, яке порушило профіль, вирішити, яким має бути простір імен — baseline чи restricted, і знати, коли PSA недостатньо виразний. Цей модуль проводить вас через таке судження: від історії PSP, через механіку профілів, у міграцію та загальнокластерну конфігурацію, а завершується діагностикою в стилі іспиту та лабораторною роботою, що відпрацьовує весь потік допуску.
Від PodSecurityPolicy до Pod Security Admission
Розділ «Від PodSecurityPolicy до Pod Security Admission»PodSecurityPolicy була першою вбудованою відповіддю Kubernetes на небезпечні специфікації Pod’ів, але мала дві властивості, які ускладнювали її експлуатацію в масштабі. Її обирали через RBAC, тож фактична політика для Pod’а залежала від того, який користувач або сервісний акаунт його створив, а не лише від того, де Pod розташований. Вона також включала мутаційну поведінку, тобто запит міг бути змінений допуском, а не прийнятий чи відхилений точно в тому вигляді, в якому був поданий. Ці рішення були потужними, але вони робили налагодження несподіваним, коли кілька ролей, контролерів та об’єктів політик взаємодіяли між собою.
Проєкт Kubernetes оголосив PSP застарілою у v1.21 і видалив її у v1.25, замінивши вбудований шлях безпеки Pod’ів контролером Pod Security Admission та стандартами Pod Security. Заміна навмисно змінила форму функціональності. PSA орієнтований на простір імен, на профіль та на валідацію. Він запитує: «чи відповідає цей Pod обраному стандарту для цього простору імен і режиму?», а не «яку обрану через RBAC політику має бути дозволено використовувати цьому творцю, і чи слід впроваджувати якісь значення за замовчуванням?».
Ця відмінність має значення під час міграції, бо PSA не є прямим замінником PSP. PSP могла виражати контроль, який стандарти Pod Security не охоплюють, і могла встановлювати значення за замовчуванням для полів, які команда застосунку забула задати. PSA очікує, що специфікація навантаження буде достатньо явною, щоб пройти валідацію. Якщо стара PSP використовувала мутацію, щоб задати значення seccomp за замовчуванням або автоматично відкинути можливості, міграція на PSA має перенести ці налаштування в маніфести, Helm-чарти, накладки Kustomize або окремий мутаційний рушій політик ще до ввімкнення примусу.
Уявіть PSP як налаштовуваний пункт перевірки з безліччю локальних правил і кількома автоматичними виправленнями. Уявіть PSA як стандартизований світлофор на кожній межі простору імен. Сигнал легше тлумачити та легше розгортати узгоджено, але він має лише три кольори: privileged, baseline та restricted. Коли організації потрібні правила, які не вписуються в ці кольори, PSA має залишатися на місці як універсальна основа, тоді як Kyverno, OPA Gatekeeper, перевірка образів або перевірки CI обробляють спеціалізований контроль.
┌──────────────────────────┐ ┌──────────────────────────┐│ PodSecurityPolicy │ │ Pod Security Admission │├──────────────────────────┤ ├──────────────────────────┤│ RBAC selects policy │ │ Namespace selects profile ││ Could mutate pod fields │ │ Validates only ││ Many custom restrictions │ │ Three upstream profiles ││ Deprecated in v1.21 │ │ Stable since v1.25 ││ Removed in v1.25 │ │ Enabled by default │└──────────────────────────┘ └──────────────────────────┘Іспит CKS зазвичай перевіряє нову модель, а не історичне написання PSP. Ви все ще можете побачити сценарій міграції, де наявне навантаження падає після переходу простору імен на restricted, або де кластеру потрібен загальнокластерний файл AdmissionConfiguration, бо самих міток простору імен недостатньо для встановлення бажаного значення за замовчуванням. У таких завданнях найшвидший шлях — визначити профіль і режим, оглянути поля Pod’а, що порушують правило, і внести найменшу зміну в маніфест, яка задовольняє стандарт без надання нових привілеїв.
Зупиніться та спрогнозуйте: якщо PSP раніше встановлювала за замовчуванням allowPrivilegeEscalation: false, але маніфести застосунку ніколи не оголошували це поле, що станеться, коли простір імен перейде на enforce: restricted під PSA? Важлива відповідь у тому, що PSA не заповнить пропущене значення. Автор Pod’а має задати поле явно, або інший компонент допуску має мутувати запит до того, як його побачить валідація PSA.
Планування міграції починається з інвентаризації, а не з міток. Перегляньте, які простори імен містять звичайні застосунки, які — агенти рівня ноди, які є системними просторами імен, а яким просторам імен розробки потрібне тимчасове ставлення лише з попередженнями. Першою зміною мітки зазвичай має бути audit: restricted і warn: restricted, тоді як enforce залишається відсутнім або встановленим на baseline. Це створює орієнтовані на розробника попередження та анотації аудиту ще до того, як кластер почне відхиляти Pod’и, які все ще можуть належати командам без поточного відповідального.
Вимір вартості є переважно операційним, а не ліцензійним, оскільки PSA постачається разом із Kubernetes. Увімкнення audit та warn все одно може створити роботу: журнали аудиту зростають, системи CI можуть видавати більше попереджень, а платформеним інженерам потрібен час на сортування порушень. Помірний кластер із сотнями просторів імен може створити достатньо шуму допуску, щоб це мало значення, якщо кожен контролер раз за разом створює невідповідні Pod’и. Практичний контроль вартості — це поетапне впровадження з чітким володінням просторами імен, закріпленими версіями та коротким списком винятків, а не один глобальний перемикач, який клацнули під час вікна оновлення.
Стандарти Pod Security як інженерні профілі
Розділ «Стандарти Pod Security як інженерні профілі»Стандарти Pod Security — це не випадкові контрольні списки. Вони описують три операційні припущення щодо довіри до робочого навантаження. Профіль privileged навмисно необмежений, бо деяким компонентам кластера потрібен доступ рівня хоста. Профіль baseline запобігає поширеним шляхам підвищення привілеїв, водночас зберігаючи широку сумісність зі звичайними образами контейнерів. Профіль restricted прагне найменших привілеїв для навантажень застосунків і очікує, що автор Pod’а буде явним щодо ідентичності, можливостей, seccomp, типів томів та підвищення привілеїв.
Корисне порівняння — це не «який профіль безпечніший?», бо restricted завжди виграє це вузьке питання. Корисне порівняння — це «які навантаження можуть чесно працювати під цим профілем, не ламаючись і не приховуючи винятків?». DaemonSet CNI, що налаштовує мережу ноди, може потребувати привілейованої поведінки та доступу до хоста, тож примушування його до restricted створило б фальшиве відчуття дисципліни політики. Вебдодаток API, що слухає порт 8080 і пише лише до оголошеного каталогу кешу, має бути здатним пройти restricted, тож залишення його на baseline пропускає легке зменшення радіуса ураження.
| Сфера контролю | Privileged | Baseline | Restricted |
|---|---|---|---|
| Привілейовані контейнери | Дозволено | Заборонено | Заборонено |
| Простори імен хоста | Дозволено | Заборонено для hostPID, hostIPC та hostNetwork | Заборонено |
| Томи HostPath | Дозволено | Заборонено | Заборонено |
| Можливості Linux | Без обмежень | Блокує небезпечні додавання поза базовим списком дозволених | Має відкинути ALL; можна додати лише NET_BIND_SERVICE |
| Запуск від імені root | Дозволено | Дозволено | Не має працювати з UID 0; важать runAsNonRoot та налаштування ненульового користувача |
| Підвищення привілеїв | Дозволено | Не блокується повністю | Має задати allowPrivilegeEscalation: false для контейнерів Linux |
| Seccomp | Без обмежень | Не має явно використовувати Unconfined | Має явно використовувати RuntimeDefault або Localhost |
| Типи томів | Без обмежень | Широко сумісні, крім hostPath | Обмежено безпечними джерелами томів, як-от ConfigMap, Secret, PVC, projected, downwardAPI, CSI, emptyDir та ephemeral |
Baseline — це профіль, який ви використовуєте, коли потрібна сумісність, але ви все ще хочете зупинити явно ризиковані специфікації Pod’ів. Він блокує привілейовані контейнери, простори імен хоста та томи HostPath, обмежує порти хоста й небезпечні додавання можливостей та запобігає кільком прямим виходам за межі контейнера. Він не вимагає запуску не від імені root, не вимагає відкидання всіх можливостей і не вимагає кореневих файлових систем лише для читання. Це робить baseline розумним значенням за замовчуванням для просторів імен розробки або застарілих просторів імен застосунків під час першої фази міграції.
Restricted — це профіль, який ви використовуєте, коли команди застосунків можуть володіти своїми маніфестами та образами. Він вимагає, щоб специфікація Pod’а закривала звичайні шляхи привілеїв: жодного підвищення привілеїв, жодного широкого набору можливостей, жодного запуску від імені root та явного профілю seccomp. Baseline також забороняє томи HostPath; restricted успадковує це правило baseline, а потім звужує решту дозволених джерел томів. Restricted все ще не нав’язує кожен контроль посилення, який може хотіти команда безпеки. Наприклад, він не вимагає readOnlyRootFilesystem, лімітів ресурсів, підписаних образів, мережевих політик чи затверджених реєстрів.
Останній пункт — це часта пастка іспиту. readOnlyRootFilesystem: true — це сильний вибір посилення застосунку, і багато організацій вимагають його для виробничих сервісів, але стандарт restricted Pod Security з апстріму його не вимагає. Якщо питання просить лише відповідності PSA, зосередьтеся на полях, які PSA фактично перевіряє. Якщо питання просить посилене навантаження поза межами PSA, тоді додавання кореневої файлової системи лише для читання та явних томів для запису є розумним додатковим захистом.
Ось компактний Pod restricted, який задовольняє поля PSA, що найчастіше перевіряються в завданнях у стилі CKS. Образ — busybox:1.36, а команда виконує sleep, тож Pod не потребує кореневої файлової системи для запису або привілейованого порту. Налаштування безпеки розділені між ідентичністю рівня Pod’а та контролем процесу рівня контейнера, бо це віддзеркалює, як зазвичай структуровані реальні маніфести.
apiVersion: v1kind: Podmetadata: name: restricted-okspec: securityContext: runAsNonRoot: true runAsUser: 1000 runAsGroup: 1000 seccompProfile: type: RuntimeDefault containers: - name: app image: busybox:1.36 command: ["sh", "-c", "sleep 3600"] securityContext: allowPrivilegeEscalation: false capabilities: drop: ["ALL"]Кілька полів у цьому маніфесті виконують роботу допуску, а не декорацію часу виконання. runAsNonRoot: true повідомляє Kubernetes, що процес не має стартувати від імені root, тоді як runAsUser: 1000 усуває неоднозначність для образів, чий користувач за замовчуванням інакше міг би бути невідомим. allowPrivilegeEscalation: false запобігає здобуттю привілеїв у стилі setuid для контейнерів Linux. capabilities.drop: ["ALL"] видаляє стандартний набір можливостей Linux, а seccompProfile.type: RuntimeDefault повідомляє середовищу виконання застосувати стандартний фільтр системних викликів замість того, щоб залишати seccomp незаданим.
Невідповідна версія допомагає швидше читати повідомлення про відхилення. Цей Pod просить привілейований режим, мережу хоста, UID 0, додані можливості та відсутній профіль seccomp. Під enforce: baseline привілейованого режиму, мережі хоста та додавання можливості вже достатньо, щоб відхилити запит. Під enforce: restricted користувач root, відсутній allowPrivilegeEscalation: false, відсутній drop: ["ALL"] та відсутній профіль seccomp також з’являться у списку порушень.
Логічне представлення:
apiVersion: v1kind: Podmetadata: name: restricted-failspec: hostNetwork: true containers: - name: app image: nginx:1.27-alpine securityContext: privileged: true runAsUser: 0 capabilities: add: ["NET_ADMIN"]Це навмисно невідповідний приклад, а не крок лабораторної роботи. YAML синтаксично коректний у дозвільному просторі імен; кожен рядок посилається на шлях поля, де застосовується відповідна політика (наприклад, privileged живе у spec.containers[].securityContext.privileged).
Перед запуском цього — який вивід ви очікуєте, якщо простір імен має enforce: baseline, warn: restricted та audit: restricted? Pod має бути відхилений, бо він порушує примусовий профіль baseline, тож режим попередження не є причиною його відмови. Якщо ви приберете порушення baseline, але залишите прогалини, що стосуються лише restricted, Pod може бути допущений, тоді як API-сервер попереджає того, хто викликав, і записує анотації аудиту для профілю restricted.
Стандарти також застосовуються до ресурсів навантаження, що створюють шаблони Pod’ів, але примус зрештою блокує запит на створення Pod’а. Це означає, що Deployment може бути прийнятий у деяких робочих процесах, тоді як його ReplicaSet раз за разом не може створити Pod’и — залежно від шляху допуску та версії об’єкта, що оцінюється. Під час іспиту перевіряйте і об’єкт контролера, і події Pod’а. Відхилений Pod може з’явитися як подія ReplicaSet, навіть якщо команда kubectl apply, що створила Deployment, виглядала успішною.
Коли ви порівнюєте профілі у виробництві, тримайте винятки ближче до типу навантаження, а не до назви команди. Простору імен для агентів ноди можуть знадобитися привілейовані контролі, бо цього вимагає клас навантаження. Простір імен для звичайних API не має залишатися привілейованим лише тому, що команда-власник зайнята. Таке формулювання зменшує політичний дрейф: виняток прив’язаний до технічної вимоги, а мітки простору імен можна посилити, коли ця вимога зникне.
Є кілька менш помітних перевірок, що відрізняють хорошу відповідь PSA від завченого шаблону. Restricted звужує дозволені sysctl до безпечних назв, обмежує типи SELinux, блокує procMount: Unmasked і запобігає явному unconfined для AppArmor там, де це поле застосовується. Baseline також блокує кілька небезпечних перемикачів, які не очевидні зі звичних прикладів privileged та hostNetwork. Коли повідомлення про відхилення називає одне з цих полів, опирайтеся бажанню замінити весь Pod. Прочитайте назване поле, приберіть небезпечне значення та збережіть решту специфікації навантаження стабільною.
Навантаження Windows додають ще одну причину читати фактичне повідомлення. У сучасному Kubernetes інформація про ОС Pod’а дає змогу стандартам Pod Security відрізняти контролі лише для Linux від Pod’ів Windows. Такі поля, як можливості Linux, seccomp та підвищення привілеїв, мають значення для контейнерів Linux; вони не є тим самим механізмом для контейнерів Windows. Завдання CKS зазвичай використовують приклади Linux, але виробничі кластери зі змішаними операційними системами мають закріплювати версії політик і тестувати обидва класи навантаження, перш ніж оголошувати простір імен готовим до примусу restricted.
Ефемерні контейнери також є частиною ментальної моделі. Налагоджувальні контейнери можна додати після того, як Pod уже запущений, і вони все одно проходять через допуск. Простір імен, що примушує restricted, не має дозволяти пізнішій налагоджувальній дії контрабандою протягувати привілейовані налаштування в Pod, який спочатку пройшов політику. Це має операційне значення, бо реагування на інциденти часто відбувається під стресом. Якщо команді потрібне привілейоване налагодження, надайте контрольований привілейований простір імен або робочий процес «розбити скло», а не послаблюйте політику для кожного Pod’а застосунку.
Стандарти навмисно уникають обіцянок рівня застосунку. Pod може пройти restricted, водночас все ще запускаючи вразливий вебфреймворк, приймаючи трафік з кожного простору імен, використовуючи непідписаний образ або записуючи чутливі дані в журнали. Це не провал PSA; це визначення межі. PSA відповідає на питання привілеїв специфікації Pod’а. NetworkPolicy, допуск образів, виявлення під час виконання, керування секретами та контролі безпеки застосунку відповідають на інші питання, що оточують основу безпеки Pod’ів.
Режими PSA, мітки простору імен та діагностика відхилень
Розділ «Режими PSA, мітки простору імен та діагностика відхилень»Pod Security Admission має три режими, і кожен режим відповідає на інше операційне питання. enforce запитує, чи має API-сервер відхилити Pod. warn запитує, чи має API-сервер дозволити Pod, але повернути попередження клієнту. audit запитує, чи має API-сервер анотувати подію аудиту, щоб команди безпеки могли пізніше шукати порушення. Режими незалежні, тож простір імен може примушувати baseline, водночас попереджаючи та проводячи аудит щодо restricted.
Цей патерн змішаних режимів — це звичайний шлях впровадження. Примус baseline блокує найнебезпечніші специфікації Pod’ів рано, тоді як warn та audit щодо restricted створюють звіт про те, що ще потребує роботи. Розробники бачать попередження в kubectl та інших клієнтах, що відображають попередження сервера. Оператори кластера бачать анотації аудиту лише тоді, коли журналювання аудиту налаштоване для API-сервера й зберігається десь корисно. Сам PSA не створює окремий дашборд, тож поверхня журналу залежить від дизайну аудиту та спостережуваності кластера.
Мітки простору імен мають фіксовану форму. Мітка режиму обирає профіль, а опційна мітка версії обирає версію політики Kubernetes. latest слідує за поточною версією API-сервера, що зручно в лабораторії, але може здивувати виробничі команди під час оновлень. Закріплена версія, як-от v1.35, робить поведінку політики стабільною, доки платформенна команда навмисно не змінить мітку. Для виробничих просторів імен закріплюйте під час впровадження та переміщуйте закріплення як частину плану оновлення.
apiVersion: v1kind: Namespacemetadata: name: payments-prod labels: pod-security.kubernetes.io/enforce: baseline pod-security.kubernetes.io/enforce-version: v1.35 pod-security.kubernetes.io/warn: restricted pod-security.kubernetes.io/warn-version: v1.35 pod-security.kubernetes.io/audit: restricted pod-security.kubernetes.io/audit-version: v1.35Ті самі мітки можна застосувати імперативно, коли ви працюєте швидко в середовищі іспиту. Використовуйте --overwrite, бо простори імен часто вже несуть одну чи кілька міток PSA, а невдала команда мітки витрачає час. Якщо ви змінюєте наявний простір імен на суворіший рівень enforce, спочатку використайте dry-run, щоб API-сервер повідомив про наявні Pod’и, які порушили б новий рівень.
kubectl label namespace payments-prod \ pod-security.kubernetes.io/enforce=baseline \ pod-security.kubernetes.io/enforce-version=v1.35 \ pod-security.kubernetes.io/warn=restricted \ pod-security.kubernetes.io/warn-version=v1.35 \ pod-security.kubernetes.io/audit=restricted \ pod-security.kubernetes.io/audit-version=v1.35 \ --overwrite
kubectl label namespace payments-prod \ pod-security.kubernetes.io/enforce=restricted \ pod-security.kubernetes.io/enforce-version=v1.35 \ --dry-run=server \ --overwriteФормат помилки — одна з найцінніших підказок, які дає PSA. Типове відхилення починається з Error from server (Forbidden), називає Pod або ресурс, ідентифікує порушений профіль та версію, потім перелічує причини на рівні полів. Не сприймайте це повідомлення як стіну тексту. Розбийте його на три питання: який профіль відхилив запит, який контейнер чи init-контейнер названо, та яке значення поля треба змінити.
Error from server (Forbidden): error when creating "pod.yaml":pods "restricted-fail" is forbidden: violates PodSecurity "restricted:v1.35":allowPrivilegeEscalation != false (container "app" must setsecurityContext.allowPrivilegeEscalation=false), unrestricted capabilities(container "app" must set securityContext.capabilities.drop=["ALL"]),runAsNonRoot != true (pod or container "app" must setsecurityContext.runAsNonRoot=true), seccompProfile (pod or container "app"must set securityContext.seccompProfile.type to "RuntimeDefault" or "Localhost")Це повідомлення майже є контрольним списком виправлень. Додайте або перемістіть відсутні поля безпеки на рівень Pod’а чи контейнера, потім повторіть apply. Якщо повідомлення називає init-контейнер чи ефемерний контейнер, виправте й цей контейнер. Перевірки restricted застосовуються до контейнерів, init-контейнерів та ефемерних контейнерів там, де поле є доречним. Deployment з одним посиленим контейнером застосунку та одним забутим init-контейнером все одно може провалити допуск.
Наступний маніфест виправляє відхилення, не додаючи непов’язаних контролів посилення. Зверніть увагу, що він не додає readOnlyRootFilesystem, бо помилка PSA про це не просила. У виробничій історії посилення ви могли б додати це пізніше, але під час виправлення на іспиті вам слід швидко задовольнити політику й уникати внесення збоїв запуску, які не є частиною питання.
apiVersion: v1kind: Podmetadata: name: restricted-fixedspec: securityContext: runAsNonRoot: true runAsUser: 101 # UID for the nginx user in nginx:1.27-alpine seccompProfile: type: RuntimeDefault containers: - name: app image: nginx:1.27-alpine securityContext: allowPrivilegeEscalation: false capabilities: drop: ["ALL"]Примітка: стандартний шлях запуску nginx припускає орієнтовані на root порти та шляхи для запису, тож цей Pod проходить допуск PSA, але може потрапити в CrashLoopBackOff під час виконання — допуск PSA та працездатність під час виконання є незалежними питаннями, що розглядаються далі в цьому модулі.
Попередження виглядають схоже, але вони не зупиняють запит. Коли простір імен має warn: restricted, kubectl apply може вивести рядки, що починаються з Warning:, які називають профіль та поля-порушники. Ці попередження легко проігнорувати під час напруженого впровадження, тому режим warn має живити тікет, звіт чи перевірку якості CI. Впровадження лише з попередженнями, яке ніхто не читає, — це просто відкладений примус без плану ремонту.
Режим audit відрізняється, бо зворотний зв’язок не повертається розробнику. PSA додає анотації аудиту до події аудиту API для запиту, і ці анотації можна запитувати через будь-який журнальний конвеєр, що отримує журнали аудиту API-сервера. Це корисно для міграції, бо захоплює трафік контролерів так само, як і людський трафік kubectl. Це також режим, що найімовірніше створить несподіваний обсяг журналу, коли контролер раз за разом повторює невідповідний шаблон Pod’а.
kubectl get namespace payments-prod --show-labels
kubectl describe namespace payments-prod
kubectl get events -n payments-prod --sort-by=.lastTimestampЦі команди не замінюють читання повідомлення про відхилення, але вони швидко вас орієнтують. get namespace --show-labels підтверджує активні режими та версії. describe namespace зручний, коли мітки незграбно переносяться в терміналі. Події допомагають, коли Pod’а, що падає, створив контролер, а не людина. На іспиті CKS ця коротка послідовність часто виявляє, що саме ви виправляєте — політику простору імен, специфікацію навантаження чи шаблон контролера.
Є ще одна тонка взаємодія: мітка простору імен керує новими допусками, а не ретроактивним переписуванням наявних Pod’ів. Наявні Pod’и продовжують працювати після того, як ви посилите мітку простору імен, хоча майбутні перестворення можуть провалитися. Саме тому деплоймент може виглядати здоровим, доки розгортання, дренаж ноди чи заміна автомасштабувальником не змусить нові Pod’и пройти допуск. Безпечне виробниче впровадження перевіряє поточні шаблони Pod’ів перед примусом і репетирує принаймні один перезапуск для критичних навантажень.
Сценарій міграції: двісті просторів імен без заморожування
Розділ «Сценарій міграції: двісті просторів імен без заморожування»Гіпотетичний сценарій: у кластері двісті просторів імен, близько тридцяти спільних платформенних просторів імен та довгий хвіст просторів імен застосунків, якими володіють окремі команди. Старе налаштування PSP дозволяло більшості сервісних акаунтів застосунків використовувати обмежувальну політику, але кілька сервісних акаунтів мали доступ до ширшої політики для міграцій та налагодження. У платформенної команди є чотири робочі дні до наступної репетиції оновлення площини управління, тож мета — не зробити кожне навантаження ідеальним. Мета — прибрати залежність від PSP, встановити передбачувану основу PSA і створити чергу виправлень профілю restricted, які команди можуть завершити, не блокуючи оновлення.
Нульова година починається з виявлення. Експортуйте мітки просторів імен, перелічіть Pod’и з полями просторів імен хоста, знайдіть привілейовані контейнери та визначте очевидні DaemonSet’и, які не можна обмежити. Команда поки що нічого не примушує, бо сама інвентаризація може виявити застарілі простори імен, покинуті контролери та хибні припущення щодо того, які навантаження ще існують. Найкорисніші стовпці таблиці — це власник простору імен, клас навантаження, пропонований профіль enforce, пропонований профіль warn, побачені порушення та власник винятку.
kubectl get namespaces --show-labels
kubectl get pods --all-namespaces -o jsonpath='{range .items[*]}{.metadata.namespace}{"\t"}{.metadata.name}{"\t"}{.spec.hostNetwork}{"\t"}{.spec.hostPID}{"\t"}{.spec.hostIPC}{"\n"}{end}'
kubectl get pods --all-namespaces -o jsonpath='{range .items[*]}{.metadata.namespace}{"\t"}{.metadata.name}{"\t"}{range .spec.containers[*]}{.name}{":"}{.securityContext.privileged}{" "}{end}{"\n"}{end}'День перший — це audit та warn. Команда позначає простори імен застосунків як audit: restricted та warn: restricted, потім позначає очевидні простори імен агентів ноди як enforce: privileged лише тоді, коли клас навантаження дійсно цього потребує. Для звичайних просторів імен застосунків enforce: baseline є хорошою першою захисною сіткою, бо він блокує привілейовані контейнери, простори імен хоста та томи HostPath, водночас залишаючи застарілим образам, що працюють від імені root, достатньо простору для подальшого обслуговування трафіку. Команда закріплює мітки до v1.35, тож поведінка політики не зміниться непомітно наступним оновленням площини управління.
День другий — це виправлення галасливих збоїв. Найчастіші причини — це зазвичай відсутній allowPrivilegeEscalation: false, відсутній capabilities.drop: ["ALL"], відсутній профіль seccomp та контейнери, що працюють з UID 0. Вони не однакові за складністю. Додавання seccomp та відкидання можливостей часто є зміною значень Helm. Відхід від root може потребувати перезбирання образів, виправлення прав доступу до файлів або зміни монтувань томів. Ця різниця визначає порядок впровадження: спочатку виправте прогалини лише в маніфестах, по-друге заплануйте перезбирання образів, по-третє задокументуйте справжні винятки.
День третій — це репетиція примусу. Платформенна команда використовує зміни міток у режимі dry-run на стороні сервера та контрольовані перезапуски для репрезентативних деплойментів. Це ловить режим збою, коли простір імен здається чистим, бо старі Pod’и ще працюють, але наступний ReplicaSet не може створити заміни. Будь-який простір імен, що провалює репетицію, залишається на enforce: baseline з restricted у warn та audit. Будь-який простір імен, що проходить, переходить на enforce: restricted, усе ще закріплений на v1.35, із записаним власником для майбутніх оновлень.
День четвертий — це прибирання та комунікація. Маніфести PSP видаляються з Git лише після того, як команда підтверджує, що жоден компонент від них більше не залежить, а платформенний ранбук змінюється з «яка PSP надає цьому сервісному акаунту дозвіл?» на «які мітки PSA застосовуються до цього простору імен?». Команда також вирішує, які прогалини потребують рушія політик. Наприклад, PSA може вимагати поля Pod’а restricted, але не може вимагати образи з внутрішнього реєстру або блокувати теги latest. Ці контролі переходять до Kyverno чи Gatekeeper, а не втискаються в PSA.
Конкретний графік має значення, бо запобігає двом поширеним збоям. Перший збій — примусити restricted скрізь до того, як команди застосунків побачили попередження, що перетворює міграцію політики на простій. Другий збій — залишити все в audit назавжди, що створює постійний звіт без межі безпеки. Чотириденна міграція не завершує кожне завдання посилення, але встановлює захищувану основу та видиму чергу для решти роботи.
Для цілей CKS ментальна модель міграції менша. Якщо простір імен заслабкий, додайте або посиліть мітки. Якщо Pod порушує профіль, виправте специфікацію Pod’а. Якщо кластеру потрібні значення за замовчуванням або винятки, що мають застосовуватися навіть за відсутності міток, використовуйте AdmissionConfiguration. Якщо вимога кастомна, як-от «дозволяти лише образи з цього реєстру» чи «вимагати мітку команди на кожному Pod’і», оберіть Kyverno чи Gatekeeper, бо PSA не має поля для такої політики.
Загальнокластерна конфігурація та винятки
Розділ «Загальнокластерна конфігурація та винятки»Мітки простору імен — це звичайний інтерфейс для PSA, бо вони роблять політику видимою там, де живуть навантаження. Загальнокластерна AdmissionConfiguration — це інтерфейс для значень за замовчуванням та винятків. Kube-apiserver завантажує її через --admission-control-config-file, і файл може задавати профілі за замовчуванням для просторів імен без міток, визначати, що відбувається за відсутності мітки версії, та звільняти конкретні імена користувачів, класи середовища виконання чи простори імен. Це не заміна міткам простору імен; це базова основа кластера під ними.
Використовуйте загальнокластерну конфігурацію, коли відсутність міток усе одно має щось означати. Команда безпеки може хотіти, щоб непозначені простори імен за замовчуванням примушували baseline, за замовчуванням попереджали про restricted та за замовчуванням проводили аудит restricted. Це уникає небезпечної прогалини, коли новостворений простір імен не має міток PSA, бо хтось забув про шаблон. Мітки простору імен усе одно можуть перевизначати значення за замовчуванням, коли класу навантаження потрібен інший профіль.
apiVersion: apiserver.config.k8s.io/v1kind: AdmissionConfigurationplugins:- name: PodSecurity configuration: apiVersion: pod-security.admission.config.k8s.io/v1 kind: PodSecurityConfiguration defaults: enforce: baseline enforce-version: v1.35 audit: restricted audit-version: v1.35 warn: restricted warn-version: v1.35 exemptions: runtimeClasses: - privileged-runtime namespaces: - kube-systemПрапорець kube-apiserver є операційно важливим, бо неправильний шлях або недійсний файл може вплинути на запуск API-сервера. У керованому кластері ви можете не мати прямого доступу до цієї конфігурації, тож практичним інструментом можуть бути мітки простору імен плюс значення за замовчуванням від провайдера. У самокерованому кластері або середовищі іспиту, що відкриває статичні маніфести Pod’ів площини управління, вам треба знати, що файл конфігурації допуску посилається API-сервером, а не застосовується через kubectl apply, як звичайний об’єкт Kubernetes.
kube-apiserver \ --admission-control-config-file=/etc/kubernetes/admission/admission.yamlВинятки мають бути рідкісними та нудними. Звільнення kube-system поширене, бо системним компонентам та агентам ноди можуть знадобитися привілеї, які навантаження застосунків ніколи не повинні копіювати. Звільнення класу середовища виконання може бути доречним, коли пісочниця чи спеціальне середовище виконання має іншу модель безпеки. Звільнення імен користувачів потужне, але небезпечне, бо воно слідує за актором, а не за навантаженням. Якщо широка автоматизаційна ідентичність звільнена, кожен простір імен, у якому ця ідентичність може створювати Pod’и, може обходити PSA.
Поля версій в AdmissionConfiguration мають той самий виробничий компроміс, що й версії міток простору імен. latest зменшує обслуговування, але прив’язує поведінку політики до оновлень. Закріплена версія підтримує контрольоване керування змінами, особливо коли оновлення кластера та оновлення профілю безпеки є окремими робочими потоками. Для навчальної програми та виробничих прикладів, орієнтованих на Kubernetes 1.35, закріплення v1.35 робить урок та впровадження детермінованими.
Закріплення має бути узгодженим між режимами, а не лише на примусовій мітці. Якщо enforce-version закріплено, але warn-version залишено на поведінку за замовчуванням, кластер може примушувати одну версію політики, водночас попереджаючи про іншу після оновлення. Це може створити заплутані звіти міграції, бо розробники бачать попередження, що не збігаються з поточною межею примусу. У виробничих ранбуках сприймайте шість міток простору імен як задокументований блок: три мітки режиму та три мітки версії, переглядані разом під час оновлень кластера.
На іспиті не зловживайте загальнокластерною конфігурацією. Якщо завдання каже «налаштуйте простір імен secure, щоб примушувати restricted», мітки — пряма відповідь. Якщо завдання каже «встановіть стандартну поведінку безпеки Pod’ів для непозначених просторів імен» або показує файл конфігурації допуску API-сервера, тоді AdmissionConfiguration із вкладеною PodSecurityConfiguration входить у сферу. Найшвидша діагностична підказка — чи запитана політика стосується конкретного простору імен, чи має застосовуватися ще до того, як власник простору імен додасть будь-які мітки.
Робочий процес іспиту CKS для завдань PSA
Розділ «Робочий процес іспиту CKS для завдань PSA»Завдання PSA на іспиті винагороджують послідовність більше, ніж запам’ятовування. Почніть з визначення простору імен, потім визначте активні мітки, потім огляньте Pod або шаблон контролера, який оцінюватиме допуск. Багато неправильних відповідей походять від виправлення окремого YAML Pod’а, тоді як справжнє навантаження — це шаблон Deployment, або від зміни міток warn, коли відхилення прийшло від enforce. Дисциплінований робочий процес утримує вас від зміни не того рівня під тиском часу.
Перша команда — це зазвичай читання простору імен. Вам треба знати всі три режими та всі доречні версії, бо конфігурація змішаних режимів є поширеною. Якщо простір імен примушує baseline і попереджає про restricted, попередження restricted не є відхиленням. Якщо простір імен примушує restricted без мітки версії, наступне питання — чи очікує завдання, що ви закріпите версію для детермінованої поведінки. Читайте мітки перед редагуванням Pod’ів, бо мітки пояснюють, який стандарт судить запит.
kubectl get namespace secure-ns --show-labelskubectl describe namespace secure-nsДругий крок — вирішити, чи запит є прямим Pod’ом, чи Pod’ом, керованим контролером. Заборонне повідомлення, що називає pods "api-7cfd...", усе одно може вказувати на шаблон Deployment, ReplicaSet, Job чи CronJob. Редагувати живий відхилений Pod зазвичай неможливо, бо Pod ніколи не було збережено. Виправте шаблон, що створить наступний Pod. На іспиті використовуйте kubectl get deploy -n secure-ns -o yaml або конкретну назву контролера, показану в подіях, потім змініть чи відредагуйте поля шаблону через kubectl patch або kubectl edit.
kubectl get events -n secure-ns --sort-by=.lastTimestampkubectl get deployment -n secure-nskubectl get deployment api -n secure-ns -o yamlТретій крок — перекласти повідомлення PSA в різницю маніфесту. Якщо повідомлення каже allowPrivilegeEscalation != false, задайте allowPrivilegeEscalation: false на названому контейнері. Якщо воно каже unrestricted capabilities, додайте capabilities.drop: ["ALL"]. Якщо воно каже seccompProfile, додайте seccompProfile.type: RuntimeDefault на рівні Pod’а чи контейнера. Якщо воно каже runAsNonRoot != true, задайте runAsNonRoot: true і приберіть будь-який явний UID 0. Не змінюйте простір імен на слабкіший профіль, якщо завдання явно не просить винятку.
Четвертий крок — подумати про область застосування. Деякі поля природно є значеннями за замовчуванням рівня Pod’а, а деякі поля — контролями рівня контейнера. seccompProfile та runAsNonRoot рівня Pod’а можуть охопити кожен контейнер, якщо контейнер їх не перевизначає. allowPrivilegeEscalation та можливості належать окремим контейнерам. Коли Pod має контейнери app, sidecar та init, перегляньте кожен список контейнерів. Найшвидше виправлення — це часто повторюваний блок securityContext контейнера, а не єдине поле рівня Pod’а, яке PSA не використовує для цього контролю.
spec: securityContext: runAsNonRoot: true runAsUser: 1000 seccompProfile: type: RuntimeDefault containers: - name: app securityContext: allowPrivilegeEscalation: false capabilities: drop: ["ALL"] initContainers: - name: init securityContext: allowPrivilegeEscalation: false capabilities: drop: ["ALL"]Зупиніться та класифікуйте: якщо питання просить «зробити так, щоб Pod пройшов restricted», а Pod наразі має hostPath, privileged: true, UID 0 та відсутній seccomp, які виправлення обов’язкові для PSA, а які — окремі вибори виробничого посилення? Обов’язкові виправлення PSA включають прибирання привілейованого режиму, прибирання hostPath, бо baseline та restricted обидва його забороняють, забезпечення запуску не від імені root, задання seccomp, блокування підвищення привілеїв та відкидання можливостей. Окремі вибори посилення можуть включати кореневі файлові системи лише для читання, затверджені реєстри образів або NetworkPolicy.
П’ятий крок — провалідувати з dry-run на стороні сервера, коли кластер це дозволяє. Dry-run надсилає запит через допуск без збереження об’єкта, що саме й є поведінкою, яка вам потрібна під час тестування виправлення політики. Це також уникає залишення провалених експериментальних об’єктів у просторі імен. Якщо dry-run недоступний для об’єкта чи середовища, використайте тимчасовий простір імен з еквівалентними мітками й видаліть об’єкт одразу після тестування.
kubectl apply -n secure-ns --dry-run=server -f fixed-pod.yamlkubectl diff -n secure-ns -f fixed-deployment.yamlkubectl apply -n secure-ns -f fixed-deployment.yamlШостий крок — переконатися, що контролер дійсно створює Pod. Успіху допуску для оновленого об’єкта Deployment недостатньо, якщо шаблон усе ще має приховане порушення або застосунок не може запуститися з новою ідентичністю. Стежте за подіями ReplicaSet та статусом Pod’а після застосування виправлення. Pod, що проходить PSA, усе одно може провалитися під час виконання, бо користувач не-root не може записувати в шлях образу. Цей збій під час виконання відрізняється від збою допуску й має налагоджуватися як проблема контексту безпеки чи файлової системи.
Останній крок — залишити намір політики видимим. Якщо ви додаєте мітки, підтвердіть фінальні мітки простору імен. Якщо ви виправляєте навантаження, підтвердіть, що шаблон містить поля безпеки, а не лише разовий Pod. Якщо ви використовуєте виняток, будьте готові пояснити, чому міток було недостатньо. Оцінювання CKS часто перевіряє фінальний стан кластера, а не вашу історію команд, тож завершуйте читанням об’єкта, який оцінювач, імовірно, огляне.
Патерни та антипатерни
Розділ «Патерни та антипатерни»Найсильніший патерн PSA — це поетапне впровадження за просторами імен: спочатку audit, по-друге warn, останнім enforce. Це не бюрократія. Це відповідає тому факту, що політика допуску оцінюється під час створення Pod’ів, тоді як багато виробничих Pod’ів могли працювати тижнями. Audit та warn виявляють, що провалиться під час наступного розгортання, а примус перетворює відомий чистий стан на справжню межу, щойно роботу з ремонту завершено.
| Патерн | Коли використовувати | Чому це працює |
|---|---|---|
enforce: baseline, warn/audit: restricted | Застарілі простори імен застосунків, що рухаються до найменших привілеїв | Блокує очевидні високоризикові специфікації, водночас створюючи чергу виправлень restricted |
enforce: restricted із закріпленою версією | Виробничі сервіси з власними маніфестами та сумісними образами | Робить вимоги найменших привілеїв передбачуваними між оновленнями |
| Privileged лише для просторів імен класу навантаження | CNI, CSI, моніторинг ноди або контрольований інструментарій «розбити скло» | Тримає необхідний доступ до хоста подалі від звичайних просторів імен застосунків |
| Значення за замовчуванням кластера плюс перевизначення простору імен | Платформенні команди, яким потрібна безпечна поведінка для нових просторів імен | Запобігає перетворенню непозначених просторів імен на прогалини політики |
Антипатерни зазвичай походять від сприйняття PSA як або заслабкого, або занадто магічного. Він заслабкий, щоб бути єдиним рівнем політики для походження образів, сегментації мережі чи кастомних бізнес-правил. Він також недостатньо магічний, щоб виправити маніфести, які раніше покладалися на мутацію PSP. Команди потрапляють у халепу, коли вмикають примус restricted до того, як специфікації навантажень фактично містять поля, яких restricted вимагає.
| Антипатерн | Чому це трапляється | Краща альтернатива |
|---|---|---|
Примус restricted на kube-system без інвентаризації | Команда хоче просте правило «безпека скрізь» | Звільніть системні простори імен або класифікуйте агентів ноди окремо |
Використання latest на кожній виробничій мітці | Це здається стійким до майбутнього та уникає ведення обліку версій | Закріпіть версії під час впровадження, потім навмисно оновлюйте закріплення після тестування оновлення |
| Припущення, що попереджень достатньо | Розробники бачать попередження, але жоден власник їх не відстежує | Спрямовуйте знахідки audit та warn у роботу з виправлення з володінням простором імен |
| Додавання Kyverno чи Gatekeeper перед PSA | Платформенна команда хоче один фреймворк політик для всього | Використовуйте PSA для основи безпеки Pod’ів з апстріму, потім додавайте кастомну політику там, де потрібно |
Баланс прагматичний. PSA має бути першим рівнем допуску для привілеїв Pod’а, бо він з апстріму, увімкнений за замовчуванням та узгоджений зі стандартами, які документує Kubernetes. Він не має ставати виправданням, щоб ігнорувати дизайн навантаження. Pod, що проходить restricted, усе одно може бути вразливим, бо використовує ризикований образ, відкриває непотрібний сервіс, не має NetworkPolicy або запускає застосунок із серйозною помилкою. Допуск — це огорожа, а не повна програма безпеки.
Фреймворк прийняття рішень
Розділ «Фреймворк прийняття рішень»Обирайте PSA окремо, коли питання стосується стандартів Pod Security з апстріму, а межа політики — це простір імен. Простір імен, повний звичайних вебсервісів, зазвичай може примушувати restricted після виправлення прогалин образів та маніфестів. Застарілий простір імен може примушувати baseline, водночас попереджаючи про restricted. Простір імен агентів ноди може бути привілейованим із чітким власником та задокументованою причиною. Ці рішення достатньо прості, щоб виразити їх мітками, а прості політики легше аудитувати під тиском іспиту та виробничим стресом.
Обирайте AdmissionConfiguration, коли кластеру потрібна поведінка за замовчуванням або централізовано керовані винятки. Ключова фраза — «до того, як з’являться мітки». Якщо новостворені простори імен мають автоматично починатися з baseline, самих міток простору імен недостатньо, бо їх треба додавати після створення простору імен. Якщо kube-system чи спеціальний клас середовища виконання має бути звільнений, загальнокластерна конфігурація дає API-серверу узгоджений список винятків замість того, щоб вимагати від кожного власника простору імен пам’ятати спеціальні комбінації міток.
Обирайте Kyverno чи OPA Gatekeeper, коли правило не є частиною стандартів Pod Security. Конкретні приклади включають вимогу образів з registry.example.com, блокування змінних тегів образів, вимогу мітки бізнес-власника, обмеження портів хоста затвердженим діапазоном або дозвіл можливості лише для Pod’ів із конкретним сервісним акаунтом та міткою. Kyverno часто привабливий, коли команди хочуть політику як YAML та опційну мутацію. Gatekeeper часто привабливий, коли команди вже використовують Open Policy Agent та обмеження Rego на кількох платформах.
| Вимога | Мітки PSA | AdmissionConfiguration | Kyverno чи Gatekeeper |
|---|---|---|---|
| Примусити restricted в одному просторі імен | Найкраще підходить | Не потрібно | Не потрібно |
| Попереджати про порушення restricted під час міграції | Найкраще підходить | Корисно як значення за замовчуванням | Опційний рівень звітності |
| За замовчуванням непозначені простори імен → baseline | Самостійно недостатньо | Найкраще підходить | Можливо, але важче |
Звільнити kube-system чи клас середовища виконання | Самостійно недостатньо | Найкраще підходить | Можливо, але менш прямо |
| Вимагати затверджений реєстр образів | Не підтримується | Не підтримується | Найкраще підходить |
| Мутувати відсутні поля контексту безпеки | Не підтримується | Не підтримується | Kyverno або інший мутаційний рівень допуску |
Для іспиту CKS надавайте перевагу найменшому інструменту, що точно відповідає завданню. Якщо запит згадує pod-security.kubernetes.io/enforce, використовуйте мітки. Якщо він показує заборонне повідомлення, що називає violates PodSecurity "restricted:v1.35", виправте поля маніфесту. Якщо він згадує файл конфігурації допуску API-сервера, обережно відредагуйте конфігурацію PodSecurity. Якщо він просить політику, яку PSA не може виразити, поясніть або реалізуйте правило рушія політик, а не вдавайте, що мітка PSA може провалідувати довільні поля.
Чи знали ви?
Розділ «Чи знали ви?»- Kubernetes оголосив PodSecurityPolicy застарілою у v1.21 і видалив її у v1.25, тож сучасна практика CKS має зосереджуватися на PSA, а не на написанні нових об’єктів PSP.
- PSA має три незалежні режими, тобто один простір імен може примушувати baseline, водночас попереджаючи та проводячи аудит щодо restricted.
latestу мітці версії PSA слідує за версією політики API-сервера, тоді як значення на кшталтv1.35закріплює поведінку для безпечнішого планування оновлень.- Профіль restricted з апстріму вимагає відкинутих можливостей та seccomp, але не вимагає
readOnlyRootFilesystem, хоча багато посібників із виробничого посилення це рекомендують.
Типові помилки
Розділ «Типові помилки»| Помилка | Чому це трапляється | Як це виправити |
|---|---|---|
Увімкнення enforce: restricted до читання попереджень | Команди хочуть швидку міграцію та недооцінюють старі шаблони Pod’ів | Почніть з audit та warn, виправте поширені порушення, потім примушуйте простір імен за простором імен |
| Сприйняття PSA як клона PSP | PSP могла мутувати поля та виражати контроль поза стандартами Pod Security | Перенесіть значення за замовчуванням у маніфести чи мутаційний рушій політик, а PSA використовуйте для валідації |
Залишення міток версії на latest у виробництві | Це зручно в прикладах та лабораторіях | Закріпіть на цільову версію кластера, як-от v1.35, потім оновлюйте закріплення під час репетицій оновлення |
| Виправлення лише головного контейнера | Повідомлення про відхилення часто називають також init- чи ефемерні контейнери | Застосовуйте поля restricted до кожного типу контейнера, який оцінює PSA |
| Очікування, що режим audit попередить розробників | Анотації аудиту йдуть у журнали аудиту API, а не інтерактивному клієнту | Використовуйте warn для зворотного зв’язку розробникам, а audit — для централізованої звітності |
Додавання readOnlyRootFilesystem, щоб задовольнити PSA | Це хороший контроль посилення, тож люди припускають, що restricted його вимагає | Додавайте його, коли навантаження може його підтримати, але спочатку виправте фактичні поля PSA |
| Звільнення широкого автоматизаційного імені користувача | Це здається легшим, ніж класифікувати простори імен навантаження | Надавайте перевагу винятку простору імен чи runtimeClass, а винятки імен користувачів тримайте вузькими та переглянутими |
Тест
Розділ «Тест»1. Ваш простір імен примушує baseline і попереджає про restricted. Pod використовує `runAsUser: 0`, але не просить мережу хоста, привілейований режим чи небезпечні додані можливості. Чи має Pod бути допущений, і який зворотний зв'язок має побачити розробник?
Pod має бути допущений, бо baseline дозволяє контейнерам працювати від імені root, коли немає іншого порушення baseline. Розробник має побачити попередження, якщо профіль restricted налаштований у режимі warn, бо restricted не дозволяє запуск від імені root і очікує налаштувань не-root. Це звичайний патерн міграції: примус baseline блокує найнебезпечніші специфікації, тоді як попередження restricted визначають наступні завдання посилення.
2. Розгортання Deployment починає падати після того, як мітка простору імен змінюється на `pod-security.kubernetes.io/enforce: restricted`. Помилка згадує `allowPrivilegeEscalation != false` та `unrestricted capabilities`. Які зміни специфікації Pod'а є найменшим імовірним виправленням?
Задайте securityContext.allowPrivilegeEscalation: false для кожного контейнера Linux, якому його бракує, і задайте securityContext.capabilities.drop: ["ALL"] для відповідних контейнерів. Не додавайте спершу непов’язані налаштування, бо повідомлення допуску вже називає провалені перевірки. Після цього повторно застосуйте чи перезапустіть контролер, щоб новий запит на створення Pod’а пройшов через допуск із виправленим шаблоном.
3. Під час міграції PSP ви виявляєте, що старі навантаження проходили, бо PSP встановлювала за замовчуванням налаштування seccomp. Під PSA restricted ті самі маніфести відхиляються через відсутній `seccompProfile`. Чому це сталося?
PSA валідує поданий Pod; він не мутує відсутні поля до відповідності. PSP могла включати поведінку встановлення за замовчуванням, тож навантаження могли залежати від мутації політики, а не оголошувати власний контекст безпеки. Виправлення — додати seccompProfile.type: RuntimeDefault чи Localhost до специфікації Pod’а чи контейнера, або використати окремий мутаційний рівень допуску, перш ніж покладатися на примус PSA.
4. Ваша платформенна команда хоче, щоб кожен новий непозначений простір імен примушував baseline, попереджав про restricted та звільняв `kube-system`. Чи слід вам вирішувати це лише мітками простору імен?
Самих міток простору імен недостатньо, бо вимога застосовується до того, як власник простору імен додасть мітки, і включає виняток рівня кластера. Використовуйте PodSecurity AdmissionConfiguration, завантажену kube-apiserver, щоб задати значення за замовчуванням та винятки, потім дозвольте міткам простору імен перевизначати значення за замовчуванням, коли доречно. У керованому кластері перевірте, чи провайдер відкриває цю конфігурацію; інакше поєднайте значення за замовчуванням провайдера з автоматизацією простору імен.
5. Команда безпеки просить вас вимагати образи з внутрішнього реєстру, а також примушувати поля безпеки Pod'а restricted. Який рівень політики має володіти кожною частиною?
Використовуйте PSA для полів безпеки Pod’а restricted, бо саме для цього й призначений профіль restricted з апстріму. Використовуйте Kyverno, Gatekeeper чи інший рушій політик допуску для правила реєстру, бо PSA не валідує префікси реєстру образів. Тримання відповідальностей окремо робить універсальну основу безпеки Pod’ів легкою для аудиту, водночас залишаючи кастомні організаційні правила в мові політик, яка може їх виразити.
6. Простір імен наразі має `enforce: restricted` без мітки версії. Кластер оновлюється, і команда хоче детерміновану поведінку політики під час зміни. Що вам слід зробити?
Додайте відповідну мітку pod-security.kubernetes.io/enforce-version, як-от v1.35 для цілі Kubernetes 1.35, і зробіть те саме для міток warn та audit, коли вони присутні. Без міток версії версія політики слідує за поведінкою за замовчуванням, що може змінитися з версією API-сервера. Закріплення перетворює оновлення політики на явний крок впровадження, а не випадковий побічний ефект оновлення кластера.
7. Подія ReplicaSet каже, що створення Pod'а заборонено, бо init-контейнер порушує restricted, але головний контейнер уже має всі очікувані поля безпеки. Куди ви дивитеся далі?
Огляньте .spec.template.spec.initContainers у шаблоні контролера та додайте відсутні поля restricted до init-контейнера. PSA перевіряє init-контейнери так само, як звичайні контейнери, для доречних контролів, тож посилений головний контейнер не робить весь Pod відповідним. Після виправлення шаблону дайте контролеру створити свіжий Pod і підтвердіть, що подія більше не з’являється.
Практична вправа
Розділ «Практична вправа»Ця вправа використовує одноразовий простір імен та звичайні операції kubectl. Її розроблено, щоб зробити потік допуску видимим без потреби в доступі до файлів площини управління. Ви позначите простір імен, викличете зворотний зв’язок baseline та restricted, відремонтуєте Pod і огляньте мітки, що пояснюють, чому кожен запит повівся так, як він повівся. Якщо ви використовуєте лабораторію Killercoda, почніть із чистого терміналу й уникайте повторного використання назв просторів імен із попередніх спроб.
Завдання 1: Створити простір імен міграції з примусом baseline
Розділ «Завдання 1: Створити простір імен міграції з примусом baseline»Створіть простір імен, що примушує baseline, водночас попереджаючи та проводячи аудит restricted. Це віддзеркалює найбезпечнішу першу фазу реальної міграції, бо високоризикові Pod’и блокуються, але проблеми, що стосуються лише restricted, видимі до того, як вони стануть простоями.
kubectl create namespace psa-lab
kubectl label namespace psa-lab \ pod-security.kubernetes.io/enforce=baseline \ pod-security.kubernetes.io/enforce-version=v1.35 \ pod-security.kubernetes.io/warn=restricted \ pod-security.kubernetes.io/warn-version=v1.35 \ pod-security.kubernetes.io/audit=restricted \ pod-security.kubernetes.io/audit-version=v1.35 \ --overwrite
kubectl get namespace psa-lab --show-labelsНотатки до рішення для завдання 1
Фінальна команда має показати всі шість міток PSA. Якщо команда мітки провалюється, бо простір імен уже існує або мітка вже має значення, перезапустіть її з --overwrite. Важливий вибір дизайну — примушувати baseline, водночас спостерігаючи restricted.
Завдання 2: Підтвердити, що baseline блокує привілейовані Pod’и
Розділ «Завдання 2: Підтвердити, що baseline блокує привілейовані Pod’и»Застосуйте Pod, що просить привілейований режим. Pod має бути відхилений, бо привілейовані контейнери порушують baseline, а не лише restricted. Прочитайте повідомлення про помилку та визначте профіль, що заблокував запит.
cat <<'EOF' | kubectl apply -n psa-lab -f -apiVersion: v1kind: Podmetadata: name: privileged-demospec: containers: - name: app image: nginx:1.27-alpine securityContext: privileged: trueEOFНотатки до рішення для завдання 2
Запит має провалитися із заборонною помилкою, що називає порушення baseline PodSecurity. Якщо він успішний, огляньте мітки простору імен, бо примус може бути відсутнім або встановленим на privileged. Видаліть Pod після цього, якщо його було несподівано допущено.
Завдання 3: Викликати попередження restricted, не блокуючи Pod
Розділ «Завдання 3: Викликати попередження restricted, не блокуючи Pod»Створіть Pod, що проходить baseline, але не має налаштувань restricted. Pod має запуститися або принаймні бути допущеним, тоді як клієнт виводить попередження про порушення restricted, як-от відсутній seccomp, відсутні відкинуті можливості та вимоги не-root.
cat <<'EOF' | kubectl apply -n psa-lab -f -apiVersion: v1kind: Podmetadata: name: baseline-passspec: containers: - name: app image: busybox:1.36 command: ["sh", "-c", "sleep 3600"]EOF
kubectl get pod baseline-pass -n psa-labНотатки до рішення для завдання 3
Простір імен примушує baseline, тож звичайний Pod BusyBox без просторів імен хоста чи привілейованих налаштувань має бути допущений. Попередження restricted очікувані, бо Pod не має явних налаштувань не-root, seccomp, підвищення привілеїв та можливостей. Ці попередження — список ремонту для наступного завдання.
Завдання 4: Посилити примус за допомогою dry-run на стороні сервера
Розділ «Завдання 4: Посилити примус за допомогою dry-run на стороні сервера»Перед справжньою зміною примусу спитайте API-сервер, що сталося б, якби простір імен примушував restricted. Це звичка, що запобігає тому, щоб наявні, але невідповідні шаблони Pod’ів здивували вас під час впровадження.
kubectl label namespace psa-lab \ pod-security.kubernetes.io/enforce=restricted \ pod-security.kubernetes.io/enforce-version=v1.35 \ --dry-run=server \ --overwriteНотатки до рішення для завдання 4
Dry-run має повідомити про попередження, якщо наявні Pod’и в просторі імен порушують запропонований примусовий рівень. Оскільки це dry-run, він не має змінювати мітки простору імен. Підтвердіть за допомогою kubectl get namespace psa-lab --show-labels, якщо ви не впевнені.
Завдання 5: Створити Pod, сумісний з restricted
Розділ «Завдання 5: Створити Pod, сумісний з restricted»Застосуйте Pod, що оголошує поля, яких зазвичай вимагає restricted. Мета — не створити універсальний шаблон, а попрактикуватися перетворювати повідомлення PSA на конкретні поля маніфесту.
cat <<'EOF' | kubectl apply -n psa-lab -f -apiVersion: v1kind: Podmetadata: name: restricted-passspec: securityContext: runAsNonRoot: true runAsUser: 1000 seccompProfile: type: RuntimeDefault containers: - name: app image: busybox:1.36 command: ["sh", "-c", "sleep 3600"] securityContext: allowPrivilegeEscalation: false capabilities: drop: ["ALL"]EOF
kubectl get pod restricted-pass -n psa-labНотатки до рішення для завдання 5
Цей Pod має бути допущений без попереджень restricted, пов’язаних із поширеними полями в маніфесті. Якщо образ чи середовище виконання додає іншу проблему, прочитайте повідомлення попередження чи відхилення та виправте назване поле, а не змінюйте політику простору імен. Важлива практика — діагностика на рівні полів.
Завдання 6: Прибрати та записати, що зробив кожен режим
Розділ «Завдання 6: Прибрати та записати, що зробив кожен режим»Видаліть простір імен та запишіть по одному реченню для кожного режиму PSA. Це змушує вас відокремити рішення допуску від зворотного зв’язку розробникам та централізованої видимості аудиту.
kubectl delete namespace psa-labНотатки до рішення для завдання 6
enforce вирішив, чи був Pod допущений. warn повернув видимі попередження клієнту, водночас дозволяючи запит, коли примус пройшов. audit записав порушення політики в анотації аудиту API, коли журналювання аудиту було налаштоване. Ці три поверхні окремі, тому виробничі впровадження часто використовують усі три одразу.
Критерії успіху
Розділ «Критерії успіху»- Ви можете пояснити, чому
privileged-demoбув відхилений під примусом baseline. - Ви можете пояснити, чому
baseline-passбув допущений, але отримав попередження в режимі warn restricted. - Ви можете перетворити попередження PSA restricted на конкретні поля
securityContextPod’а. - Ви можете використати dry-run на стороні сервера перед посиленням примусу простору імен.
- Ви можете описати, коли міток простору імен достатньо, а коли потрібна AdmissionConfiguration.
- Ви можете назвати один приклад правила, що потребує Kyverno чи Gatekeeper, а не PSA.
Перевірка для учня
Розділ «Перевірка для учня»Baseline також забороняє томи HostPath; restricted успадковує це правило baseline, а потім звужує решту дозволених джерел томів.
Перш ніж рухатися далі, переконайтеся, що можете пояснити, чому Pod із spec.volumes[].hostPath падає в просторі імен, що примушує baseline:v1.35, навіть якщо він не просить привілейований режим чи простори імен хоста.
Джерела
Розділ «Джерела»- Kubernetes: Pod Security Admission
- Kubernetes: Pod Security Standards
- Kubernetes: Enforce Pod Security Standards by configuring namespace labels
- Kubernetes: Enforce Pod Security Standards with namespace labels and the built-in admission controller
- Kubernetes Blog: Pod Security Admission Controller Stable in v1.25
- Kubernetes: PodSecurityPolicy deprecation
- Kubernetes KEP 2579: Pod Security Admission
- Kubernetes: Migrate from PodSecurityPolicy to the Built-In PodSecurity Admission Controller
- Kubernetes source: restricted runAsNonRoot check
- Kyverno policy library: Pod Security Standards
- OPA Gatekeeper policy library
Наступний модуль
Розділ «Наступний модуль»Модуль 4.3: Керування секретами — Захист секретів Kubernetes.