Ця сторінка дозволяє вам спробувати декларативні політики допуску, які дають змогу використовувати Common Expression Language (CEL) для перевірки або зміни ресурсів.
Kubernetes 1.37 підтримує два види політик допуску:
Цей посібник охоплює обидва види політик допуску.
Вам треба мати кластер Kubernetes, а також інструмент командного рядка kubectl має бути налаштований для роботи з вашим кластером. Рекомендується виконувати ці настанови у кластері, що має щонайменше два вузли, які не виконують роль вузлів управління. Якщо у вас немає кластера, ви можете створити його, за допомогою minikube або використовувати одну з цих пісочниць:
Щоб визначати політики допуску, ви маєте бути адміністратором кластера. Переконайтеся, що маєте доступ адміністратора до кластера, на якому навчаєтеся.
Для ValidatingAdmissionPolicy вам потрібно:
Для MutatingAdmissionPolicy вам потрібно:
Щоб перевірити версію, виконайте kubectl version. Якщо ви використовуєте старішу версію Kubernetes, перегляньте документацію для цієї версії.
Декларативні політики допуску пропонують декларативну, вбудовану альтернативу вебхукам допуску.
Використовуючи Common Expression Language (CEL) для оголошення правил політики, ці політики оцінюються безпосередньо в API-сервері.
Ці політики мають широкі можливості налаштування, що дозволяє авторам політик визначати логіку, яку адміністратори кластерів можуть параметризувати та застосовувати до ресурсів залежно від потреб.
Ці два типи політик мають різне призначення.
ValidatingAdmissionPolicy призначена для забезпечення обмежень.
MutatingAdmissionPolicy призначена для зміни ресурсів під час допуску.
Кожна застосована політика завжди має обʼєкт політики (ValidatingAdmissionPolicy або MutatingAdmissionPolicy) та окремий обʼєкт привʼязки (ValidatingAdmissionPolicyBinding або MutatingAdmissionPolicyBinding).
Ви також можете використовувати параметри, які є необовʼязковими. Докладніше див. ресурси параметрів (ValidatingAdmissionPolicy) або ресурси параметрів (MutatingAdmissionPolicy).
Обʼєкти політики описують абстрактну логіку політики за допомогою Common Expression Language (CEL). Наприклад, ValidatingAdmissionPolicy може обмежувати кількість реплік або гарантувати наявність певних міток, тоді як MutatingAdmissionPolicy може змінювати ресурси, наприклад додавати типову мітку до простору імен.
Обʼєкти привʼязки повʼязують політику з вашим кластером і визначають область її дії. ValidatingAdmissionPolicyBinding або MutatingAdmissionPolicyBinding зʼєднує політику з конкретними ресурсами. Якщо ви хочете застосовувати політику лише до певної підмножини ресурсів, саме в привʼязці ви звужуєте область дії політики (за допомогою matchResources).
Параметри дають змогу відокремити конфігурацію поведінки політики від її визначення. Ресурси параметрів — це ресурси Kubernetes, доступні в API. Це можуть бути вбудовані типи API (як-от ConfigMap) або власні ресурси. Привʼязка політики потім використовує spec.paramRef, щоб посилатися на фактичний ресурс параметра.
Якщо політика не потребує параметрів, ви не вказуєте spec.paramKind.
Обидва види політик спираються на мову виразів, відому як Common Expression Language (CEL). Прочитайте CEL у Kubernetes, щоб дізнатися більше.
Якщо ви новачок у CEL, потренуйтеся писати дуже простий вираз, як-от false || true. Тестувати вирази CEL можна в CEL Playground.
Кожна привʼязка політики допуску повинна вказувати одну або кілька дій, щоб оголосити, як політика застосовується.
Для ValidatingAdmissionPolicyBinding підтримуваними validationActions є:
Невдала перевірка політики або помилка, що виникла, обробляються відповідно до цих дій. Збої, визначені failurePolicy, обробляються відповідно до цих дій, лише якщо failurePolicy встановлено в Fail (або не вказано).
Докладніше про логування аудиту для політик див. у розділі Анотації аудиту: помилки перевірки.
Не можна використовувати Deny і Warn разом, оскільки така комбінація дублювала б помилку перевірки і в тілі відповіді API, і в HTTP-заголовку Warning:.
Для MutatingAdmissionPolicyBinding дія завжди полягає у зміні обʼєкта.
Ви можете використовувати JSON Patch або apply configuration Kubernetes.
Тепер спробуйте визначити ValidatingAdmissionPolicy.
Нижче наведено приклад ValidatingAdmissionPolicy, яка вимагає, щоб будь-який Deployment мав кілька реплік.
---
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicy
metadata:
name: "enforce-multiple-replicas-deployments"
annotations:
kubernetes.io/description: "Require that matching Deployments have multiple replicas"
spec:
matchConstraints:
resourceRules:
- apiGroups: ["apps"]
apiVersions: ["v1"]
resources: ["deployments"] # the Deployment API
operations: ["CREATE", "UPDATE"] # the API verb, converted to upper case
validations:
- expression: "object.spec.replicas >= 2"
spec.validations містить вирази CEL, які використовують Common Expression Language (CEL) для перевірки запиту. Якщо вираз оцінюється як false, перевірка застосовується відповідно до поля spec.failurePolicy.
Напишіть подібну політику й застосуйте її.
Або, якщо ви хочете застосувати готовий маніфест:
kubectl apply --server-side -f https://k8s.io/examples/access/manifest-admission-control/vap-min-replicas.yaml
Сама по собі вона нічого не робить.
Ви можете спробувати створити Deployment з 0 або 1 реплікою; це працюватиме (хіба що інша політика завадить цьому).
Щоб вона запрацювала, визначте ValidatingAdmissionPolicyBinding.
Виберіть простір імен, де ви будете застосовувати нову політику.
Нижче наведено приклад ValidatingAdmissionPolicyBinding для політики, яку ви створили:
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicyBinding
metadata:
name: enforce-multiple-replicas-deployments-binding
spec:
policyName: "enforce-multiple-replicas-deployments"
validationActions: [Deny]
matchResources:
namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: default # змініть це, щоб відповідати простору імен, який ви використовуєте
Будь-хто з повним/адміністративним доступом до простору імен може записувати його мітки. Це включає видалення мітки з простору імен.
Мітка kubernetes.io/metadata.name захищена, але якщо ви використовуєте іншу мітку, подбайте, щоб видаляти або редагувати вибрану вами мітку могли лише довірені користувачі.
Створіть маніфест на основі цього прикладу YAML (якщо ви використовуєте простір імен default, ви можете використовувати його без змін). Застосуйте маніфест за допомогою kubectl apply.
Тепер перевірте політику. Спробуйте створити Deployment, а потім масштабувати його до 0 реплік за допомогою kubectl scale. Що відбувається?
Ви можете змінити ValidatingAdmissionPolicyBinding, щоб використовувати іншу дію перевірки замість Deny. Якщо вибрати дію перевірки Warning і спробувати масштабувати Deployment до 0 реплік, що станеться?
Якщо ви дійсно змінили налаштування ValidatingAdmissionPolicyBinding так, щоб воно лише попереджало користувачів, то тут є проблема…
Назва неправильна! Якщо ви змінюєте ValidatingAdmissionPolicyBinding або повʼязану ValidatingAdmissionPolicy так, що вона лише попереджає людей, ви повинні перевірити, чи також потрібно змінити назву політики. Ви б змінили назву, щоб переконатися, що назва не вводить людей в оману.
Якщо у вас є Deployment з 0 або 1 реплікою і ви знову перемкнете ValidatingAdmissionPolicyBinding у режим Deny, це не вплине на жодні наявні ресурси.
(Якщо ви захочете масштабувати Deployment до щонайменше 2 реплік, цього можна досягти іншим способом — наприклад, за допомогою контролера).
На цьому все для ValidatingAdmissionPolicy. Тепер ви дізнаєтеся про MutatingAdmissionPolicies.
Для цього прикладу уявіть, що ви хочете використовувати Pod security admission для забезпечення того, щоб простори імен, окрім системних просторів імен, застосовували стандарт безпеки Podʼів.
Подібно до перевірки, ви можете створити MutatingAdmissionPolicy, яка може змінювати ресурси під час допуску. Тип API, який вам потрібно змінити, — це Namespace.
Ось MutatingAdmissionPolicy, яка робить частину цього:
---
# Caution: read the notes for this default-pod-security-baseline policy before
# you apply it, so that you understand the information security consequences.
apiVersion: admissionregistration.k8s.io/v1
kind: MutatingAdmissionPolicy
metadata:
name: "default-pod-security-baseline"
annotations:
kubernetes.io/description: "Default new namespaces to enforce the Baseline pod security standard"
spec:
reinvocationPolicy: IfNeeded
matchConstraints:
resourceRules:
- apiGroups: [""]
apiVersions: ["v1"]
operations: ["CREATE"]
resources: ["namespaces"]
matchConditions:
- name: "exclude-system-namespaces"
# If the name begins with "kube-", it's a system namespace.
# Assume that the API server or cluster management tooling applies relevant defaults.
expression: "!object.metadata.name.startsWith('kube-')"
- name: "no-existing-pod-security-label"
expression: "!('pod-security.kubernetes.io/enforce' in object.metadata.labels)"
mutations:
- patchType: "ApplyConfiguration"
applyConfiguration:
expression: "Object{metadata: Object.metadata{labels: {'pod-security.kubernetes.io/enforce': 'baseline'}}}"
Ця політика встановлює типове значення. Той, хто має можливість оновлювати Namespace, може видалити мітку pod-security.kubernetes.io/enforce з простору імен.
Якщо ви не впевнені, що це означає, прочитайте документацію з безпеки або зверніться по зовнішню консультацію з інформаційної безпеки.
Щоб застосувати цю політику:
kubectl apply --server-side -f https://k8s.io/examples/access/manifest-admission-control/default-pod-security-baseline.yaml
Щоб активувати цю політику, потрібен MutatingAdmissionPolicyBinding; наприклад:
apiVersion: admissionregistration.k8s.io/v1
kind: MutatingAdmissionPolicyBinding
metadata:
name: default-pod-security-baseline
spec:
# назва MutatingAdmissionPolicy, яку застосовувати
policyName: default-pod-security-baseline
Спробуйте створити новий простір імен з назвою example:
kubectl create ns example
Перевірте його мітки:
kubectl describe ns example
Хоча ви не вказали рівень примусового застосування Pod security admission, мітку встановлено.
Далі перевірте, чи можете знайти спосіб обійти налаштування безпеки. Створіть YAML-маніфест для іншого Namespace:
apiVersion: v1
kind: Namespace
metadata:
name: another-example
labels:
pod-security.kubernetes.io/enforce: privileged
Ви можете створити цей простір імен з локального маніфесту за допомогою kubectl apply --server-side. Чи це працює?
Так, і новий простір імен дозволяє запускати привілейовані Podʼи.
Ця політика допуску не була налаштована для перевірки чи обмеження. Вона надає типове значення, але ви можете встановити власне. Однак ви можете поєднати змінювальний допуск із політикою перевірки допуску, щоб щось примусово забезпечити й водночас полегшити дотримання вимог. (Цей посібник цього не пояснює, але так можна зробити.)
Надання корисного типового значення означає, що коли люди нічого не встановлюють, вони отримують кращий результат, ніж просто повідомлення про помилку. Уявіть, що у вас є правило перевірки, згідно з яким усі простори імен мають примусово застосовувати щонайменше стандарт baseline. Той, хто не знає про це правило, може спробувати щось розгорнути й одразу побачити повідомлення про помилку, коли спробує створити простір імен.
Ресурси параметрів дають змогу відокремити конфігурацію політики від її визначення. Політика може визначати paramKind, який описує групу, версію та тип (також відомий як GVK) ресурсу параметра. Потім привʼязка політики повʼязує цю політику з областю дії, до якої її привʼязано, відповідно до налаштувань конкретного ресурсу параметра.
---
# Caution: read the notes for this default-pod-security-configurable policy before
# you apply it, so that you understand the information security consequences.
apiVersion: admissionregistration.k8s.io/v1
kind: MutatingAdmissionPolicy
metadata:
name: "default-pod-security-configurable"
annotations:
kubernetes.io/description: "Default new namespaces to enforce the chosen pod security standard"
spec:
reinvocationPolicy: IfNeeded
paramKind:
apiVersion: v1
kind: ConfigMap
matchConstraints:
resourceRules:
- apiGroups: [""]
apiVersions: ["v1"]
operations: ["CREATE"]
resources: ["namespaces"]
matchConditions:
- name: "exclude-system-namespaces"
# If the name begins with "kube-", it's a system namespace.
# Assume that the API server or cluster management tooling applies relevant defaults.
expression: "!object.metadata.name.startsWith('kube-')"
- name: "no-existing-pod-security-label"
expression: "!('pod-security.kubernetes.io/enforce' in object.metadata.labels)"
mutations:
- patchType: "ApplyConfiguration"
applyConfiguration:
expression: "Object{metadata: Object.metadata{labels: {'pod-security.kubernetes.io/enforce': params.data.default}}}"
Ось зразок MutatingAdmissionPolicyBinding:
---
apiVersion: admissionregistration.k8s.io/v1
kind: MutatingAdmissionPolicyBinding
metadata:
name: default-pod-security-configurable
spec:
# назва MutatingAdmissionPolicy, яку застосовувати
policyName: default-pod-security-configurable
# параметри для використання
paramRef:
# якщо ConfigMap відсутній або порожній, не встановлювати типове значення
# (але дозволити створення простору імен)
parameterNotFoundAction: Allow
# де знайти параметр
namespace: kube-system
name: default-pod-security-standard
і ось зразок ConfigMap, який потрібно помістити до простору імен kube-system:
---
apiVersion: v1
kind: ConfigMap
metadata:
namespace: kube-system
name: default-pod-security-standard
data:
default: baseline # також може бути "restricted"
Визначте обидва. Ви маєте спочатку створити ConfigMap; привʼязка очікує, що ресурс параметра вже існує (навіть якщо ви плануєте змінити його пізніше).
Тепер видаліть попередній MutatingAdmissionPolicyBinding:
kubectl delete mutatingadmissionpolicybindings/default-pod-security-baseline
і створіть новий простір імен:
kubectl create ns yet-another-example
kubectl describe ns yet-another-example
Чи отримали мітки типові значення?
# Ця команда запускає редактор, який дозволяє змінити .data.default для параметра
kubectl --namespace kube-system edit configmap default-pod-security-standard
Після зміни спробуйте створити ще один простір імен. Що відбувається?
Щоб видалити створені ресурси, виконайте такі команди:
kubectl delete validatingadmissionpolices/enforce-multiple-replicas-deployments \
validatingadmissionpolicybindings/enforce-multiple-replicas-deployments
kubectl delete mutatingadmissionpolicies/default-pod-security-baseline \
mutatingadmissionpolicybindings/default-pod-security-baseline
kubectl delete mutatingadmissionpolicies/default-pod-security-configurable \
mutatingadmissionpolicybindings/default-pod-security-configurable
kubectl --namespace kube-system delete configmaps/default-pod-security-standard
kubectl delete namespaces/example namespaces/another-example namespaces/yet-another-example
Якщо ви створили тестові Podʼи або тестові простори імен, приберіть і їх.