fix pols for 1.18

This commit is contained in:
2026-05-14 18:55:39 +07:00
parent 5578400e7f
commit ffa61ab646
19 changed files with 266 additions and 180 deletions
+114 -57
View File
@@ -1,57 +1,114 @@
# Другие варианты проверок
#
# проверить, что PVC использует StorageClass из одобренного списка:
#
rules:
- name: check-storage-class
match:
resources:
kinds:
- PersistentVolumeClaim
context:
- name: storageClassInfo
apiCall:
urlPath: "/apis/storage.k8s.io/v1/storageclasses/{{ request.object.spec.storageClassName }}"
jmesPath: "metadata.labels.\"approved-for-production\""
validate:
message: >-
StorageClass '{{ request.object.spec.storageClassName }}' не одобрена для production.
Используйте StorageClass с лейблом approved-for-production: "true"
deny:
conditions:
- key: "{{ storageClassInfo }}"
operator: NotEquals
value: "true"
# проверить, что количество реплик не превышает кворум с учётом текущей нагрузки:
#
context:
- name: existingDeployments
apiCall:
urlPath: >-
/apis/apps/v1/namespaces/{{ request.object.metadata.namespace }}/deployments
jmesPath: "items[?metadata.name != '{{ request.object.metadata.name }}'] | length(@)"
validate:
message: >-
В namespace уже {{ existingDeployments }} деплойментов.
Максимум разрешено 20.
deny:
conditions:
- key: "{{ existingDeployments }}"
operator: GreaterThanOrEquals
value: "20"
# принимать решения на основе состояния нод
#
context:
- name: nodesInfo
apiCall:
urlPath: "/api/v1/nodes"
jmesPath: "items[?metadata.labels.\"node-type\" == 'gpu'].metadata.name"
validate:
message: "GPU workloads требуют минимум 2 GPU-ноды в кластере"
deny:
conditions:
- key: "{{ length(nodesInfo) }}"
operator: LessThan
value: "2"
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: check-storage-class-approval
annotations:
policies.kyverno.io/title: "Проверка одобрения StorageClass"
policies.kyverno.io/category: Governance
policies.kyverno.io/severity: high
policies.kyverno.io/subject: PersistentVolumeClaim
policies.kyverno.io/description: >-
Проверяет, что PVC использует StorageClass из одобренного списка.
StorageClass считается одобренной, если имеет лейбл approved-for-production: "true".
spec:
validationFailureAction: Enforce
background: false
rules:
- name: check-storage-class
match:
resources:
kinds:
- PersistentVolumeClaim
context:
- name: storageClassInfo
apiCall:
urlPath: "/apis/storage.k8s.io/v1/storageclasses/{{ request.object.spec.storageClassName }}"
jmesPath: "metadata.labels.\"approved-for-production\""
validate:
message: >-
StorageClass '{{ request.object.spec.storageClassName }}' не одобрена для production.
Используйте StorageClass с лейблом approved-for-production: "true".
deny:
conditions:
any:
- key: "{{ storageClassInfo }}"
operator: NotEquals
value: "true"
---
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: limit-deployments-per-namespace
annotations:
policies.kyverno.io/title: "Лимит Deployment в namespace"
policies.kyverno.io/category: Governance
policies.kyverno.io/severity: medium
policies.kyverno.io/subject: Deployment
policies.kyverno.io/description: >-
Ограничивает количество Deployment в одном namespace до 20.
Используется apiCall для подсчёта существующих деплойментов.
spec:
validationFailureAction: Enforce
background: false
rules:
- name: check-deployment-count
match:
resources:
kinds:
- Deployment
context:
- name: existingDeployments
apiCall:
urlPath: >-
/apis/apps/v1/namespaces/{{ request.object.metadata.namespace }}/deployments
jmesPath: "items[?metadata.name != '{{ request.object.metadata.name }}'] | length(@)"
validate:
message: >-
В namespace '{{ request.object.metadata.namespace }}' уже {{ existingDeployments }} деплойментов.
Максимум разрешено 20.
deny:
conditions:
any:
- key: "{{ existingDeployments }}"
operator: GreaterThanOrEquals
value: "20"
---
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: require-gpu-nodes-for-gpu-workloads
annotations:
policies.kyverno.io/title: "GPU workloads требуют GPU-нод"
policies.kyverno.io/category: Resources
policies.kyverno.io/severity: high
policies.kyverno.io/subject: Pod
policies.kyverno.io/description: >-
Запрещает запускать GPU-workloads если в кластере меньше 2 GPU-нод.
GPU-workload определяется лейблом workload-type: gpu на поде.
spec:
validationFailureAction: Enforce
background: false
rules:
- name: check-gpu-nodes
match:
resources:
kinds:
- Pod
selector:
matchLabels:
workload-type: gpu
context:
- name: gpuNodes
apiCall:
urlPath: "/api/v1/nodes"
jmesPath: "items[?metadata.labels.\"node-type\" == 'gpu'].metadata.name"
validate:
message: >-
GPU workloads требуют минимум 2 GPU-ноды в кластере.
Текущее количество GPU-нод: {{ length(gpuNodes) }}.
deny:
conditions:
any:
- key: "{{ length(gpuNodes) }}"
operator: LessThan
value: "2"
@@ -1,33 +1,60 @@
# Полезный паттерн — разные правила для CREATE и UPDATE
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: validate-deployment-operations
annotations:
policies.kyverno.io/title: "Разные проверки для CREATE и UPDATE"
policies.kyverno.io/category: Governance
policies.kyverno.io/severity: medium
policies.kyverno.io/subject: Deployment
policies.kyverno.io/description: >-
Демонстрирует паттерн: разные правила для CREATE и UPDATE операций.
При создании — обязательные лейблы app и team.
При обновлении — запрет смены образа на тег latest.
spec:
validationFailureAction: Enforce
background: false
rules:
- name: validate-on-create-only
match:
resources:
kinds:
- Deployment
preconditions:
any:
- key: "{{ request.operation }}"
operator: Equals
value: CREATE
validate:
message: >-
Новый Deployment '{{ request.object.metadata.name }}' должен иметь лейблы app и team.
pattern:
metadata:
labels:
app: "?*"
team: "?*"
rules:
- name: validate-on-create-only
match:
resources:
kinds:
- Deployment
preconditions:
any:
- key: "{{ request.operation }}"
operator: Equals
value: CREATE
validate:
# применяется только при создании
- name: validate-image-on-update
match:
resources:
kinds:
- Deployment
preconditions:
all:
- key: "{{ request.operation }}"
operator: Equals
value: UPDATE
- key: >-
{{ request.object.spec.template.spec.containers[0].image }}
operator: NotEquals
value: >-
{{ request.oldObject.spec.template.spec.containers[0].image }}
validate:
# применяется только при UPDATE с изменением образа
- name: validate-image-on-update
match:
resources:
kinds:
- Deployment
preconditions:
all:
- key: "{{ request.operation }}"
operator: Equals
value: UPDATE
- key: "{{ request.object.spec.template.spec.containers[0].image }}"
operator: NotEquals
value: "{{ request.oldObject.spec.template.spec.containers[0].image }}"
validate:
message: >-
Образ изменён с '{{ request.oldObject.spec.template.spec.containers[0].image }}'
на '{{ request.object.spec.template.spec.containers[0].image }}'.
Запрещено использовать тег latest при обновлении образа.
deny:
conditions:
any:
- key: "{{ request.object.spec.template.spec.containers[0].image }}"
operator: EndsWith
value: ":latest"