[Перевод] Политика как код на Kubernetes вместе с Kyverno

92255d74fa5395c497f902b6fee9c45c.png

Kubernetes смог произвести революцию в облачной экосистеме, позволив людям запускать распределенные приложения на масштабе. Хотя Kubernetes — это многофункциональная и надежная платформа для оркестрации контейнеров, она имеет свои собственные сложности. Управлять Kubernetes в таком масштабе, когда над ним работают сразу несколько команд, непросто. Трудно контролировать правильность действий пользователей и их возможный выход за рамки допустимого.

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

Как работает Kyverno?

Kyverno работает на основе dymanic admission controller, который проверяет каждый запрос, который вы отправляете через kubectl на сервер Kube API. Если запрос соответствует политике, Kyverno пропускает его. В противном случае он отклоняет запрос с определенным сообщением.

Это позволяет Kyverno осуществлять такие функции, как:

  • Проверку ограничений CPU и памяти.

  • Контроль за тем, чтобы пользователи не меняли сетевые политики, установленные по умолчанию.

  • Проверку, соответствует ли имя ресурса определенному шаблону.

  • Обеспечение того, чтобы определенные ресурсы всегда содержали соответствующую метку.

  • Запрет удалений и изменений для определенных ресурсов.

  • Автоматическое изменение imagePullPolicy на Always, если тег изображения latest.

  • Создание сетевой политики по умолчанию для каждого нового namespace.

Kyverno использует CRD (пользовательские определения ресурсов) для определения политик, поэтому написание политик настолько просто, как их применение с помощью kubectl.

Есть три основные функции, предоставляемые Kyverno:

  • проверка (validation)

  • изменение (mutation)

  • генерация (generation)

Давайте взглянем на некоторые примеры манифестов для каждой из них.

Проверка

Прекрасным примером использования является обеспечение того, чтобы все поды имели установленные значения для requests/limits. Следующий пример прекрасно объясняет это:

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: check-resources
spec:
  validationFailureAction: enforce
  rules:
    - name: check-pod-resources
      match:
        resources:
          kinds:
            - Pod
      validate:
        message: "CPU and memory resource requests and limits are required"
        pattern:
          spec:
            containers:
              - name: "*"
                resources:
                  limits:
                    memory: "?*"
                    cpu: "?*"
                  requests:
                    memory: "?*"
                    cpu: "?*"

Хотя большая часть примера сама себя документирует и объясняет, давайте разберем параметр validationFailureAction Он указывает, следует ли соблюдать это требование (с помощью enforce) или следует только проверить его (с помощью audit) и сообщить о нарушениях.

Изменение (mutation)

Mutation означает изменение ресурсов, если они соответствуют определенному шаблону. Отличным примером этого яцвляется изменение imagePullPolicy на Always, если тег образа контейнера latest.

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: image-pull-policy-always
spec:
  rules:
    - name: image-pull-policy-latest
      match:
        resources:
          kinds:
            - Pod
      mutate:
        overlay:
          spec:
            containers:
              - (image): "*:latest"
                imagePullPolicy: "Always"

Генерация (generation)

Генерирование, как следует из названия, генерирует (создает) ресурс для определенного события. Например, если кто-то создает новый namespace, мы можем захотеть применить сетевую политику по умолчанию.

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: "default"
spec:
  rules:
  - name: "default-deny"
    match:
      resources: 
        kinds:
        - Namespace
        name: "*"
    exclude:
      namespaces:
        - "kube-system"
        - "default"
        - "kube-public"
        - "kyverno"
    generate: 
      kind: NetworkPolicy
      name: default-deny-all-traffic
      namespace: "{{request.object.metadata.namespace}}" 
      data:  
        spec:
          podSelector: {}
          policyTypes: 
          - Ingress
          - Egress

Переходим к практике

Теперь давайте перейдем к практике и посмотрим на Kyverno в работе. Мы установим Kyverno, а затем применим политику валидации для осуществления проверки наличия определенной метки. Если метка не существует, Kyverno отклонит запрос. В противном случае он будет одобрен.

Предпосылки

Для начала работы нам нужен функциональный кластер Kubernetes.

Устанавливаем Kyverno

Установка Kyverno проста. Вы можете либо применить манифест Kyverno Kubernetes, доступный на GitHub, либо установить последнюю версию helm chart.

Применение манифеста

kubectl create -f 
https://raw.githubusercontent.com/kyverno/kyverno/master/definitions/
release/install.yaml

Использование Helm chart

helm repo add kyverno https://kyverno.github.io/kyverno/
kubectl create ns kyverno
helm install kyverno --namespace kyverno kyverno/kyverno

Чтобы проверить, успешно ли мы установили Kyverno, перечислите все ресурсы в namespace kyverno:

# kubectl get all -n kyverno
NAME                           READY   STATUS    RESTARTS   AGE
pod/kyverno-5f7769d697-x8lkj   0/1     Running   0          21s
NAME                  TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)   AGE
service/kyverno-svc   ClusterIP   10.96.167.8           443/TCP   21s
NAME                      READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/kyverno   0/1     1            0           21s
NAME                                 DESIRED   CURRENT   READY   AGE
replicaset.apps/kyverno-5f7769d697   1         1         0       21s

