Контроль допуску на основі маніфестів
Kubernetes v1.36 [alpha](стандартно вимкнено)Цей розділ надає огляд конфігурації контролю допуску на основі маніфестів. Контроль допуску на основі маніфестів дозволяє завантажувати вебхуки допуску та політики CEL з статичних файлів на диску, а не з API Kubernetes. Ці політики активні з моменту запуску API-сервера, працюють незалежно від etcd і можуть захищати ресурси допуску на основі API від модифікацій.
Щоб використовувати цю функцію, увімкніть функціональну можливість ManifestBasedAdmissionControlConfig і налаштуйте поле staticManifestsDir у файлі AdmissionConfiguration, переданому kube-apiserver через --admission-control-config-file.
Для чого використовувати контроль допуску на основі маніфестів?
Політики допуску та вебхуки, зареєстровані через API Kubernetes (такі як ValidatingAdmissionPolicy, MutatingAdmissionPolicy, ValidatingWebhookConfiguration та MutatingWebhookConfiguration), мають кілька вроджених обмежень:
- Пробіл при завантаженні: Застосування політик через REST вимагає створення та завантаження обʼєктів API динамічним контролером допуску. До цього моменту політики не застосовуються.
- Пробіл самозахисту: Ресурси конфігурації допуску (такі як ValidatingWebhookConfiguration) самі не підпадають під вебхук-допуск, щоб уникнути циклічних залежностей. Користувач з достатніми привілеями може видалити або змінити критичні політики допуску.
- Залежність від etcd: Конфігурації допуску через REST залежать від доступності etcd. Якщо etcd недоступний або пошкоджений, політики допуску можуть не завантажитися правильно.
Контроль допуску на основі маніфестів вирішує ці обмеження, завантажуючи конфігурації з файлів на диску. Ці конфігурації:
- Активні з моменту готовності API-сервера обслуговувати запити
- Не видимі та не змінювані через API Kubernetes
- Незалежні від доступності etcd
- Можуть перехоплювати операції над ресурсами допуску на основі API самі по собі
Підтримувані типи ресурсів
Ви можете включати наступні типи ресурсів у файли маніфестів. Підтримується лише версія API admissionregistration.k8s.io/v1.
| Назва втулка | Підтримувані типи ресурсів |
|---|---|
ValidatingAdmissionWebhook | ValidatingWebhookConfiguration |
MutatingAdmissionWebhook | MutatingWebhookConfiguration |
ValidatingAdmissionPolicy | ValidatingAdmissionPolicy, ValidatingAdmissionPolicyBinding |
MutatingAdmissionPolicy | MutatingAdmissionPolicy, MutatingAdmissionPolicyBinding |
Ви також можете використовувати v1.List, щоб обʼєднати кілька ресурсів одного типу втулка в одному документі.
Кожна тека, вказана у staticManifestsDir для певного втулка допуску, повинна містити лише типи ресурсів, дозволені для цього втулка. Наприклад, тека, налаштована для втулка ValidatingAdmissionPolicy, може містити лише ресурси ValidatingAdmissionPolicy та ValidatingAdmissionPolicyBinding.
Налаштування контролю допуску на основі маніфестів
Щоб увімкнути контроль допуску на основі маніфестів, вам потрібно:
- Увімкнути функціональну можливість
ManifestBasedAdmissionControlConfigна kube-apiserver. - Файл
AdmissionConfigurationз полямиstaticManifestsDir, що вказують на теки, які містять ваші файли маніфестів. - Самі файли маніфестів на диску, доступні для процесу kube-apiserver.
AdmissionConfiguration
Додайте staticManifestsDir до конфігурації втулка для кожного втулка допуску, який повинен завантажувати маніфести з диска. Кожен втулок потребує власної теки.
# Цей приклад AdmissionConfiguration налаштовує всі чотири втулка для
# завантаження контролю допуску на основі маніфестів з статичних файлів на диску.
apiVersion: apiserver.config.k8s.io/v1
kind: AdmissionConfiguration
plugins:
- name: ValidatingAdmissionWebhook
configuration:
apiVersion: apiserver.config.k8s.io/v1
kind: WebhookAdmissionConfiguration
kubeConfigFile: "<path-to-kubeconfig>"
staticManifestsDir: "/etc/kubernetes/admission/validating-webhooks/"
- name: MutatingAdmissionWebhook
configuration:
apiVersion: apiserver.config.k8s.io/v1
kind: WebhookAdmissionConfiguration
kubeConfigFile: "<path-to-kubeconfig>"
staticManifestsDir: "/etc/kubernetes/admission/mutating-webhooks/"
- name: ValidatingAdmissionPolicy
configuration:
apiVersion: apiserver.config.k8s.io/v1
kind: ValidatingAdmissionPolicyConfiguration
staticManifestsDir: "/etc/kubernetes/admission/validating-policies/"
- name: MutatingAdmissionPolicy
configuration:
apiVersion: apiserver.config.k8s.io/v1
kind: MutatingAdmissionPolicyConfiguration
staticManifestsDir: "/etc/kubernetes/admission/mutating-policies/"
Поле staticManifestsDir приймає абсолютний шлях до теки. Всі файли безпосередніх нащадків з розширеннями .yaml, .yml або .json у теці завантажуються. Підтеки та файли з іншими розширеннями ігноруються. Шаблони glob та відносні шляхи не підтримуються.
Передайте цей файл kube-apiserver за допомогою прапорця --admission-control-config-file.
Типи конфігурацій
Кожен втулок допуску використовує конкретний тип конфігурації:
| Втулок | apiVersion | kind |
|---|---|---|
ValidatingAdmissionWebhook | apiserver.config.k8s.io/v1 | WebhookAdmissionConfiguration |
MutatingAdmissionWebhook | apiserver.config.k8s.io/v1 | WebhookAdmissionConfiguration |
ValidatingAdmissionPolicy | apiserver.config.k8s.io/v1 | ValidatingAdmissionPolicyConfiguration |
MutatingAdmissionPolicy | apiserver.config.k8s.io/v1 | MutatingAdmissionPolicyConfiguration |
Створення файлів маніфестів
Файли маніфестів містять стандартні визначення ресурсів Kubernetes. Ви можете включати кілька ресурсів в один файл, використовуючи роздільники документів YAML (---).
Правила найменування
Всі обʼєкти у файлах маніфестів повинні мати імена, що закінчуються суфіксом .static.k8s.io. Наприклад: deny-privileged.static.k8s.io.
Коли функціональна можливість ManifestBasedAdmissionControlConfig увімкнена, створення обʼєктів допуску на основі API з іменами, що закінчуються на .static.k8s.io, блокується. Коли функціональна можливість вимкнена, повертається лише попередження.
Примітка:
Якщо два файли маніфестів визначають обʼєкти одного типу з однаковими іменами, API-сервер не запускається, показуючи відповідну помилку.Обмеження
Конфігурації допуску на основі маніфестів існують ізольовано і не можуть посилатися на ресурси API. Застосовуються наступні обмеження:
- Webhooks: Повинні використовувати
clientConfig.url. ПолеclientConfig.serviceне дозволяється, оскільки мережа сервісів може бути недоступною під час запуску API-сервера. - Policies: Поле
spec.paramKindне дозволяється. Політики не можуть посилатися на ConfigMaps або інші обʼєкти кластера для параметрів. - Bindings: Поле
spec.paramRefне дозволяється. Полеspec.policyNameповинно посилатися на політику, визначену в тому ж наборі файлів маніфестів, і повинно закінчуватися на.static.k8s.io.
Файли маніфестів декодуються за допомогою строгого декодера, який відхиляє файли, що містять дубльовані або невідомі поля. Кожен обʼєкт проходить те саме автоматичне заповнення та перевірку, що й REST API.
Приклади
Захист ресурсів допуску на основі API
Ключовою можливістю допуску на основі маніфестів є здатність перехоплювати операції над ресурсами конфігурації допуску (ValidatingAdmissionPolicy, MutatingAdmissionPolicy, ValidatingWebhookConfiguration, MutatingWebhookConfiguration та їхні привʼязки). REST-орієнтовані вебхуки та політики допуску не викликаються для цих типів ресурсів, щоб уникнути циклічних залежностей, але політики на основі маніфестів можуть застосовувати правила до них, оскільки вони не мають цієї циклічної залежності.
Наступний приклад дозволяє запобігати видаленню або модифікації ресурсів допуску, які мають мітку platform.example.com/protected: "true":
# Це приклад ValidatingAdmissionPolicy, який запобігає видаленню або
# зміні ресурсів доступу на основі API з міткою
# "platform.example.com/protected: true".
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicy
metadata:
name: "example-protect-admission-resources.static.k8s.io"
annotations:
kubernetes.io/description: "Prevent modification or deletion of protected admission resources"
spec:
failurePolicy: Fail
matchConstraints:
resourceRules:
- apiGroups: ["admissionregistration.k8s.io"]
apiVersions: ["*"]
operations: ["DELETE", "UPDATE"]
resources:
- "validatingadmissionpolicies"
- "validatingadmissionpolicybindings"
- "mutatingadmissionpolicies"
- "mutatingadmissionpolicybindings"
- "validatingwebhookconfigurations"
- "mutatingwebhookconfigurations"
validations:
- expression: >-
!has(oldObject.metadata.labels) ||
!('platform.example.com/protected' in oldObject.metadata.labels) ||
oldObject.metadata.labels['platform.example.com/protected'] != 'true'
message: "Protected admission resources cannot be modified or deleted"
---
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicyBinding
metadata:
name: "example-protect-admission-resources-binding.static.k8s.io"
annotations:
kubernetes.io/description: "Bind protect-admission-resources policy to all admission resources"
spec:
policyName: "example-protect-admission-resources.static.k8s.io"
validationActions:
- Deny
Застосування ValidatingAdmissionPolicy з диска
Наступний приклад визначає політику, яка забороняє привілейовані контейнери у всіх просторах імен, крім kube-system:
# Це приклад політики ValidatingAdmissionPolicy, яка забороняє запуск контейнерів із підвищеними правами
# у всіх просторах імен, крім kube-system.
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicy
metadata:
name: "example-deny-privileged.static.k8s.io"
annotations:
kubernetes.io/description: "Deny privileged containers outside kube-system"
spec:
failurePolicy: Fail
matchConstraints:
resourceRules:
- apiGroups: [""]
apiVersions: ["v1"]
operations: ["CREATE", "UPDATE"]
resources: ["pods"]
variables:
- name: allContainers
expression: >-
object.spec.containers +
(has(object.spec.initContainers) ? object.spec.initContainers : []) +
(has(object.spec.ephemeralContainers) ? object.spec.ephemeralContainers : [])
validations:
- expression: >-
!variables.allContainers.exists(c,
has(c.securityContext) && has(c.securityContext.privileged) &&
c.securityContext.privileged == true)
message: "Privileged containers are not allowed"
---
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicyBinding
metadata:
name: "example-deny-privileged-binding.static.k8s.io"
annotations:
kubernetes.io/description: "Bind deny-privileged policy to all namespaces except kube-system"
spec:
policyName: "example-deny-privileged.static.k8s.io"
validationActions:
- Deny
matchResources:
namespaceSelector:
matchExpressions:
- key: "kubernetes.io/metadata.name"
operator: NotIn
values: ["kube-system"]
Помістіть цей файл у теку, налаштовану як staticManifestsDir для втулка ValidatingAdmissionPolicy. Політика та її привʼязка завантажуються разом атомарно.
Налаштування ValidatingWebhookConfiguration з диска
Наступний приклад налаштовує вебхук перевірки, який викликає зовнішню URL-адресу:
# Це приклад конфігурації ValidatingWebhookConfiguration, яка викликає зовнішню
# точку доступу веб-хука на основі URL-адреси для перевірки створення та оновлень подів.
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
name: "example-security-webhook.static.k8s.io"
annotations:
kubernetes.io/description: "Validate pod creation and updates via external webhook"
webhooks:
- name: "security.platform.example.com"
clientConfig:
url: "https://security-webhook.platform.example.com:443/validate"
caBundle: "<base64-encoded-CA-bundle>"
rules:
- apiGroups: [""]
apiVersions: ["v1"]
operations: ["CREATE", "UPDATE"]
resources: ["pods"]
admissionReviewVersions: ["v1"]
sideEffects: None
failurePolicy: Fail
Примітка:
URL-адреси вебхуків повинні бути доступними для kube-apiserver під час запуску. Підтримуються лише точки доступу на основі URL-адрес; посилання на сервіси не допускаються в конфігураціях вебхуків на основі маніфестів.Використання формату List
Ви можете використовувати v1.List, щоб групувати повʼязані ресурси в одному документі:
# Це приклад використання формату v1.List для обʼєднання
# ValidatingAdmissionPolicy та її привʼязки в одному документі.
apiVersion: v1
kind: List
items:
- apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicy
metadata:
name: "example-require-labels.static.k8s.io"
annotations:
kubernetes.io/description: "Require app.kubernetes.io/name label on all pods"
spec:
failurePolicy: Fail
matchConstraints:
resourceRules:
- apiGroups: [""]
apiVersions: ["v1"]
operations: ["CREATE"]
resources: ["pods"]
validations:
- expression: >-
has(object.metadata.labels) &&
'app.kubernetes.io/name' in object.metadata.labels
message: "All pods must have the 'app.kubernetes.io/name' label"
- apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicyBinding
metadata:
name: "example-require-labels-binding.static.k8s.io"
annotations:
kubernetes.io/description: "Bind require-labels policy to all namespaces except kube-system"
spec:
policyName: "example-require-labels.static.k8s.io"
validationActions:
- Deny
matchResources:
namespaceSelector:
matchExpressions:
- key: "kubernetes.io/metadata.name"
operator: NotIn
values: ["kube-system"]
Порядок оцінки
Конфігурації на основі маніфестів оцінюються до конфігурацій на основі API. Це забезпечує пріоритет політик на рівні платформи, які застосовуються через статичну конфігурацію, над політиками на основі API.
Для самих ресурсів конфігурації допуску (ValidatingAdmissionPolicy, MutatingAdmissionPolicy, ValidatingAdmissionPolicyBinding, MutatingAdmissionPolicyBinding, ValidatingWebhookConfiguration, MutatingWebhookConfiguration) оцінюються лише втулки допуску на основі маніфестів. Втулки на основі API пропускаються для цих типів ресурсів, щоб уникнути циклічних залежностей.
Спостереження за файлами та динамічне перезавантаження
kube-apiserver спостерігає за налаштованими теками на наявність змін:
Початкове завантаження: Під час запуску всі налаштовані шляхи читаються та перевіряються. API-сервер не стає готовим, поки всі маніфести не будуть успішно завантажені. Неправильні маніфести призводять до помилки запуску.
Динамічне перезавантаження: Зміни у файлах маніфестів запускають цикл перезавантаження:
- Зміни файлів виявляються за допомогою fsnotify з резервним опитуванням (стандартний інтервал 1 хвилина), подібно до іншого перезавантаження конфігураційних файлів у kube-apiserver.
- Обчислюється хеш вмісту всіх файлів маніфестів при кожній перевірці. Якщо хеш не змінився, перезавантаження не відбувається.
- Нові конфігурації перевіряються перед застосуванням.
- Якщо перевірка не вдається, помилка реєструється, метрики оновлюються, а попередня дійсна конфігурація зберігається.
- Успішні перезавантаження атомарно замінюють попередню конфігурацію.
- Атомарне оновлення файлів: Щоб уникнути часткових читань під час запису файлів, вносьте зміни атомарно (наприклад, записуйте у тимчасовий файл і перейменовуйте його). Це особливо важливо при оновленні змонтованих ConfigMaps або Secrets у контейнеризованих середовищах.
Увага:
Якщо під час запуску присутній неправильний файл маніфесту, API-сервер не запускається. Під час роботи, якщо перезавантаження не вдається через помилки перевірки, попередня дійсна конфігурація зберігається, а помилка реєструється.Спостережуваність
Метрики
Контроль допуску на основі маніфестів надає наступні метрики для моніторингу стану перезавантаження:
| Тип | Опис | Метрика |
|---|---|---|
| Counter | Загальна кількість спроб перезавантаження, з мітками status (success або failure), plugin та apiserver_id_hash. | apiserver_manifest_admission_config_controller_automatic_reloads_total |
| Gauge | Час останньої спроби перезавантаження, з мітками status, plugin та apiserver_id_hash. | apiserver_manifest_admission_config_controller_automatic_reload_last_timestamp_seconds |
| Gauge | Поточна інформація про конфігурацію (значення завжди 1), з мітками plugin, apiserver_id_hash та hash. Використовуйте мітку hash для виявлення розбіжностей конфігурації між API-серверами. | apiserver_manifest_admission_config_controller_last_config_info |
Мітка plugin визначає втулок допуску, до якого застосовується метрика: ValidatingAdmissionWebhook, MutatingAdmissionWebhook, ValidatingAdmissionPolicy або MutatingAdmissionPolicy.
Оскільки обʼєкти на основі маніфестів мають імена, що закінчуються на .static.k8s.io, наявні метрики допуску (такі як apiserver_admission_webhook_rejection_count) можуть визначати рішення на основі маніфестів, фільтруючи за міткою name.
Анотації аудиту
Наявні анотації аудиту (такі як validation.policy.admission.k8s.io/validation_failure та mutation.webhook.admission.k8s.io/round_0_index_0) включають імʼя обʼєкта. Ви можете визначити рішення на основі маніфестів, фільтруючи за іменами, що закінчуються на .static.k8s.io.
Міркування стосовно високої доступності
Кожен екземпляр kube-apiserver завантажує свої власні файли маніфестів незалежно. У налаштуваннях високої доступності з кількома екземплярами API-сервера:
- Кожен API-сервер повинен бути налаштований окремо. Немає синхронізації конфігурацій на основі маніфестів між API-серверами.
- Використовуйте зовнішні інструменти управління конфігурацією (такі як Ansible, Puppet або спільні точки монтування) для підтримки узгодженості файлів маніфестів між екземплярами.
- Метрика
apiserver_manifest_admission_config_controller_last_config_infoнадає міткуhash, яку можна використовувати для виявлення розбіжностей конфігурації між екземплярами API-сервера.
Ця поведінка схожа на інші конфігурації kube-apiserver на основі файлів, такі як шифрування даних у спокої та автентифікація.
Оновлення та пониження версії
Оновлення: Увімкнення функції та надання конфігурації маніфестів є опціональним. Наявні кластери без конфігурації маніфестів не зазнають змін у поведінці.
Пониження версії: Перед пониженням до версії без цієї функції:
- Видаліть записи
staticManifestsDirз файлуAdmissionConfiguration. - Якщо ви покладаєтесь на політики на основі маніфестів, відтворіть їх як обʼєкти API, де це можливо.
- Перезапустіть kube-apiserver.
Попередження:
Пониження версії без видалення конфігураціїstaticManifestsDir призведе до того, що API-сервер не зможе запуститися через невідомі поля конфігурації.Усунення несправностей
| Симптом | Можлива причина | Рішення |
|---|---|---|
| API-сервер не запускається | Неправильний файл маніфесту при запуску | Перевірте журнали API-сервера на наявність помилок валідації. Виправте файл маніфесту та перезапустіть сервер. |
| API-сервер не запускається | Дублювання імен обʼєктів у файлах маніфестів | Переконайтеся, що всі імена обʼєктів у втулка staticManifestsDir унікальні. |
| Політики не застосовуються після оновлення файлу | Помилка перезавантаження валідації | Перевірте метрику automatic_reloads_total{status="failure"} та журнали API-сервера. Виправте маніфест і дочекайтеся наступного циклу перезавантаження. |
| Запити вебхуків не виконуються | URL вебхука недоступний | Перевірте, чи доступний URL, вказаний у clientConfig.url, з kube-apiserver. |
Неможливо створити обʼєкти API з суфіксом .static.k8s.io | Суфікс імені зарезервований для функції | Суфікс .static.k8s.io зарезервований для конфігурацій на основі маніфестів, коли функція увімкнена. Використовуйте інше імʼя для обʼєктів на основі API. |
Що далі
- Дізнайтеся про ValidatingAdmissionPolicy для політик валідації на основі CEL.
- Дізнайтеся про MutatingAdmissionPolicy для політик мутації на основі CEL.
- Дізнайтеся про Dynamic Admission Control для контролю доступу на основі вебхуків.
- Прочитайте документ про дизайн KEP-5793.