Расширение сред Kubernetes (K8s), добавление новых кластеров и приложений — необходимые процессы для развития сервисов. В таких условиях для каждого администратора Kubernetes критически важно обеспечить последовательность и непрерывность соблюдения политик безопасности (ПБ) для всех новых и существующих ресурсов. Но сделать это вручную почти невозможно: сложно, дорого, снижает гибкость разработки, повышает риск ошибок из-за человеческого фактора. Администратору для комфортной работы с ПБ нужна автоматизация. И в этом ему поможет Gatekeeper.
Меня зовут Александр Чадин, я ведущий программист VK Cloud Solutions. У нас в облаке есть Gatekeeper, и я расскажу, как с его помощью автоматизировать работу с политиками безопасности в Kubernetes, как работает этот инструмент и когда он нужен.
Главное о Gatekeeper
Gatekeeper — специфическая реализация Open Policy Agent (OPA) для Kubernetes, которая работает в качестве Webhook для валидации манифестов. Этот инструмент предназначен для аудита и автоматического применения к ресурсам Kubernetes политик безопасности, написанных на языке Rego.
Gatekeeper встраивается между сервером API Kubernetes и OPA, принимает все поступающие в кластер запросы и в реальном времени проверяет их на соответствие предварительно настроенным политикам безопасности.
При такой схеме Gatekeeper регистрируется в качестве контроллера с помощью Webhook-проверки в API Kubernetes
Gatekeeper запускается при каждом создании, обновлении или удалении ресурсов в кластере. Gatekeeper Webhook перехватывает запросы, направленные в Kubernetes API, и проверяет их цепочкой политик, определенных администратором кластера. Ограничения оцениваются как логические, и если они не выполняются, то запрос отклоняется.
Прелесть Gatekeeper в том, что он позволяет:
- контролировать действия пользователя в кластере;
- автоматически применять установленные политики безопасности ко всему кластеру.
Одновременно с этим Gatekeeper упрощает взаимодействие DevOps-специалистов и разработчиков: DevOps-инженеры могут не переживать по поводу ошибок при разработке, а разработчики получают мгновенную обратную связь о том, что не так и где нужны изменения.
В актуальной версии Gatekeeper контроллер допуска интегрирован с OPA Constraint Framework. Он обеспечивает соблюдение политик на основе CRD и надежность совместного использования декларативно настроенных политик.
Gatekeeper отвечает за контроль допуска и аудита. Это позволяет:
- создавать шаблоны политик на языке Rego;
- формировать политики в виде CRD;
- хранить результаты аудита в CRD политики.
Схема работы Gatekeeper
Политики Gatekeeper состоят из двух манифестов:
-
Шаблон ограничений (Constraint Template). Позволяет объявлять новые ограничения и отделять логику ограничения от конкретных ресурсов, к которым она применяется. Шаблон содержит всю информацию для работы ограничения, включая тип объекта, к которому оно применяется, и параметры, которые ограничение должно предоставлять.
-
Ограничения (Constraints). Это объединение шаблонов с параметрами — ресурсами разных типов: поды, деплойменты, секреты и другие. Спецификацию ограничений также используют для выбора принудительного действия (Deny, Warn или Dry Run). По умолчанию для него установлено значение Deny: отклоняются любые приводящие к нарушениям запросы на добавление, изменение или удаление ресурса.
В связке с Gatekeeper работает аудитор. Он позволяет администраторам видеть, какие из уже существующих ресурсов нарушают вводимые политики безопасности. Фактически аудитор помогает привести к соответствию политикам все ресурсы на кластере, независимо от того, когда они были созданы — до принятия политики или после.
Особенности работы с Gatekeeper
Рассмотрим особенности каждого этапа работы с Gatekeeper.
Проверка контроля допуска
После установки всех компонентов Gatekeeper в кластере сервер API вызывает Webhook Gatekeeper Admission для обработки запросов в API Kubernetes. Запуск происходит при каждом создании, обновлении или удалении ресурса в кластере.
При проверке Gatekeeper действует как мост между сервером API и OPA. Сервер API применяет все политики, выполняемые OPA.
Политики и ограничения
Каждое ограничение записывают с помощью декларативного языка Rego, который использует OPA для перечисления экземпляров данных, нарушающих ожидаемое состояние системы. Все ограничения оцениваются как логические: если одно не выполнено, отклоняется весь запрос.
Перед определением ограничения создают шаблон, который позволяет объявлять новые ограничения.
Пример шаблона ограничения CRD, которое требует наличия определенных лейблов на произвольном объекте:
apiVersion: templates.gatekeeper.sh/v1beta1
kind: ConstraintTemplate
metadata:
name: k8srequiredlabels
spec:
crd:
spec:
names:
kind: K8sRequiredLabels
listKind: K8sRequiredLabelsList
plural: k8srequiredlabels
singular: k8srequiredlabels
validation:
# Schema for the `parameters` field
openAPIV3Schema:
properties:
labels:
type: array
items: string
targets:
- target: admission.k8s.gatekeeper.sh
rego: |
package k8srequiredlabels
deny[{"msg": msg, "details": {"missing_labels": missing}}] {
provided:={label|input.review.object.metadata.labels[label]}
required := {label | label := input.parameters.labels[_]}
missing := required - provided
count(missing) > 0
msg := sprintf("you must provide labels: %v", [missing])
}
После развертывания шаблона ограничения в кластере на его основе можно создать ограничение для конкретных типов объектов.
Пример CRD-ограничения, которое требует, чтобы метка
hr
присутствовала во всех пространствах имен:apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sRequiredLabels
metadata:
name: ns-must-have-hr
spec:
match:
kinds:
- apiGroups: [""]
kinds: ["Namespace"]
parameters:
labels: ["hr"]
Пример CRD-ограничения, которое требует присутствия метки
finance
во всех пространствах имен:apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sRequiredLabels
metadata:
name: ns-must-have-finance
spec:
match:
kinds:
- apiGroups: [""]
kinds: ["Namespace"]
parameters:
labels: ["finance"]
Таким образом, ограничения позволяют:
- повторно использовать предварительно созданные шаблоны;
- определять область применения с помощью поля Match;
- предоставлять ограничениям параметры, выбранные пользователем, для настройки индивидуального поведения каждого ограничения.
Аудит
Аудит позволяет оценивать ресурсы в соответствии с принятыми в кластере ограничениями. Это помогает выявлять неправильные конфигурации, созданные ранее.
Gatekeeper хранит результаты аудита как
Violations
в поле Status
соответствующего ограничения.
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sRequiredLabels
metadata:
name: ns-must-have-hr
spec:
match:
kinds:
- apiGroups: [""]
kinds: ["Namespace"]
parameters:
labels: ["hr"]
status:
auditTimestamp: "2019-08-06T01:46:13Z"
byPod:
- enforced: true
id: gatekeeper-controller-manager-0
violations:
- enforcementAction: deny
kind: Namespace
message: 'you must provide labels: {"hr"}'
name: default
- enforcementAction: deny
kind: Namespace
message: 'you must provide labels: {"hr"}'
name: gatekeeper-system
- enforcementAction: deny
kind: Namespace
message: 'you must provide labels: {"hr"}'
name: kube-public
- enforcementAction: deny
kind: Namespace
message: 'you must provide labels: {"hr"}'
name: kube-system
Репликация данных
Перед оценкой ресурсов на соответствие политикам безопасности может потребоваться подгрузка данных из Kubernetes в Gatekeeper. Она нужна в тех случаях, когда недостаточно оцениваемых объектов и требуется информация по ресурсам из кластера. Например, ограничение, которое обеспечивает уникальность имени хоста входа, должно иметь доступ ко всем другим входам в кластере.
Для настройки репликации данных Kubernetes используют ресурс конфигурации синхронизации с реплицируемыми в OPA ресурсами.
Пример репликации всего пространства имен и ресурсов pod в OPA:
apiVersion: config.gatekeeper.sh/v1alpha1
kind: Config
metadata:
name: config
namespace: "gatekeeper-system"
spec:
sync:
syncOnly:
- group: ""
version: "v1"
kind: "Namespace"
- group: ""
version: "v1"
kind: "Pod"
После синхронизации данных с OPA правила могут получить доступ к кэшированным данным в документе data.inventory. Он имеет следующий формат:
- Для объектов с кластерной областью:
data.inventory.cluster[<groupVersion>][<kind>][<name>]
- Пример ссылки на пространство имен Gatekeeper:
data.inventory.cluster["v1"].Namespace["gatekeeper"]
- Для объектов, ограниченных пространством имен:
data.inventory.namespace[<namespace>][groupVersion][<kind>][<name>]
- Пример ссылки на модуль Gatekeeper:
data.inventory.namespace["gatekeeper"]["v1"]["Pod"]["gatekeeper-controller-manager-d4c98b788-j7d92"]
Зачем вам нужен Gatekeeper?
Зачастую политики безопасности для ресурсов Kubernetes разрабатывают с запасом — в них добавляют как обязательные, так и необязательные параметры. Это усложняет разработку и создает трудности, если ресурсы настраивают разные команды.
Gatekeeper помогает стандартизировать настройку всех ресурсов в кластере и автоматически блокировать создание или обновление тех из них, которые не соответствуют принятым политикам. С его помощью чаще всего проверяют:
-
Resource requests and limits (запросы на ограничения и лимиты). Применяют, когда важно, чтобы в каждом контейнере были указаны запросы и ограничения ресурсов. Например, это помогает исключить «проблему шумного соседа» — когда один контейнер чрезмерно потребляет ресурсы хоста и создает их дефицит на сервере.
-
Соответствия разрешенному пространству имен. Используют, если нужно разделить права доступа к ресурсу или кластеру для разных команд. Например, работать с ресурсами может только команда, использующая соответствующее пространство имен.
-
Ограничения на права входных ресурсов. Применяют, когда важно ограничить права входных ресурсов на обслуживание трафика. Например, если нужно применить стандарт в стратегии шлюза API, используя nginx-ingress, где только один входной ресурс может обрабатывать запросы
/api/${resource}
.
-
Ограничений на запуск от неразрешенных имен. Используют, когда важно ограничить запуск контейнеров от пользователя Root, если они не находятся в списке разрешений, определенном в политиках.
-
Готовность контейнеров. Например, если нужно, чтобы liveness-/readiness-пробы могли гарантировать, что трафик не достигнет контейнера, который не готов к нему, и что контейнеры перезапускаются, когда они переходят в невосстановимое состояние;
-
Ограничения на монтирование папок на под. Позволяют ограничить возможность подключения отдельных папок с хоста на под или наоборот — разрешить маунт только определенных папок. Актуально, если в кластере с общим доступом есть папки с конфиденциальной системной информацией.
Главное по теме: что нужно знать о Gatekeeper
- Gatekeeper обеспечивает интеграцию с OPA и Kubernetes.
- Инструмент встраивается между сервером API Kubernetes и OPA, принимает поступающие в кластер запросы и проверяет их на соответствие актуальным политикам безопасности.
- Решение позволяет настроить политики один раз и быть уверенным, что все создаваемые ресурсы в кластере им соответствуют.
- Gatekeeper незначительно влияет на производительность системы и практически не сказывается на скорости обработки запросов.
- Инструмент может работать с политиками безопасности, содержащими разные ограничения.
В Kubernetes от VK Cloud Solutions доступен Gatekeeper. Его можно протестировать — для этого новым пользователям при регистрации начисляем 3000 бонусных рублей. Будем рады, если вы попробуете и оставите обратную связь.
Комментарии (2)
r0binak
08.06.2022 20:27+2OPA конечно хорошо, но всё-таки более Kubernetes native будет Kyverno. Да и правила там писать куда проще.
turbotankist
"Opa" прикольная штука, мы её используем для некоторых валидаций, но как же взрывается мозг когда нужно написать какое-то сложное правило. Тратишь несколько часов если не знаешь синтаксис rego, вроде работает, вроде разобрался с синтаксисом. Но потом через 2 месяца нужно написать ещё одно правило и изучение начинается с нуля.
Может я просто полный ноль в функциональных языках.