Контроль допуску на основі маніфестів

СТАН ФУНКЦІОНАЛУ: 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.

Підтримувані типи ресурсів для контролю допуску на основі маніфестів
Назва втулкаПідтримувані типи ресурсів
ValidatingAdmissionWebhookValidatingWebhookConfiguration
MutatingAdmissionWebhookMutatingWebhookConfiguration
ValidatingAdmissionPolicyValidatingAdmissionPolicy, ValidatingAdmissionPolicyBinding
MutatingAdmissionPolicyMutatingAdmissionPolicy, MutatingAdmissionPolicyBinding

Ви також можете використовувати v1.List, щоб обʼєднати кілька ресурсів одного типу втулка в одному документі.

Кожна тека, вказана у staticManifestsDir для певного втулка допуску, повинна містити лише типи ресурсів, дозволені для цього втулка. Наприклад, тека, налаштована для втулка ValidatingAdmissionPolicy, може містити лише ресурси ValidatingAdmissionPolicy та ValidatingAdmissionPolicyBinding.

Налаштування контролю допуску на основі маніфестів

Щоб увімкнути контроль допуску на основі маніфестів, вам потрібно:

  1. Увімкнути функціональну можливість ManifestBasedAdmissionControlConfig на kube-apiserver.
  2. Файл AdmissionConfiguration з полями staticManifestsDir, що вказують на теки, які містять ваші файли маніфестів.
  3. Самі файли маніфестів на диску, доступні для процесу 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.

Типи конфігурацій

Кожен втулок допуску використовує конкретний тип конфігурації:

Типи конфігурацій для кожного втулка допуску
ВтулокapiVersionkind
ValidatingAdmissionWebhookapiserver.config.k8s.io/v1WebhookAdmissionConfiguration
MutatingAdmissionWebhookapiserver.config.k8s.io/v1WebhookAdmissionConfiguration
ValidatingAdmissionPolicyapiserver.config.k8s.io/v1ValidatingAdmissionPolicyConfiguration
MutatingAdmissionPolicyapiserver.config.k8s.io/v1MutatingAdmissionPolicyConfiguration

Створення файлів маніфестів

Файли маніфестів містять стандартні визначення ресурсів 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 спостерігає за налаштованими теками на наявність змін:

  1. Початкове завантаження: Під час запуску всі налаштовані шляхи читаються та перевіряються. API-сервер не стає готовим, поки всі маніфести не будуть успішно завантажені. Неправильні маніфести призводять до помилки запуску.

  2. Динамічне перезавантаження: Зміни у файлах маніфестів запускають цикл перезавантаження:

    • Зміни файлів виявляються за допомогою fsnotify з резервним опитуванням (стандартний інтервал 1 хвилина), подібно до іншого перезавантаження конфігураційних файлів у kube-apiserver.
    • Обчислюється хеш вмісту всіх файлів маніфестів при кожній перевірці. Якщо хеш не змінився, перезавантаження не відбувається.
    • Нові конфігурації перевіряються перед застосуванням.
    • Якщо перевірка не вдається, помилка реєструється, метрики оновлюються, а попередня дійсна конфігурація зберігається.
    • Успішні перезавантаження атомарно замінюють попередню конфігурацію.
  1. Атомарне оновлення файлів: Щоб уникнути часткових читань під час запису файлів, вносьте зміни атомарно (наприклад, записуйте у тимчасовий файл і перейменовуйте його). Це особливо важливо при оновленні змонтованих 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 на основі файлів, такі як шифрування даних у спокої та автентифікація.

Оновлення та пониження версії

Оновлення: Увімкнення функції та надання конфігурації маніфестів є опціональним. Наявні кластери без конфігурації маніфестів не зазнають змін у поведінці.

Пониження версії: Перед пониженням до версії без цієї функції:

  1. Видаліть записи staticManifestsDir з файлу AdmissionConfiguration.
  2. Якщо ви покладаєтесь на політики на основі маніфестів, відтворіть їх як обʼєкти API, де це можливо.
  3. Перезапустіть 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.
Востаннє змінено May 05, 2026 at 3:37 PM PST: [uk] Ukrainian translation (all-in-one) (f7bdd3ee72)