Использование внешних политик Kyverno с KSPM
Использование внешних политик Kyverno с KSPM
В модуле Контроль Kubernetes® (KSPM) сервиса Yandex Security Deck можно использовать собственные политики на базе Kyverno, установленного модулем. Такие политики называются внешними: вы создаете и изменяете их напрямую через Kubernetes API — например, с помощью kubectl
KSPM управляет установкой Kyverno и своими правилами. Внешними политиками и сбором результатов их работы управляет пользователь. Нарушения внешних политик не создают алерты KSPM. Для сбора результатов можно отдельно установить Policy Reporter и настроить отправку — например, в Yandex Object Storage.
В этом руководстве вы настроите две CEL-политики из policies.kyverno.io/v1Audit и Deny, настроив через Policy Reporter отправку результатов в Object Storage.
Чтобы настроить внешние политики и сбор результатов:
- Подготовьте инфраструктуру.
- Создайте политику генерации NetworkPolicy.
- Создайте политику проверки ValidatingPolicy.
- Настройте отправку результатов в Object Storage.
- Проверьте доставку результатов.
Если созданные ресурсы вам больше не нужны, удалите их.
Перед началом работы
Зарегистрируйтесь в Yandex Cloud и создайте платежный аккаунт:
- Перейдите в консоль управления
, затем войдите в Yandex Cloud или зарегистрируйтесь. - На странице Yandex Cloud Billing
убедитесь, что у вас подключен платежный аккаунт, и он находится в статусеACTIVEилиTRIAL_ACTIVE. Если платежного аккаунта нет, создайте его и привяжите к нему облако.
Если у вас есть активный платежный аккаунт, вы можете создать или выбрать каталог, в котором будет работать ваша инфраструктура, на странице облака
Подробнее об облаках и каталогах.
Необходимые платные ресурсы
В стоимость поддержки инфраструктуры входит:
- мастер кластера (тарифы Managed Service for Kubernetes);
- вычислительные ресурсы и хранилище узлов (тарифы Yandex Compute Cloud);
- публичные IP-адреса мастера и узлов, если для них включен публичный доступ (тарифы Yandex Virtual Private Cloud);
- хранение данных и операции с объектами в Object Storage (тарифы Object Storage).
Подготовьте инфраструктуру
Примечание
Если у вас уже есть кластер Kubernetes с внешними политиками, перенесите свои политики на Kyverno по инструкции диагностики KSPM.
-
Создайте бакет Object Storage.
-
Создайте сервисный аккаунт с именем
kyverno-saи назначьте ему роли на каталог:k8s.clusters.agent— для управления кластером Kubernetes.vpc.publicAdmin— для работы с сетью Virtual Private Cloud.container-registry.images.puller— для скачивания необходимых Docker-образов.storage.uploader— для загрузки объектов в бакет.security-deck.worker— для работы в модуле KSPM.
-
Создайте статический ключ доступа для сервисного аккаунта. Сохраните идентификатор ключа и секретный ключ.
-
Создайте облачную сеть
kyverno-networkи [подсеть] (../../vpc/operations/subnet-create.md)kyverno-subnet. -
Создайте группу безопасности
kyverno-sgв той же сети. Добавьте правила из таблицы:Направление
трафикаДиапазон портов Протокол Источник /
назначениеCIDR-блоки /
группа безопасностиОписание Входящий443TCPДиапазон адресов0.0.0.0/0k8s-apiВходящий6443TCPДиапазон адресов0.0.0.0/0k8s-apiВходящий0-65535ЛюбойГруппа безопасностиТекущаяmaster-nodeВходящий0-65535ЛюбойДиапазон адресов10.96.0.0/16,10.112.0.0/16pods-servicesВходящий0-65535TCPПроверки состояния балансировщика— healthchecksИсходящий0-65535ЛюбойГруппа безопасностиТекущаяmaster-nodeИсходящий0-65535ЛюбойДиапазон адресов0.0.0.0/0nodes-external -
Создайте кластер Kubernetes:
- Облачная сеть —
kyverno-network. - Подсеть —
kyverno-subnet. - Сервисный аккаунт для ресурсов —
kyverno-sa. - Сервисный аккаунт для узлов —
kyverno-sa. - CIDR кластера —
10.96.0.0/16. - CIDR сервисов —
10.112.0.0/16.
Убедитесь, что кластер соответствует требованиям KSPM.
- Облачная сеть —
-
Создайте группу узлов, которая соответствует требованиям KSPM.
-
Активируйте KSPM для кластера. Для модуля должно быть включено хотя бы одно правило типа
Admission. -
Настройте доступ к кластеру через kubectl. Проверьте настройку:
-
Проверьте выбранный контекст:
kubectl config current-contextКоманда должна вывести контекст вашего кластера.
-
Убедитесь, что доступны типы политик из примера:
kubectl get crd validatingpolicies.policies.kyverno.io generatingpolicies.policies.kyverno.io -o nameРезультат:
... customresourcedefinition.apiextensions.k8s.io/validatingpolicies.policies.kyverno.io customresourcedefinition.apiextensions.k8s.io/generatingpolicies.policies.kyverno.io
-
Какими ресурсами управляет KSPM
Пространство имен yc-security зарезервировано для компонентов KSPM. KSPM управляет служебными ресурсами в этом пространстве имен. Размещайте внешние политики уровня пространства имен, Policy Reporter и свои приложения в отдельных пространствах имен.
KSPM сохраняет за собой право создавать, изменять, пересоздавать и удалять свои ресурсы при установке, обновлении, восстановлении состояния и удалении компонентов. Это относится к служебным ресурсам в yc-security, а также к политикам и CRD Kyverno с меткой kspm.yandex.cloud/managed-by: kspm.
Не изменяйте и не удаляйте служебные ресурсы KSPM вручную: KSPM может перезаписать ручные изменения таких ресурсов при дальнейшей работе.
Метка kspm.yandex.cloud/managed-by: kspm зарезервирована для ресурсов KSPM. Не устанавливайте ее на внешние политики — KSPM может принять их за свои и удалить.
Если нужно изменить конфигурацию Kyverno, который управляется KSPM, обратитесь в техническую поддержку.
Создайте политику генерации GeneratingPolicy
GeneratingPolicy автоматически создает NetworkPolicy, которая ограничивает входящие соединения. Она применяется ко всем подам этого пространства имен. Чтобы создать политику генерации:
-
Создайте файл
generate-policy.yamlс манифестом политики:apiVersion: policies.kyverno.io/v1 kind: GeneratingPolicy metadata: name: external-default-deny-ingress spec: matchConstraints: objectSelector: matchLabels: example.com/network-isolation: enabled resourceRules: - apiGroups: [""] apiVersions: [v1] operations: [CREATE, UPDATE] resources: [namespaces] variables: - name: namespace expression: object.metadata.name generate: - expression: >- generator.Apply(variables.namespace, [ { "apiVersion": dyn("networking.k8s.io/v1"), "kind": dyn("NetworkPolicy"), "metadata": dyn({"name": "default-deny-ingress"}), "spec": dyn({ "podSelector": dyn({}), "policyTypes": dyn(["Ingress"]), "ingress": dyn([]) }) } ]) -
Примените политику и дождитесь ее готовности:
kubectl apply -f generate-policy.yaml kubectl wait generatingpolicy.policies.kyverno.io/external-default-deny-ingress \ --for=jsonpath='{.status.conditionStatus.ready}'=true --timeout=120sРезультат:
generatingpolicy.policies.kyverno.io/external-default-deny-ingress created generatingpolicy.policies.kyverno.io/external-default-deny-ingress condition met -
Создайте файл
namespace.yamlс манифестом пространства имен:apiVersion: v1 kind: Namespace metadata: name: external-policy-workloads labels: example.com/network-isolation: enabled -
Создайте пространство имен и дождитесь создания NetworkPolicy:
kubectl apply -f namespace.yaml kubectl wait --for=create networkpolicy/default-deny-ingress \ -n external-policy-workloads --timeout=120s kubectl get networkpolicy default-deny-ingress -n external-policy-workloads -o yamlРезультат:
namespace/external-policy-workloads created networkpolicy.networking.k8s.io/default-deny-ingress condition metФрагмент вывода команды
kubectl get networkpolicy:apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: default-deny-ingress namespace: external-policy-workloads spec: podSelector: {} policyTypes: - Ingress
Создайте политику проверки ValidatingPolicy
ValidatingPolicy используется для проверки запросов и лимитов контейнеров Deployment. Чтобы создать политику проверки:
-
Создайте файл
validate-policy.yamlс манифестом политики:apiVersion: policies.kyverno.io/v1 kind: ValidatingPolicy metadata: name: external-require-resources annotations: policies.kyverno.io/title: Require resource requests and memory limits policies.kyverno.io/severity: medium spec: validationActions: - Audit failurePolicy: Ignore evaluation: admission: enabled: true background: enabled: true matchConstraints: namespaceSelector: matchLabels: kubernetes.io/metadata.name: external-policy-workloads resourceRules: - apiGroups: [apps] apiVersions: [v1] operations: [CREATE, UPDATE] resources: [deployments] variables: - name: containers expression: object.spec.template.spec.containers + object.spec.template.spec.?initContainers.orValue([]) validations: - expression: >- variables.containers.all(c, has(c.resources) && has(c.resources.requests) && 'cpu' in c.resources.requests && 'memory' in c.resources.requests && has(c.resources.limits) && 'memory' in c.resources.limits) message: "Each container must specify CPU and memory requests and a memory limit." -
Примените политику и дождитесь ее готовности:
kubectl apply -f validate-policy.yaml kubectl wait validatingpolicy.policies.kyverno.io/external-require-resources \ --for=jsonpath='{.status.conditionStatus.ready}'=true --timeout=120sРезультат:
validatingpolicy.policies.kyverno.io/external-require-resources created validatingpolicy.policies.kyverno.io/external-require-resources condition met
Политика external-require-resources проверяет развертывания в пространстве имен external-policy-workloads: каждый основной и init-контейнер должен иметь параметры request для CPU и памяти, а также параметр limit памяти. Параметр limit CPU не требуется. Параметр spec.evaluation.background.enabled: true также включает проверку существующих подходящих ресурсов.
Для CEL-политик в режиме Audit с фоновыми проверками рекомендуется указывать spec.failurePolicy: Ignore, чтобы недоступность Kyverno или ошибки в политике не блокировали запросы к кластеру. Действие при нарушении задается отдельно в spec.validationActions: Audit фиксирует нарушение, Deny отклоняет запрос.
Настройте отправку результатов в Object Storage
Для CEL-политик обычные результаты имеют источник KyvernoValidatingPolicy. Для заблокированных запросов плагин Kyverno создает отчеты на основе событий Kubernetes с источником Kyverno Event. Разрешите оба источника в настройках отправки.
В этом руководстве в Policy Reporter настраивается отправка результатов в Object Storage. Policy Reporter также поддерживает вебхуки, Loki, Elasticsearch, Kinesis и другие направления отправки
Установите Policy Reporter
Policy Reporter будет сохранять отчеты о проверка в бакет в формате JSON. Чтобы установить Policy Reporter:
-
Создайте пространство имен для Policy Reporter:
kubectl create namespace policy-reporterРезультат:
namespace/policy-reporter created -
Создайте файл
s3-secret.yaml. Укажите в нем идентификатор и секретную часть статического ключа:apiVersion: v1 kind: Secret metadata: name: policy-reporter-s3 namespace: policy-reporter type: Opaque stringData: accessKeyId: "<идентификатор_статического_ключа>" secretAccessKey: "<секретный_ключ>" -
Создайте секрет:
kubectl apply -f s3-secret.yamlРезультат:
secret/policy-reporter-s3 created -
Создайте файл
values.yamlс настройками Policy Reporter. В полеbucketукажите имя подготовленного бакета:fullnameOverride: external-policy-reporter image: tag: "3.11.2" ui: enabled: false plugin: kyverno: enabled: true image: tag: "0.7.3" blockReports: enabled: true eventNamespace: "" sourceFilters: [] target: s3: endpoint: https://storage.yandexcloud.net region: ru-central1 bucket: "<имя_бакета>" prefix: external-policies secretRef: policy-reporter-s3 skipExistingOnStartup: true sources: - kyverno - KyvernoValidatingPolicy - Kyverno Event filter: policies: exclude: - "kspm.*" - "*/kspm.*"Шаблоны
kspm.*и*/kspm.*исключают политики, которые управляются KSPM. Не используйте префиксkspm.для внешних политик.Параметр
eventNamespaceс пустым значением включает наблюдение за событиями во всех пространствах имен. Результаты будут сохраняться в бакете с префиксомexternal-policies/. -
Установите Policy Reporter:
helm repo add policy-reporter https://kyverno.github.io/policy-reporter helm repo update policy-reporter helm upgrade --install external-policy-reporter policy-reporter/policy-reporter \ --version 3.11.1 \ --namespace policy-reporter --create-namespace \ --values values.yaml \ --wait --timeout 5m -
Убедитесь, что поды Policy Reporter запущены:
kubectl get deployments -n policy-reporterРезультат:
NAME READY UP-TO-DATE AVAILABLE AGE external-policy-reporter 1/1 1 1 1m external-policy-reporter-kyverno-plugin 1/1 1 1 1m
Проверьте доставку результатов
Проверьте работу политики external-require-resources в двух режимах: Audit и Deny. В режиме Audit политика фиксирует нарушения, но не блокирует создание ресурсов. В режиме Deny политика отклоняет запросы, не соответствующие правилам. Результаты работы обоих режимов должны появиться в Object Storage.
Проверьте нарушение в режиме Audit
-
Создайте файл
deployment.yamlс манифестом Deployment без параметровrequestsиlimits:apiVersion: apps/v1 kind: Deployment metadata: name: external-audit-violation namespace: external-policy-workloads spec: replicas: 1 selector: matchLabels: app: external-audit-violation template: metadata: labels: app: external-audit-violation spec: containers: - name: nginx image: nginx:stable -
Создайте Deployment:
kubectl create -f deployment.yamlРезультат:
deployment.apps/external-audit-violation created -
Проверьте результат срабатывания политики:
kubectl get policyreports.wgpolicyk8s.io -n external-policy-workloads -o yamlДождитесь результата
failв PolicyReport. Фрагмент вывода:items: - scope: apiVersion: apps/v1 kind: Deployment name: external-audit-violation namespace: external-policy-workloads results: - policy: external-require-resources result: fail source: KyvernoValidatingPolicy -
В консоли управления
откройте подготовленный бакет Object Storage. В префиксеexternal-policies/найдите и скачайте JSON-объект с результатом этой проверки. Проверьте следующие поля:{ "policy": "external-require-resources", "status": "fail", "source": "KyvernoValidatingPolicy", "resource": { "kind": "Deployment", "namespace": "external-policy-workloads", "name": "external-audit-violation" } }
Проверьте блокировку запроса в режиме Deny
-
Переведите политику в режим
Deny:kubectl patch validatingpolicy.policies.kyverno.io external-require-resources \ --type=merge \ -p '{"spec":{"validationActions":["Deny"]}}' kubectl wait validatingpolicy.policies.kyverno.io/external-require-resources \ --for=jsonpath='{.status.conditionStatus.ready}'=true --timeout=120sРезультат:
validatingpolicy.policies.kyverno.io/external-require-resources patched validatingpolicy.policies.kyverno.io/external-require-resources condition met -
Создайте новый Deployment без параметров
requestsиlimits:kubectl create deployment external-denied --image=nginx:stable \ -n external-policy-workloadsЗапрос будет отклонен:
error: failed to create deployment: admission webhook "vpol.validate.kyverno.svc-ignore" denied the request: Policy external-require-resources failed: Each container must specify CPU and memory requests and a memory limit. -
Убедитесь, что ресурс не создан:
kubectl get deployment external-denied -n external-policy-workloads --ignore-not-foundКоманда не должна ничего вывести.
-
Дождитесь нового JSON-объекта в префиксе
external-policies/вашего бакета. Скачайте его и проверьте следующие поля:{ "policy": "external-require-resources", "status": "fail", "source": "Kyverno Event", "resource": { "kind": "Deployment", "namespace": "external-policy-workloads", "name": "external-denied" } } -
Исправьте Deployment, созданный в режиме
Audit:kubectl set resources deployment external-audit-violation \ -n external-policy-workloads \ --requests=cpu=100m,memory=64Mi --limits=memory=128MiРезультат:
deployment.apps/external-audit-violation resource requirements updated -
Повторно получите отчеты:
kubectl get policyreports.wgpolicyk8s.io -n external-policy-workloads -o yamlДождитесь результата
passдля исправленного Deployment:items: - scope: apiVersion: apps/v1 kind: Deployment name: external-audit-violation namespace: external-policy-workloads results: - policy: external-require-resources result: pass source: KyvernoValidatingPolicy
Проверьте исключение результатов KSPM
Новые результаты нарушений правил KSPM не должны появляться в бакете, а результаты нарушений внешних политик — продолжать поступать.
Результаты KSPM сохраняются в отчетах Kubernetes и хранилище Policy Reporter. Фильтр исключает их только из отправки в Object Storage.
Не удаляйте отчеты и результаты KSPM ради фильтрации своих уведомлений: KSPM использует их для доставки событий.
Как удалить созданные ресурсы
Чтобы перестать платить за созданные ресурсы:
- Удалите кластер Managed Service for Kubernetes.
- Удалите группу безопасности.
- Удалите подсеть.
- Удалите облачную сеть.
- Удалите сервисный аккаунт. Если аккаунт используется в настройках коннектора KSPM или для других задач, не удаляйте его.
- Удалите объекты из бакета.
- Удалите бакет.