Раскрытие возможностей Kubernetes 1.26 с помощью новой функции ValidatingAdmissionPolicy

Раскрытие возможностей Kubernetes 1.26 с помощью новой функции ValidatingAdmissionPolicy

11 января 2023 г.

Команда Kubernetes выпустила последнюю версию, k8s 1.26, несколько дней назад, и она содержит несколько очень интересных новых функций. Одно из них, которое бросается в глаза, — это CEL для управления доступом. Он позволяет нам создать ValidatingAdmissionPolicy, поднимая безопасность нашего кластера на новый уровень.

<цитата>

Проверка политик допуска представляет собой декларативную внутрипроцессную альтернативу проверке веб-перехватчиков допуска.

Проверка политик допуска использует Common Expression Language (CEL) для объявления правил проверки политики.

Что такое CEL?

<цитата>

Общий язык выражений (CEL) реализует общую семантику для оценки выражений, упрощая взаимодействие различных приложений. https://github.com/google/cel-spec

Это язык программирования, используемый в Kubernetes для создания пользовательских политик контроля доступа. Он позволяет создавать сложные, детализированные политики для обеспечения безопасности и соответствия требованиям в кластере.

В предыдущей статье мы рассмотрели, как можно использовать контроллеры допуска Kubernetes для принудительной проверки, например как предотвращение использования последнего тега для образов контейнеров. В этом посте мы углубимся в новую функцию ValidatingAdmissionPolicy, которая позволяет нам расширить наши возможности проверки еще более простым способом, не прибегая к веб-перехватчикам!

Локальное тестирование K8s 1.26

Для локального тестирования можно использовать такие инструменты, как kind или microk8s.

Прежде чем использовать kind или microk8s, обязательно включите функцию ValidatingAdmissionPolicy и admissionregistration.k8s.io/ v1alpha1 API.

microk8s — https://microk8s.io#
microk8s install --channel 1.26

Вам потребуется отредактировать файл kube-apiserver, расположенный по адресу, указанному во фрагменте ниже, чтобы активировать необходимые функции.

$ vim /var/snap/microk8s/current/args/kube-apiserver

...
--feature-gates=ValidatingAdmissionPolicy=true
--runtime-config=admissionregistration.k8s.io/v1alpha1=true
...

Если вы используете Mac и у вас установлен microk8, он использует многопроходную в качестве виртуальной машины. Чтобы получить доступ к виртуальной машине, выполните следующую команду:

$ multipass list
Name                    State             IPv4             Image
microk8s-vm             Running           192.168.64.5     Ubuntu 18.04 LTS

$ multipass shell microk8s-vm

вид - https://kind.sigs.k8s.io#

При желании вы можете создать кластер, используя файл конфигурации, написанный на языке YAML, который содержит все необходимые настройки.

kind: Cluster
name: demo-cel
apiVersion: kind.x-k8s.io/v1alpha4
featureGates:
  "ValidatingAdmissionPolicy": true
runtimeConfig:
  "admissionregistration.k8s.io/v1alpha1": true
nodes:
- role: control-plane
  image: kindest/node:v1.26.0

Выполнить

$ kind create cluster --config=cluster.yaml

Как для kind, так и для microk8s вы можете использовать kubectl, чтобы проверить, включены ли все необходимые функции.

$ kubectl api-versions | grep admissionregistration

admissionregistration.k8s.io/v1alpha1

$ kubectl api-resources | grep ValidatingAdmissionPolicy

validatingadmissionpolicies                      admissionregistration.k8s.io/v1alpha1   false        ValidatingAdmissionPolicy
validatingadmissionpolicybindings                admissionregistration.k8s.io/v1alpha1   false        ValidatingAdmissionPolicyBinding

Теперь, когда вы настроили свой кластер, вы готовы начать экспериментировать с ValidatingAdmissionPolicy.

Воспроизведение

Чтобы создать политику, необходимо создать следующее:

  1. Политика ValidatingAdmissionPolicy, описывающая абстрактную логику политики (например, «эта политика гарантирует, что для определенного ярлыка установлено определенное значение»).
  2. И привязку ValidatingAdmissionPolicyBinding, которая связывает ValidatingAdmissionPolicy с определенной областью или контекстом."

