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"