Applying OPA Gatekeeper
Last updated
Last updated
https://habr.com/ru/companies/slurm/articles/688268/
Представим, что мы маленькая компания. Мы хотим перенести рабочие нагрузки в Kubernetes, но нас очень волнует вопрос безопасности. Мы уже создали кластеры, опираясь на рекомендации по безопасности из официальной документации Kubernetes. Бизнес растёт, и нам нужно что-то изменить, чтобы защитить среду Kubernetes и в то же время управлять действиями конечных пользователей в кластере. Мы используем встроенные возможности Kubernetes, вроде управления доступом на основе ролей (RBAC), политик безопасности pod’ов, политик сети, управления secret’ами и т. д.
В какой-то момент мы понимаем, что нам нужны более детальные настройки. Например, мы хотим запретить развёртывание pod’ов, если образ поступает из ненадёжного реестра. Встроенных функций нам уже не хватает, и мы начинаем обдумывать собственные политики, удовлетворяющие нашим требованиям.
Допустим, мы сформулировали политики. Как теперь легко и быстро применить их в среде Kubernetes?
В статье мы ответим на этот вопрос.
OPA Gatekeeper — это контроллер политики для Kubernetes. Если точнее — настраиваемый вебхук для доступа (admission webhook) в Kubernetes, который помогает применять политики и поддерживает систему управления и контроля. OPA перед Gatekeeper расшифровывается как Open Policy Agent, потому что это их проект (Github).
Что такое OPA? Мы уже разобрались, что это Open Policy Agent, но что он делает? Это инструмент общего назначения для работы с политиками. Его можно применять с авторизацией API, SSH, Docker и т. д. В OPA политики пишутся на специальном языке Rego и обычно сохраняются как файлы *.rego
.
OPA можно использовать где угодно, а вот OPA Gatekeeper создан специально для контроля доступа в Kubernetes.
Больше об OPA читайте в вводном обзоре Open Policy Agent.
https://kubernetes.io/blog/2019/08/06/opa-gatekeeper-policy-and-governance-for-kubernetes/
Этот проект создан специально под Kubernetes и помогает организациям быстро и без лишних проволочек применять политики и рекомендации по безопасности в средах Kubernetes.
Зачем организациям вообще нужны политики?
В двух словах, политики определяют, что пользователи могут делать в кластере.
Это зависит от потребностей организации или юридических требований.
Например, мы можем определить в своей среде следующие политики:
Загружать образы можно только из одобренных репозиториев.
Для всех pod’ов нужно установить лимиты по ресурсам.
Pod’ы нельзя запускать от имени root
Pod’ы не могут содержать привилегированный контейнер.
С помощью Gatekeeper мы можем применять политики для защиты и оптимизации без лишних хлопот, используя кастомные определения ресурсов и Rego.
Здесь можно узнать, чем Gatekeeper отличается от OPA.
Как вообще работает Gatekeeper?
В Kubernetes есть так называемые динамические контроллеры доступа (Dynamic Admission Controllers) — вебхуки (обратные вызовы HTTP), которые перехватывают запросы до их сохранения в etcd. Gatekeeper работает как проверяющий вебхук доступа (validating admission webhook) поверх движка OPA. Gatekeeper описывает и применяет политику с помощью OPA Constraint Framework. Когда мы динамически настраиваем политики OPA с помощью кастомных определений ресурсов (Custom Resource Definition, CRD), Gatekeeper затем опирается на эти политики, чтобы отклонять или принимать запросы.
https://kubernetes.io/blog/2019/03/21/a-guide-to-kubernetes-admission-controllers/
В Gatekeeper политики определяются в виде ограничений. Ограничения мы пишем на Rego, но сначала нужно создать шаблон ограничения, с помощью которого мы объявим само ограничение. Шаблон описывает логику Rego и схему ограничения.
По сути, ограничение — это CRD, создаваемое из шаблона. То есть Gatekeeper будет создавать новое CRD для описания каждой определяемой политики.
Шаблон ограничения можно сравнить с функцией, а ограничение — с вызовом функции.
Прежде чем перейти к практической части, давайте скажем пару слов о Rego.
Rego — это очень простой и хорошо задокументированный язык, на котором мы пишем политики в шаблонах ограничений. Прочтите документацию по Rego, чтобы понять, как использовать политики Rego в шаблонах. Там все очень просто. Затем приступайте к практической части.
Определим простейший шаблон ограничения.
k8srequiredlabels-constrainttemplate.yaml
Как видите, мы пишем политики Rego в разделе .targets в шаблоне. Это первое, что мы должны сделать, чтобы подготовить само ограничение. Обратите внимание, что для ресурса указан тип (kind) ConstraintTemplate, а это CRD входит в установку Gatekeeper. Где же ограничение? Посмотрите на поле .spec.crd.spec.names.kind в шаблоне. K8sRequiredLabels и есть наше ограничение. Не существует CRD с именем Constraint (как для ConstraintTemplate). Ограничение само по себе представляет собой CRD, которое мы создадим из шаблона. В данном случае это K8SRequiredLabels. Мы также видим, что ограничение ждёт входных данных, потому что мы должны указать обязательные метки. Эти входные данные обозначены в политике Rego как input.parameters.
Давайте рассмотрим конкретный пример. Мы установим Gatekeeper на локальный кластер minikube с помощью Helm. Потом мы попытаемся запретить в кластере привилегированные контейнеры. Там будет один фокус. Вместо команды eval $(minikube docker-env) мы используем контекст Docker, чтобы получить доступ к Docker-демону на виртуальной машине Minikube. В этой документации можно узнать больше о контексте Docker.
Запустим локальный кластер Kubernetes с помощью minikube.
minikube-start.png
Настроим контекст Docker, чтобы использовать Docker-демон на виртуальной машине Minikube.
docker-context.png
Установить OPA Gatekeeper можно разными способами. Мы, например, используем Helm. Полный список способов установки см. в этой документации.
helm-gatekeeper.png
Этот чарт совместим с Helm 3 начиная с Gatekeeper 3.1.1. При использовании Helm 3 мы видим предупреждения о хуке crd-install
. Это связано с обратной совместимостью с Helm 2 и не повлияет на развёртывание чарта.https://github.com/open-policy-agent/gatekeeper#deploying-via-helm
Какие CRD были созданы при установке Gatekeeper? Как видите, у нас нет CRD с именем Constraint, зато есть CRD с именем ConstraintTemplate.
Давайте определим шаблон ограничения, чтобы запретить привилегированные контейнеры в кластере.
privileged-constrainttemplate.yaml
Здесь мы определяем ограничение PriviligedContainer. В этом ограничении будет использоваться политика Rego, которая определена в разделе .targets в шаблоне ограничения. Если мы применим этот манифест YAML, будет создано CRD с именем PrivilegedContainer.
privileged-container-crd.png
Как определить ограничение PriviligedContainer в кластере? Давайте посмотрим. Здесь важно отметить, что ограничение нужно применить явно, иначе запрет на привилегированные контейнеры не начнёт действовать.
priviliged-container-constraint.yaml
Мы указали, что хотим перехватывать запросы pod’ов и применять к ним политику. Давайте применим ограничение и протестируем его.
apply-privileged-constraint.png
Проверим, что получилось. Сначала мы создадим обычный pod, и тут проблем возникнуть не должно. Затем мы возьмём pod с привилегированным контейнером, и на этот раз запрос должен быть отклонён.
apply-privileged-pod.png
Как видите, все работает. Мы применили манифест YAML, и теперь в кластере запрещены привилегированные контейнеры. Кстати, политики не обязательно писать самим — есть официальная библиотека с большим набором вариантов. Убедитесь сами.
OPA Gatekeeper — это полезный инструмент, с помощью которого можно легко описывать и определять политики в кластерах Kubernetes. Это правда очень удобно. Здесь мы рассмотрели не все возможности OPA Gatekeeper. Там ещё много интересного, честное слово.
БОНУС. Существует ещё один проект — Kyverno. В чём-то он похож на OPA Gatekeeper, но может менять или создавать ресурсы, а для написания политик не использует Rego.