Применение политик

Теперь мы подошли к вопросу о политике. Давайте применим политику, которая гарантирует, что все поды должны содержать метку (label) с именем app. Создайте файл с именем require-app-label.yaml с приведенным ниже содержанием:

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: require-app-label
spec:
  validationFailureAction: enforce
  rules:
  - name: check-for-app-label
    match:
      resources:
        kinds:
        - Pod
    validate:
      message: "label `app` is required"
      pattern:
        metadata:
          labels:
            app: "?*"

Если вы посмотрите на YAML, мы увидим, что там есть раздел match, который содержит типы ресурсов, которые мы должны сопоставить. В этом примеры мы видим сущность типа Pod. Секция validate определяет сообщение, которое мы должны вывести, если проверка завершится неудачей, и шаблон, объясняющий, что нам нужно сопоставить.

f449cea7bee6c9593cc3473b842f652d.jpg

Загляните под капот Kubernetes. Учить на практическом курсе по подписке в удобное время.

Поскольку это пользовательский ресурс kubernetes, мы можем применить его напрямую и получить желаемый результат:

kubectl apply -f require-app-label.yaml

Проверка

Итак, пришло время для небольшого тестирования! Давайте создадим pod без метки (label) и посмотрим, что у нас получится:

kubectl run nginx --image=nginx

3af931bff066ec545d7c4e7f0981b197.gif

Итак, как мы видим, проверка завершилась неудачей по причине, указанной ниже:

Error from server: admission webhook "nirmata.kyverno.resource.validating-webhook" denied the request:
resource Deployment/default/nginx was blocked due to the following policies
require-app-label:
  autogen-check-for-app-label: 'Validation error: label `app` is required; Validation rule autogen-check-for-app-label failed at path /spec/template/metadata/labels/app/'

Здесь всё работает, как и ожидалось, поскольку мы еще не предоставили метку (label). Теперь давайте попробуем с меткой name=nginx:

kubectl run nginx --image=nginx --labels="name=nginx" --generator=run-pod/v1

86adabc91b8adcb680c772fc281e3e7d.gif

Этот запуск тоже терпит неудачу, так как метка (label) приложения по-прежнему отсутствует. Давайте создадим под NGINX с меткой  app=nginx:

kubectl run nginx --image=nginx --labels="app=nginx" --generator=run-pod/v1

0671d090c3fea0afce4859845937a6f0.gif

Как мы можем видеть, под был создан успешно. Теперь давайте используем kubectl для получения пода и меток:

kubectl get pod nginx --show-labels

9e7cea26f7c3c54087da0f803f56188f.gif

Под запущен и содержит метку app=nginx.

Заключение

Kyverno — это отличный инструмент policy-as-code, который очень эффективен в применении лучших практик на уровне компании. Поскольку он является родным для Kubernetes, он прост в написании и эксплуатации и не требует обслуживания специализированными разработчиками.

Заглянуть под капот Kubernetes

Всех, кто уже работал с Kubernetes и хочет углубить свои знания, мы приглашаем на курс «Kubernetes: Мега».

На курсе мы рассмотрим авторизацию в кластере, автоскейлинг, резервное копирование и другие вещи, касающиеся продвинутой эксплуатации кластера. Вас ждут 13 онлайн-встреч со спикерами по 1–1,5 часа, более 6 часов практики на стендах, групповой чат с куратором и итоговая сертификация. Что еще будет:  

  • создадим отказоустойчивый кластер в ручном режиме;

  • авторизация в кластере;

  • настройка autoscaling;

  • резервное копирование;  

  • Stateful приложения в кластере;

  • интеграция Kubernets и Vault для хранения секретов;

  • HorizontalPodAutoscaler;

  • ротация сертификатов в кластере;

  • Blue-Green Deploy и Canary Deploy;

  • настройка Service mesh.

Для кого курс

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

Мы сделали курс для администраторов кластеров и баз данных, DevOps«ов, специалистов по безопасности, архитекторов и инфраструктурных разработчиков, которые давно работают с k8s, хотят глубже понять тонкости и научиться реализовывать сложные сценарии.

Профит от изучения Kubernetes

Главный результат познания Kubernetes — уменьшается time-to-market продукта. Это важно, потому что обычно ожидание становится критичным для команды эксплуатации, пока продукт непрерывно улучшают. С K8s можно быстро поднять себе в stage-кластере инфраструктуру, протестироваться на ней, поэкспериментировать и что-то выкатить. 

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

По подписке дешевле

Мы в тестовом режиме запустили подписку, в которую входят 20 курсов Слёрм. За 50 000 рублей вы можете пройти интересные вам программы из списка в течение трех месяцев.

Стоимость видеокурса «Kubernetes: Мега» без подписки — 70 000 рублей, а с подпиской вы получите гораздо больше знаний на 20 000 дешевле. Оформите подписку до 21 марта и успейте собрать все сливки.

Узнать подробности и записаться.

© Habrahabr.ru