Допустим, вы хотите создать политику, которая обеспечивает высокую доступность в производственных развертываниях, требуя как минимум 3 реплики. Эту политику можно реализовать с помощью следующих ресурсов ValidatingAdmissionPolicy и ValidatingAdmissionPolicyBinding:

apiVersion: admissionregistration.k8s.io/v1alpha1
kind: ValidatingAdmissionPolicy
metadata:
  name: "force-ha-in-prod"
spec:
  failurePolicy: Fail
  matchConstraints:
    resourceRules:
    - apiGroups:   ["apps"]
      apiVersions: ["v1"]
      operations:  ["CREATE", "UPDATE"]
      resources:   ["deployments"]
  validations:
    - expression: "object.spec.replicas >= 3"
      message: "All production deployments should be HA with at least three replicas"

В приведенном выше YAML показано, как вы можете указать, какие ресурсы и операции будут затронуты политикой. В разделе spect.validations вы можете использовать CEL для определения выражений, которым должен удовлетворять ресурс, чтобы он был принят политикой. Если выражение оценивается как false, проверка выполняется в соответствии с полем spec.failurePolicy.

Согласно официальной документации Kubernetes, выражения CEL могут обращаться содержание запросов и ответов на вход через ряд переменных:

  • object: объект из входящего запроса (null для запросов DELETE).
  • oldObject: существующий объект (нулевой для запросов CREATE).
  • запрос: атрибуты запроса на допуск.
  • params: ресурс параметра, на который ссылается оцениваемая привязка политики (пусто, если параметр ParamKind не установлен).

Теперь, когда у вас есть первая политика, вам нужно связать ее с помощью ValidatingAdmissionPolicyBinding:

apiVersion: admissionregistration.k8s.io/v1alpha1
kind: ValidatingAdmissionPolicyBinding
metadata:
  name: "force-ha-in-prod-binding"
spec:
  policyName: "force-ha-in-prod"
  matchResources:
    namespaceSelector:
      matchLabels:
        env: production

MatchResources решает, следует ли запускать политику управления доступом для объекта, основываясь на том, соответствует ли он критериям соответствия. В этом случае вы используете namespaceSelector, чтобы применить политику ко всем пространствам имен, помеченным env: production.

Возможно, вы захотите использовать objectSelector, который решает, следует ли запускать проверку, основываясь на том, есть ли у объекта совпадающие метки. Он оценивается как по старой, так и по новой версии объекта, что позволяет настроить проверки, гарантирующие, что ресурсы не будут изменены определенным образом.

apiVersion: admissionregistration.k8s.io/v1alpha1
kind: ValidatingAdmissionPolicyBinding
metadata:
  name: "force-ha-in-prod-object-binding"
spec:
  policyName: "force-ha-in-prod"
  matchResources:
    objectSelector:
      matchLabels:
        from: kungfudev

Конечно, вы также можете использовать пустой LabelSelector, который будет соответствовать всем объектам. Это может быть полезно, если вы хотите, чтобы ваша политика применялась ко всем ресурсам, независимо от их меток.

apiVersion: admissionregistration.k8s.io/v1alpha1
kind: ValidatingAdmissionPolicyBinding
metadata:
  name: "force-ha-in-prod-for-all-binding"
spec:
  policyName: "force-ha-in-prod"
  matchResources:

Чтобы протестировать политику, вы можете попробовать применить следующий YAML, который включает пространство имен и развертывание только с двумя репликами.

apiVersion: v1
kind: Namespace
metadata:
  name: payments-system
  labels:
    env: production
---
apiVersion: apps/v1
kind: Deployment
metadata:
  namespace: payments-system
  name: payment-gateway
  labels:
    app: nginx
    from: kungfudev
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.23.3
        ports:
        - containerPort: 80

Тестирование:

$ kubectl apply -f force-ha-in-prod.yaml
validatingadmissionpolicy.admissionregistration.k8s.io/force-ha-in-prod created

$ kubectl apply -f force-ha-in-prod-binding.yaml
validatingadmissionpolicybinding.admissionregistration.k8s.io/force-ha-in-prod-binding created

$ kubectl apply -f payment-deployment.yaml
The deployments "payment-gateway" is invalid: : ValidatingAdmissionPolicy 'force-ha-in-prod' with binding 'force-ha-in-prod-binding' denied request: All production deployments should be HA with at least three replicas

