Москва: проверенные б/у ноутбуки с гарантией и проверкой перед оплатой
+7 906 722-94-45

Главная → Статьи → Kyverno: admission-политики Kubernetes в YAML

Kyverno на практике: политики кластера на понятном YAML

Как описать правила для кластера в Kyverno: validate, mutate, generate, проверка подписей образов, режимы audit/enforce и внедрение без поломки деплоя.

Прямой ответ

Admission-контроллер — компонент, intercept'ящий запросы к API-серверу до записи (манифест проходит валидацию схемы, затем — «политики кластера» — «деплой приняли, но он не соответствует правилам» — отклоняется/мутируется на входе — k8s-механика); Kyverno — admission-политики на YAML (без OPA/Rego-языка — политики читаются как манифесты — «политика безопасности как код, который понимает разработчик» — главный аргумент против OPA Gatekeeper — Rego мощнее, но учить язык ради «nonroot обязателен» — избыточно — выбор-контекст); четыре типа правил: validate (отклонить несоответствие: «runAsNonRoot: true обязателен», «resource requests обязательны» — ресурсы-контекст — «задеплоили без лимитов — нода легла» — политика закрывает класс), mutate (поправить автоматически: добавить лейблы/annotations, sidecar-инъекция, подставить digest по тегу — «манифест неполный — дополним при admission» — defaults-слой — конфигурация), generate (создать сопутствующее: NetworkPolicy default-deny при создании namespace (networkpolicy — «новый namespace рождается изолированным»), quota/limitrange — «правила наследуются автоматически» — не по памяти онбордера), verifyImages (подписи образов — cosign-верификация при деплое (cosign — «задеплоить неподписанное» — API-сервер отклонит — supply chain-замок); режимы применения: audit (политика проверяет существующее, нарушения — в PolicyReport — «что уже нарушает» — картина без риска), enforce (отклонение при создании — жёсткий режим); внедрение-дисциплина (иначе «включили — всё легло»): (1) audit-фаза (недели — PolicyReport-скан кластера — список нарушителей — метрики-дашборд — «40 деплоев без nonroot» — работа до enforce), (2) fixes-волна (helm-шаблоны — securityContext/ресурсы в values по умолчанию — «политика + шаблон» — пара — конфигурация), (3) enforce по namespace'ам постепенно (флаги-культура), (4) exception'ы явные (policy-exceptions — ресурс с обоснованием/сроком — «legacy-сервис до марта» — не «выключили политику» — техдолг-учёт); политики — в git (IaC — terraform-дисциплина — PR-ревью политик — ревью-чеклист — «политика в проде без ревью» — инцидент-генератор); тесты политик обязательны (kyverno-cli — kyverno test с тест-манифестами — «политика отклоняет/пропускает/мутирует как задумано» — CI-джоба — github-actions — политики без тестов — мина — сценарий ниже).

Практика: набор политик продакшен-кластера

