Kubernetes — это мощный инструмент, который помогает нам эффективно и надежно управлять и развертывать наше программное обеспечение. Однако по мере того как наши системы становятся все более сложными, может возникнуть проблема с обеспечением их безопасности и соответствия правилам и нормам. Именно здесь на помощь приходит Open Policy Agent (OPA). Перевели туториал, где рассматривается, как OPA можно использовать в Kubernetes для обеспечения безопасности наших систем и соблюдения политик.

Что такое OPA?

Прежде чем погрузиться в изучение OPA в Kubernetes, стоит рассмотреть, что такое OPA и как он работает. OPA — это механизм политики, который оценивает политики во время выполнения. Он обеспечивает централизованный способ управления политиками, которые могут применяться в различных приложениях и средах. OPA использует язык политик под названием Rego, который позволяет разработчикам писать политики как в человекочитаемом, так и в машиноисполняемом виде. После написания политик они хранятся в центральном хранилище политик, доступ к которому может получить механизм OPA.

Как OPA работает с Kubernetes

OPA имеет встроенную интеграцию с Kubernetes, что позволяет легко развернуть и использовать OPA в среде Kubernetes. Существует несколько способов интеграции OPA с Kubernetes:

OPA с Gatekeeper

Одним из самых популярных способов является Gatekeeper. OPA Gatekeeper — это validating admission controller Kubernetes, который применяет политики к объектам Kubernetes при их создании или изменении. Когда пользователь или процесс пытается создать или изменить объект Kubernetes, OPA Gatekeeper перехватывает запрос и проверяет его на соответствие политикам, определенным в OPA. Если запрос нарушает политику, он отклоняется.

OPA gatekeeper и Kubernetes
OPA gatekeeper и Kubernetes

OPA с Service Mesh

Еще один способ использования OPA с Kubernetes — это использование Service Mesh, например Istio или Envoy. Service Mesh помогают нам управлять трафиком между различными сервисами, и мы можем использовать OPA для обеспечения безопасности этого трафика и соблюдения наших политик. Например, мы можем использовать OPA для блокировки трафика к сервису, который не имеет правильной авторизации, или для шифрования трафика между сервисами.

В этой статье рассмотрим пошаговую установку Gatekeeper.

Обзор OPA Gatekeeper

Как мы уже упоминали ранее, OPA Gatekeeper — это validating admission controller, который будет вызываться через веб-хук Kubernetes. Validating admission контроллеры используются для проверки того, разрешен ли ресурс Kubernetes набором правил или политик, прежде чем он будет создан или обновлен в реальной системе.

Установка OPA Gatekeeper

Для установки OPA gatekeeper требуется разрешение Cluster Admin. Поэтому необходимо создать роль и привязку ролей, чтобы предоставить доступ OPA gatekeeper ко всем ресурсам в Kubernetes.

Есть много способов установить OPA gatekeeper, мы можем использовать команду Helm следующим образом. Базовый Helm chart можно найти в charts/gatekeeper. Если у вас установлен Helm, вы можете развернуть его с помощью следующих инструкций для Helm v3.

$ helm repo add gatekeeper https://open-policy-agent.github.io/gatekeeper/charts --force-update
"gatekeeper" has been added to your repositories

После выполнения вышеуказанной команды вы можете увидеть результаты развертывания, как показано ниже.

helm install gatekeeper/gatekeeper --name-template=gatekeeper --namespace gatekeeper-system --create-namespace
NAME: gatekeeper
LAST DEPLOYED: Wed Mar 22 09:21:54 2023
NAMESPACE: gatekeeper-system
STATUS: deployed
REVISION: 1
TEST SUITE: None

Компоненты привратника OPA установлены в пространстве имен gatekeeper-system. Выполнив следующую команду, можно просмотреть информацию об установленных ресурсах.

