Deckhouse 1.68 на тестовом КИИ-кластере: admission webhook для политик ФСТЭК и меньше ручных CRD
Обновили тестовый кластер до Deckhouse 1.68: разбираем changelog с точки зрения КИИ - нативный admission webhook для security-policy и поддержка Kubernetes 1.33.
Deckhouse Kubernetes Platform 1.68 вышел с поддержкой Kubernetes 1.33 и улучшениями модуля security-policy
На прошлой неделе прогнали обновление до Deckhouse 1.68 на тестовом кластере, который живёт как стенд для КИИ-конфигураций. Это не первый раз, когда мы идём сначала туда, а не сразу в production - предыдущий опыт с Deckhouse и сертификатом ФСТЭК показал: лучше разобраться с нюансами на стенде, чем потом объяснять клиенту, почему политика безопасности перестала работать.
В этот раз интересен changelog не с точки зрения CNI или staged rollout (это мы разбирали раньше), а именно с точки зрения security-policy и того, как 1.68 меняет жизнь на сертифицированной КИИ-инфраструктуре.
Kubernetes 1.33: что это значит для КИИ-кластера
Поддержка Kubernetes 1.33 в Deckhouse 1.68 - это не просто «апгрейд версии». Для КИИ-кластеров это означает несколько конкретных вещей.
В 1.32 стабилизировался DRA (Dynamic Resource Allocation) - механизм, который нужен для нормальной работы с аппаратными ускорителями и специализированными устройствами; в 1.33 он уже работает как stable. Для промышленных контуров, где в кластере могут работать контроллеры с аппаратными интерфейсами, это полезно. Но важнее другое: 1.33 закрыл несколько CVE в kube-apiserver, которые в предыдущих версиях требовали дополнительных компенсирующих мер. На сертифицированной платформе это напрямую влияет на модель угроз.
Практически: обновление прошло без сюрпризов. API-несовместимостей в нашем тестовом стенде не обнаружили. Ресурсы, которые были задеплоены на 1.32, поднялись без изменений манифестов. Если в вашем кластере есть кастомные операторы с захардкоженными версиями API - стоит перепроверить, но для стандартного KII-стека на Deckhouse это некритично.
security-policy: наконец-то нативный admission webhook
Вот это главное изменение для наших задач. Модуль security-policy в 1.68 перешёл на нативный ValidatingAdmissionWebhook вместо прежней схемы с Gatekeeper в качестве промежуточного слоя.
Что это меняет на практике.
Раньше схема была такой: Deckhouse разворачивал Gatekeeper, под него создавались ConstraintTemplate CRD, под каждое требование ФСТЭК - отдельный Constraint. В итоге на кластер ложилось несколько десятков CRD только ради политик безопасности. При аттестации это создавало головную боль: инспектор смотрит на кластер, видит кучу кастомных ресурсов, задаёт вопросы. Нам приходилось каждый раз объяснять, что это не хаос, а политики.
Теперь модуль security-policy работает напрямую через SecurityPolicy CRD - один ресурс, понятная структура, встроенный webhook. Gatekeeper по умолчанию больше не поднимается, если не нужен явно. Количество CRD в кластере сократилось примерно вдвое только за счёт этого изменения.
Пример того, как теперь выглядит политика запрета привилегированных контейнеров:
apiVersion: deckhouse.io/v1alpha1
kind: SecurityPolicy
metadata:
name: fstec-no-privileged
spec:
match:
namespaceSelector:
matchLabels:
security-zone: critical
policies:
allowPrivileged: false
allowPrivilegeEscalation: false
runAsNonRoot: true
Никаких ConstraintTemplate, никаких Constraint, никакого Rego. Просто декларативный CRD с понятной семантикой. Аудитору объяснять проще, документировать проще, поддерживать - тоже.
Что поменяли в аудит-логах
В 1.68 изменилась детализация событий от security-policy webhook. Раньше в логах kube-apiserver при отклонении запроса появлялось что-то вроде admission webhook "validation.gatekeeper.sh" denied the request - и дальше нужно было смотреть в логи Gatekeeper, чтобы понять, какая именно политика сработала.
Теперь в событии аудита явно указывается имя SecurityPolicy и конкретный параметр, который нарушен. Это важно для SIEM-интеграции: если вы отдаёте аудит-логи Kubernetes в MaxPatrol SIEM или аналог - парсер теперь может однозначно связать событие с конкретным требованием из модели угроз. Раньше это требовало дополнительных корреляций.
Что не понравилось
Честно: миграция с Gatekeeper на нативный webhook не полностью автоматическая. Если у вас были кастомные ConstraintTemplate под задачи, которые выходят за рамки стандартного security-policy - их нужно переписать вручную или оставить Gatekeeper работать параллельно. В нашем тестовом стенде был один кастомный шаблон для проверки лейблов на namespace - его пришлось перенести.
Документация на этот момент у Deckhouse есть, но неполная. В migration guide описан стандартный сценарий, а нестандартные конструкции остаются на совести оператора. Мы потратили пару часов, чтобы разобраться с одним хитрым шаблоном.
Второй момент - при обновлении с версий до 1.65 есть промежуточный шаг, который нельзя пропустить. На 1.66 или 1.67 нужно явно дать команду миграции модуля перед апгрейдом до 1.68. Мы об этом знали заранее (читали release notes), но если обновляться через несколько минорных версий по-умолчанию - есть риск словить неработающий webhook при запуске. На тестовом стенде это пережить легко, в production - неприятно.
Вывод по тестовому стенду
Для managed-кластеров на КИИ это обновление даёт реальное упрощение: меньше CRD, лучше аудит, понятнее структура для аттестации. Обновление на production-кластеры планируем после того, как пройдёт ещё пара недель на стенде и убедимся, что новые аудит-события нормально ложатся в SIEM.
Контекст по новым требованиям ФСТЭК к непрерывному мониторингу КИИ первой категории, которые появились в начале января, добавляет этому обновлению дополнительный вес - подробнее писали в отдельном посте. Улучшенная детализация аудит-событий от security-policy как раз ложится в эту задачу.