Базовый набор (проверенный, в порядке внедрения): (1) require-non-root (validate: runAsNonRoot=true, runAsUser>0, allowPrivilegeEscalation=false — харднинг — «root в контейнере» — закрыт входом — distroless-синергия); (2) require-requests-limits (validate: resources.requests.cpu/memory обязательны — ёмкость — «под без requests — нода перепродана — evict-лотерея» — политика + HPA-корректность — HPA без requests не считает утилизацию); (3) restrict-image-registries (validate: только свои реестры — «деплой с docker.io в обход» — supply chain — реестр — allowlist доменов); (4) disallow-latest-tag (mutate→validate: :latest запрещён (или мутируется в digest — verifyImages-связка — «откат невозможен с latest» — теги — репро-деплой); (5) require-probes (validate: liveness/readiness обязательны — healthcheck — «под без проб — роутер шлёт трафик в мёртвое» — политика минимума); (6) default-networkpolicy (generate: при создании namespace — default-deny ingress/egress (networkpolicy — изоляция по рождению); (7) verify-images (cosign identity+issuer (cosign — только CI-подписанное — audit→enforce отдельно — самый чувствительный (ломает локальные dev-деплои — dev-namespace исключения); (8) resource-quota-generate (generate: LimitRange на namespace — дефолты ресурсов — «забыли requests — лимитрейндж подставит» — защита нод); продвинутые: cleanup-политики (TTL старых джоб/failed-подов — реестр-гигиена — кластер не зарастает), PSS-профили (Pod Security Standards — baseline/restricted через Kyverno-шаблоны — «restricted для новых namespace» — постепенность); PolicyReport-обзор еженедельный (метрики — нарушения-тренд — incident-культура — «политики живут, когда смотрят отчёты»).

Практический сценарий: «политика легла прод» — и как делать правильно

Анти-сценарий (реальный, разбор): команда включила Kyverno с пятью enforce-политиками за день (nonroot+ресурсы+реестры+latest+пробы); 14:00 — enforce на весь кластер; 14:20 — деплой хотфикса отклонён («runAsNonRoot отсутствует» — легаси-манифест 2022 года — хотфикс не проходит — incident в разгар инцидента — классика); 14:40 — «выключили Kyverno целиком» (вместо исключения одной политики — защита пропала совсем — хуже исходного); постмортем: политика без audit-фазы/тестов/исключений — процесс-провал, не инструмент-провал; правильная версия той же задачи: (1) audit 2 недели (PolicyReport: 47 нарушений nonroot из 120 деплоев — метрики — работа видна до enforce); (2) fixes (helm-чарты: securityContext в values по умолчанию (helm — 35 из 47 закрыты шаблоном; 12 легаси — policy-exception с дедлайном и owner'ом — техдолг-реестр); (3) тесты (kyverno-cli: позитив/негатив/мутация — CI — github-actions — регрессия политики — красный билд — тесты-культура); (4) enforce поэтапно (dev → staging → прод-namespace'ы — стратегии — неделя); (5) break-glass (отдельная signed-джоба аварийного деплоя (cosign — «аварийка проходит политики, потому что собрана правильно» — не «политику выключили» — runbook-пункт); (6) проверка боем (тестовый «плохой» манифест в staging — отклонён с понятным сообщением — «сообщение политики» — UX для разработчика — message: с инструкцией, не «validation error» — доки-культура); итоги: 5 политик enforce за месяц, ноль инцидентов внедрения, нарушения новых деплоев — ноль (шаблоны+политики — пара — «правильное по умолчанию» — golden path — платформа-мышление); главный вывод: admission-политики — продукт для команд (audit → шаблоны → тесты → gradual enforce → exceptions с дедлайнами — «включить и посмотреть» — путь к выключенной безопасности — OWASP-процесс).

FAQ

Kyverno против OPA Gatekeeper — что выбрать? Язык: Kyverno — YAML/JMESPath-выражения (разработчик читает/пишет без нового языка), OPA — Rego (полноценный язык политик — мощнее для сложной логики — кривая обучения месяцы — «политики пишет один человек» — bus factor); охват: Kyverno — k8s-нативен (validate/mutate/generate/verifyImages — k8s-специфика из коробки), OPA — универсален (k8s+микросервисы+terraform+CI — «единая политика везде» — экосистема conftest — terraform-политики); производительность/зрелость — оба прод-готовы (CNCF — k8s-экосистема); критерий: команда без policy-инженера, политики — k8s-гигиена (nonroot/ресурсы/подписи) — Kyverno (быстрее внедрение, понимает каждый); организация с выделенной платформенной командой и политиками за пределами k8s — OPA; смешение — нормально (Kyverno в кластере, conftest в CI — CI-политики — разные слои — харднинг).

Почему политика пропускает нарушение / отклоняет не то? Типичные причины: match-ресурсы не те (политика на Deployments, нарушение — в StatefulSet/DaemonSet/CronJob — «job-поды без nonroot» — match все workload-типы (+Pod для голого — манифесты); exclude переборщили (namespace/лейбл-исключения шире задуманного — «исключили kube-system, а селектор сматчил и прод» — исключения — точечно — ревью); mutate-порядок (несколько mutate-политик на ресурс — алфавитный порядок применения — конфликт патчей — «мутация перетирает» — anchors/порядок проверять — kyverno-cli покажет); фоновые контроллеры (Deployment создаёт ReplicaSet создаёт Pod — политика на Pod сработает на создании пода контроллером — ошибка всплывёт в событиях реплисета, не деплоя — «apply прошёл, под не поднялся» — kubectl describe rs — диагностика); отладка: kyverno-cli apply/test локально (манифест+политика — мгновенно — тесты — «прод как тестовый стенд» — нет), PolicyReport + события Kyverno-пода (логи — причины решений видны).

Как обновлять политики, не ломая работающие деплои? Ключевой факт: admission работает на создании/изменении (существующие поды живут при любой новой политике — «ужесточили — старые поды не упали» — но пересоздание (деплой/эвикт/рескейл — HPA) — новый под по новым правилам — «нод-сбой + новая политика = под не встанет» — скрытая мина); практика: audit-фаза перед enforce (PolicyReport покажет, сколько живого нарушает — fixes до ужесточения — сценарий выше), исключения с дедлайнами для легаси (policy-exception — YAML-ресурс в git — IaC — «исключение живёт в репозитории, не в голове»), проверка пересоздания (тест: удалить под легаси-деплоя в staging — встанет ли — chaos-культура — «политика + эвикт» — сценарий, который забывают), rollback политики (git-revert + apply — стратегии — политика-код откатывается как код — минуты); мониторинг: метрика admission-отклонений (Prometheus — всплеск после ужесточения — разбор — алерты — «отклонения растут» — кто-то борется с политикой вместо фикса).

Нужны ли admission-политики в маленьком кластере / на одном сервере? Масштаб меняет цену ошибки, не класс рисков: «один сервер, три сервиса» (подман-контекст — там systemd-юниты, не k8s) — k8s-политики не нужны вовсе; маленький k8s (3–10 сервисов, команда 2–3) — минимальный набор окупается (nonroot+requests+latest-запрет — 3 политики, день внедрения с audit — харднинг — «маленький кластер» растёт, привычки формируются сразу — техдолг-предотвращение); одиночный разработчик на кластере — да, но шаблонами (helm-values по умолчанию — политика — страховка от себя-через-полгода — доки — «я помню» — не работает); критерий не размер, а цена пересоздания (поды пересоздаются автоматически — HPA/эвикты/нод-фейлы (failover — аналогия по серьёзности) — «встанет ли под заново по новым правилам» — вопрос, который политика делает явным — в любом размере).

Источники: документация Kyverno (introduction, writing policies, policy types) — ссылки в шапке.