Политика отклоняет развертывание, поскольку оно не соответствует требованиям, определенным при проверке политики. Однако если вы измените развертывание, чтобы использовать 4 реплики вместо 2, политика должна разрешить это.

...
spec:
  replicas: 4
  selector:
    matchLabels:
...


$ kubectl apply -f payment-deployment.yaml
deployment.apps/payment-gateway created

Вау, мы только что сделали все наши производственные развертывания высокодоступными с помощью нескольких простых действий! Наша политика на данный момент довольно проста, но это не мешает нам создавать более сложные проверки. Представьте, что вы не разрешаете тег «последний», разрешаете только изображения из нашего собственного реестра или убедитесь, что для всех контейнеров установлены ограничения ЦП. Возможности безграничны благодаря силе ValidatingAdmissionPolicy в наших руках!

Используя все возможности CEL, мы можем объединить несколько выражений для создания более сложных проверок.

Чтобы узнать о дополнительных функциях и возможностях, предлагаемых CEL, перейдите по этой ссылке.

apiVersion: admissionregistration.k8s.io/v1alpha1
kind: ValidatingAdmissionPolicy
metadata:
  name: "prod-ready-policy"
spec:
  failurePolicy: Fail
  matchConstraints:
    resourceRules:
    - apiGroups:   ["apps"]
      apiVersions: ["v1"]
      operations:  ["CREATE", "UPDATE"]
      resources:   ["deployments"]
  validations:
    - expression: "object.spec.template.spec.containers.all(c, !c.image.endsWith(':latest'))"
      message: "cannot use the latest tag"
    - expression: "object.spec.template.spec.containers.all(c, c.image.startsWith('myregistry.com/'))"
      message: "image from an untrusted registry"
    - expression: "has(object.metadata.labels.env) && object.metadata.labels.env in ['prod', 'production']"
      message: "deployment should have an env and have to be prod or production"
    - expression: |
        object.spec.template.spec.containers.all(
          c, has(c.resources) && has(c.resources.limits) && has(c.resources.limits.cpu)
        )        
      message: "container does not have a cpu limit set"
---
apiVersion: admissionregistration.k8s.io/v1alpha1
kind: ValidatingAdmissionPolicyBinding
metadata:
  name: "prod-reay-policy-binding"
spec:
  policyName: "prod-reay-policy"
  matchResources:
    namespaceSelector:
      matchExpressions:
      - key: "env"
        operator: "In"
        values: [prod, production,]

В приведенном выше YAML вы заметите, что мы можем использовать matchExpressions во время привязки, чтобы придать нашей политике более динамичную область действия.

Функция ValidatingAdmissionPolicy также включает ресурсы параметров, которые позволяют отделить конфигурацию политики от ее определения. Это означает, что, например, вместо того, чтобы жестко задавать минимальное количество реплик для всех пространств имен в политике высокой доступности, вы можете использовать параметр и настроить разные значения для разных сред. Ознакомьтесь с официальной документацией, чтобы используйте эту функцию.

В заключение

Благодаря CEL и новой функции ValidatingAdmissionPolicy в k8s 1.26 у нас теперь есть возможность создавать собственные сложные политики для обеспечения безопасности и соответствия требованиям в наших кластерах.

Мы знаем, что агент Open Policy Agent (OPA) широко используется, но ValidatingAdmissionPolicy + CEL спроектирован так, чтобы быть более легким и простым в использовании, чем OPA. ValidatingAdmissionPolicy изначально интегрирован с Kubernetes, что означает, что его можно использовать непосредственно на сервере API Kubernetes, не требуя отдельного механизма политик.

Существуют плюсы и минусы использования OPA или ValidatingAdmissionPolicy + CEL для применения политик в Kubernetes. OPA мог бы быть более многофункциональным и мощным механизмом политик, но он может потребовать дополнительной настройки и обслуживания. ValidatingAdmissionPolicy + CEL проще в использовании и лучше интегрируется с Kubernetes, но может не иметь всех расширенных функций OPA. В конечном счете, выбор механизма политик будет зависеть от конкретных требований и предпочтений пользователя.

Найдите все файлы YAML и другие примеры в этом репозитории.

Спасибо за внимание, и я надеюсь, что вы нашли эту статью полезной и легкой для понимания. Удачного создания кластера!

:::информация Также опубликовано здесь.

:::


Оригинал
PREVIOUS ARTICLE
NEXT ARTICLE