$ kubectl -n gatekeeper-system get all                                                                       
NAME                                                 READY   STATUS    RESTARTS      AGE
pod/gatekeeper-audit-549bcc6775-z74gm                1/1     Running   1 (92s ago)   100s
pod/gatekeeper-controller-manager-7785cd6b4c-j64zv   1/1     Running   0             100s
pod/gatekeeper-controller-manager-7785cd6b4c-mcfv5   1/1     Running   0             100s
pod/gatekeeper-controller-manager-7785cd6b4c-xr9kt   1/1     Running   0             100s

NAME                                 TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
service/gatekeeper-webhook-service   ClusterIP   10.96.120.252   <none>        443/TCP   100s

NAME                                            READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/gatekeeper-audit                1/1     1            1           100s
deployment.apps/gatekeeper-controller-manager   3/3     3            3           100s

NAME                                                       DESIRED   CURRENT   READY   AGE
replicaset.apps/gatekeeper-audit-549bcc6775                1         1         1       100s
replicaset.apps/gatekeeper-controller-manager-7785cd6b4c   3         3         3       100s

OPA Gatekeeper Constraint Template

Ресурс ConstraintTemplate — это, по сути, шаблон для генерации ресурсов Constraint, которые являются фактическими объектами Kubernetes, обеспечивающими соблюдение политик, определенных в ConstraintTemplate. Ресурс ConstraintTemplate определяет код Rego, который будет использоваться для оценки объектов Kubernetes на соответствие набору политик, определенных в ConstraintTemplate.

Давайте создадим шаблон ConstraintTemplate, который будет блокировать все запросы на развертывание, в которых отсутствует наш частный реестр private.example.com

$ cat <<EOF | kubectl apply -f -
apiVersion: templates.gatekeeper.sh/v1beta1
kind: ConstraintTemplate
metadata:
  name: k8sallowedrepos
spec:
  crd:
    spec:
      names:
        kind: K8sAllowedRepos
      validation:
        # Schema for the `parameters` field
        openAPIV3Schema:
          properties:
            repos:
              type: array
              items:
                type: string
  targets:
    - target: admission.k8s.gatekeeper.sh
      rego: |
        package k8sallowedrepos

        violation[{"msg": msg}] {
          container := input.review.object.spec.containers[_]
          satisfied := [good | repo = input.parameters.repos[_] ; good = contains(container.image, repo)]
          not any(satisfied)
          msg := sprintf("container <%v> has an invalid image repo <%v>, allowed repos are %v", [container.name, container.image, input.parameters.repos])
        }

        violation[{"msg": msg}] {
          container := input.review.object.spec.initContainers[_]
          satisfied := [good | repo = input.parameters.repos[_] ; good = contains(container.image, repo)]
          not any(satisfied)
          msg := sprintf("container <%v> has an invalid image repo <%v>, allowed repos are %v", [container.name, container.image, input.parameters.repos])
        }
EOF

$ constrainttemplate.templates.gatekeeper.sh/k8sallowedrepos created

Если вы внимательно посмотрите, мы проверяем правильность имен образов репо в контейнерах regular & initContainer в полезной нагрузке запроса развертывания k8s.

package k8sallowedrepos

violation[{"msg": msg}] {
  container := input.review.object.spec.containers[_]
  satisfied := [good | repo = input.parameters.repos[_] ; good = contains(container.image, repo)]
  not any(satisfied)
  msg := sprintf("container <%v> has an invalid image repo <%v>, allowed repos are %v", [container.name, container.image, input.parameters.repos])
}

violation[{"msg": msg}] {
  container := input.review.object.spec.initContainers[_]
  satisfied := [good | repo = input.parameters.repos[_] ; good = contains(container.image, repo)]
  not any(satisfied)
  msg := sprintf("container <%v> has an invalid image repo <%v>, allowed repos are %v", [container.name, container.image, input.parameters.repos])
}

Ограничение OPA Gatekeeper

Ограничения можно рассматривать как шаблоны для объектов Kubernetes, которые обеспечивают соблюдение определенного набора политик. Каждое ограничение состоит из двух основных частей: spec и parameters. spec определяет набор политик, которые вы хотите применить к объектам Kubernetes, а раздел parameters позволяет передавать переменные, которые могут быть использованы в spec.

Мы создадим следующее ограничение (K8sAllowedRepos), чтобы сообщить Gatekeeper, что администратор хочет, чтобы вышеуказанный ConstraintTemplate применялся, и Gatekeeper будет применять и следить за тем, чтобы в системе Kubernetes были развернуты только допустимые репозитории образов.

$ cat <<EOF | kubectl apply -f -
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sAllowedRepos
metadata:
  name: allow-only-private-registry
spec:
  match:
    kinds:
      - apiGroups: [""]
        kinds: ["Pod"]
  parameters:
    repos:
      - "private.example.com"
EOF

$ K8sAllowedRepos.constraints.gatekeeper.sh/allow-only-private-registry created

ПРИМЕЧАНИЕ: Нужно изменить private.example.com на имя нашего собственного Image registry host. Кроме того, в списке может быть более одного реестра.

Теперь давайте проверим, работает ли ограничение так, как ожидалось. Сначала развернем под, который использует репозиторий private.example.com  для образа, удовлетворяющего ограничениям.

$ cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
  name: allowed-image-pod
spec:
  containers:
    - name: allowed-image-pod
      image: private.example.com/sample-api:tagname
      resources:
        limits:
          cpu: "100m"
          memory: "30Mi"
EOF          

pod/allowed-image-pod created

Под развернут, поэтому Gatekeeper не отказал нам в развертывании.

Теперь давайте создадим другое развертывание, которое не будет использовать наш разрешенный образ.

$ cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
  name: deny-image-pod
spec:
  containers:
    - name: deny-image-pod
      image: docker.io/library/nginx:latest
      resources:
        limits:
          cpu: "100m"
          memory: "30Mi"
EOF          

Error from server (Forbidden): error when creating "STDIN": admission webhook "validation.gatekeeper.sh" denied the request: [allow-only-private-registry] container <deny-image-pod> has an invalid image repo <docker.io/library/nginx:latest>, allowed repos are ["private.example.com"]

Gatekeeper отклонил наши запросы на развертывание запрещенных образов.

Вот так мы можем создать множество политик с помощью Gatekeeper, чтобы обеспечить безопасность нашей системы Kubernetes.

Библиотека политик OPA Gatekeeper

OPA Gatekeeper Policy Library — это коллекция предварительно созданных политик, которые вы можете использовать с OPA Gatekeeper. Библиотека включает в себя политики для внедрения лучших практик безопасности, требований соответствия, квот на ресурсы и многое другое. Вы можете использовать эти политики как есть или настроить их под свои нужды.

Библиотека включает в себя набор каталогов, каждый из которых содержит набор политик, ориентированных на определенную область, например безопасность или соответствие нормативным требованиям. Каждая политика определяется в виде файла Rego, а каталог также содержит файл README с дополнительной информацией о политиках.

Заключение

Kubernetes — это мощный инструмент, который помогает нам управлять и развертывать программное обеспечение, но обеспечить безопасность и соответствие систем требованиям может быть непросто. Open Policy Agent (OPA) предоставляет мощное решение для внедрения политик и обеспечения безопасности наших систем. Используя OPA с Kubernetes, мы можем упростить применение политик, повысить безопасность и обеспечить соответствие нормативным требованиям.

Изучи Open Policy Agent (OPA) в Kubernetes в Слёрме за 10 000 ₽

Мы подробно изучаем Open Policy Agent в одном из модулей продвинутого курса Kubernetes: Мега. Теперь можно купить этот модуль отдельно за 10 000 ₽. Оформить его можно в самом конце этого лендинга.

В полной версии курса мы подробно разбираем ещё Network Policy, безопасность и высокодоступные приложения, ротацию сертификатов, аутентификацию пользователей в кластере, хранение секретов, Horisontal Pod Autoscaler, создание собственного оператора K8s, в общем, залезаем под капот Kubernetes. ???? Полная программа.

Комментарии (0)