- PVSM.RU - https://www.pvsm.ru -

Прогресс shell-operator и addon-operator: хуки как admission webhooks, Helm 3, OpenAPI, хуки на Go и многое другое

Прогресс shell-operator и addon-operator: хуки как admission webhooks, Helm 3, OpenAPI, хуки на Go и многое другое - 1

Shell-operator [1] и addon-operator [2] — Open Source-проекты компании «Флант» для администраторов Kubernetes, представленные в апреле 2019 года. Первый призван упростить создание K8s-операторов: для этого с ним достаточно писать простые скрипты (на Bash, Python и т.п.) или любые бинарники, которые будут вызываться в случае наступления определённых событий в Kubernetes API. Второй (addon-operator) — его «старший брат», цель которого — упростить установку Helm-чартов в кластер, используя для их настройки хуки shell-operator’а.

В последний раз мы рассказывали [3] о возможностях shell-operator по состоянию на релиз v1.0.0-beta.11 (летом прошлого года), если не считать последовавшего доклада на KubeCon EU’2020 [4], который знакомил с проектом тех, кто о нём ещё не знает. (К слову, этот доклад мы по-прежнему рекомендуем всем желающим разобраться, как shell-operator облегчает жизнь при создании операторов, и увидеть наглядные примеры его применения.)

За минувшее время и shell-operator, и addon-operator получили множество интересных новшеств, которым и посвящена эта статья.

Изменения в shell-operator v1.0.0-rc1

Прогресс shell-operator и addon-operator: хуки как admission webhooks, Helm 3, OpenAPI, хуки на Go и многое другое - 2

Хуки для shell-operator [1] теперь можно использовать как обработчики для ValidatingWebhookConfigurationодного из вариантов admission webhook [5]. Т.е. хук может проверить ресурс Kubernetes во время создания или редактирования и отклонить операцию, если ресурс не соответствует каким-то правилам. Таким правилом может быть такая политика: «можно создавать только ресурсы с образом из repo.example.com». Пример реализации подобной политики можно посмотреть в директории 204-validating-webhook [6]. Shell-operator поддерживает такие хуки для кластеров Kubernetes с версией не ниже 1.16.

Иллюстрация того, как происходит конфигурация такого хука (фрагмент shell-хука [7] из примера выше):

function __config__(){
    cat <<EOF
configVersion: v1
kubernetesValidating:
- name: private-repo-policy.example.com
  namespace:
    labelSelector:
      matchLabels:
        # helm adds a 'name' label to a namespace it creates
        name: example-204
  rules:
  - apiGroups:   ["stable.example.com"]
    apiVersions: ["v1"]
    operations:  ["CREATE", "UPDATE"]
    resources:   ["crontabs"]
    scope:       "Namespaced"
EOF
}

Другое новшество — группу произвольных метрик теперь можно удалить, вернув ключ action:

{"group":"group_name_1", "action":"expire"}

Это удобно, когда пропадают объекты, сведения о которых были в метриках. Подробный пример разобран в документации [8].

Остальные значимые нововведения в shell-operator разбиты на категории:

1. Улучшения в потреблении ресурсов и производительности

  • Период ресинхронизации информеров теперь случайно распределён во времени. Без распределения все информеры одновременно обращались к API-серверу, что периодически создавало лишнюю нагрузку.

    Прогресс shell-operator и addon-operator: хуки как admission webhooks, Helm 3, OpenAPI, хуки на Go и многое другое - 3
  • Введена экспоненциально возрастающая задержка между повторными запусками ошибочного хука.

  • В операциях на чтение в очередях сделаны read-only-локи вместо общего лока и на запись, и на чтение.

  • Добавлены метрики с процессорным временем и с потреблением памяти для каждого хука (см. shell_operator_hook_run_sys_cpu_seconds в METRICS [9]).

2. Изменения в сборке образа

  • Теперь flant/shell-operator — это образ с поддержкой архитектур AMD64, ARM и ARM64 (привет любителям Raspberry Pi [10]!).

  • Бинарный файл shell-operator собирается статически и должен работать в любом Linux-дистрибутиве.

  • Образ flant/shell-operator с Bash, kubectl и jq теперь только на основе Alpine. Если требуется другой дистрибутив, то бинарный файл можно взять из основного образа, а Dockerfile есть в примерах [11].

  • Убрана директория .git, попавшая в образ по ошибке.

  • Обновлены версии инструментов: Alpine 3.12, kubectl 1.19.4, Go 1.15.

  • Бинарный файл jq собран из того же коммита, что и libjq*, чтобы устранить проблемы производительности jq-1.6 (#206 [12]).

* Кстати, libjq-go [13] — это наш небольшой Open Source-проект, предлагающий CGO bindings для jq. Он был создан для нужд shell-operator, но недавно мы встретили и другой пример его использования — в проекте Xbus [14]. Это платформа французской компании для интеграции enterprise-систем, построенная поверх NATS. Здорово видеть, когда Open Source сам делает своё полезное дело даже в небольших проектах, от которых ничего особого не ожидаешь.

3. Менее значимые изменения

  • В лог при старте записываются предупреждения про файлы хуков без флага исполнения (+x).

  • Проект можно собирать без включения CGO. Теперь удобно использовать shell-operator в других проектах, если быстрый обработчик jqFilter не нужен.

  • Добавлен shell_lib.sh, чтобы подключать shell framework одной строкой. Пример использования этой библиотеки мы демонстрировали в уже упомянутом докладе на KubeCon [4].

Новости addon-operator

Прогресс shell-operator и addon-operator: хуки как admission webhooks, Helm 3, OpenAPI, хуки на Go и многое другое - 4

Последний релиз addon-operator [2] состоялся в начале прошлого года, с тех пор в нем было по-настоящему много изменений.

Одно из главных — поддержка схем OpenAPI для values. Можно задавать контракты для values, которые нужны для Helm, и для config values, которые хранятся в ConfigMap и используются для конфигурации модулей пользователем.

Например, такая схема определяет два обязательных поля для глобальных values (project и clusterName), а также два опциональных поля (строка clusterHostname и объект discovery без ограничений по ключам):

# /global/openapi/config-values.yaml

type: object
additionalProperties: false
required:
  - project
  - clusterName
minProperties: 2
properties:
  project:
    type: string
  clusterName:
    type: string
  clusterHostname:
    type: string
  discovery:
    type: object

Подробнее — см. в документации [15].

Ещё одно знаковое событие — экспериментальная поддержка написания хуков на языке Go. Для их работы придётся компилировать свой addon-operator, добавив импорты с путями к хукам. Пример их использования можно найти в каталоге 700-go-hooks [16].

Иллюстрация глобального хука на Go из примера выше:

package global_hooks

import "github.com/flant/addon-operator/sdk"

var _ = sdk.Register(&GoHook{})

type GoHook struct {
	sdk.CommonGoHook
}

func (h *GoHook) Metadata() sdk.HookMetadata {
	return h.CommonMetadataFromRuntime()
}

func (h *GoHook) Config() *sdk.HookConfig {
	return h.CommonGoHook.Config(&sdk.HookConfig{
		YamlConfig: `
configVersion: v1
onStartup: 10
`,
		MainHandler: h.Main,
	})
}

func (h *GoHook) Main(input *sdk.BindingInput) (*sdk.BindingOutput, error) {
	input.LogEntry.Infof("Start Global Go hook")
	return nil, nil
}

Реализация соответствующего SDK пока находится на уровне альфа-версии и не может похвастать достаточной документацией, но если вас заинтересовала такая возможность — смело спрашивайте в комментариях, а лучше — приходите в Tg-канал @kubeoperator [17].

Среди других ключевых изменений в addon-operator выделим следующие:

  • Поддержка установки модулей с помощью Helm 3.

  • Введены понятия «сходимости» и «сходимости при старте» — это название цикла рестарта всех модулей. Добавлен endpoint для readiness-пробы: Pod addon-operator’а переводится в состояние Ready, когда прошёл первый старт всех модулей, т.е. «сходимость при старте» достигнута.

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

  • Запуск информеров и запуск Synchronization для Kubernetes-хуков теперь производится в отдельных очередях, а также появилась возможность отключить ожидание выполнения таких хуков при старте.

  • Сборка образа изменена аналогично shell-operator’у: Alpine в качестве основы, мультиплатформенный образ, статический бинарный файл и т.д.

  • Доступно больше метрик для мониторинга состояния — подробнее в METRICS [18].

Также в addon-operator перекочевали многие улучшения из shell-operator, была актуализирована документация и сделаны другие мелкие правки. В данный момент заканчиваются работы по поддержке схем OpenAPI, после чего будет опубликован релиз v1.0.0-rc1.

Новые применения shell-operator

За минувшее время shell-operator обрёл не только новые возможности, но и новых пользователей. Среди них отметим следующие известные нам проекты:

  • В Confluent сделали проект Kafka DevOps [19]. В нём реализована «модель production-окружения, в котором запущено streaming-приложение, пишущее в Apache Kafka на Confluent Cloud». Это окружение построено на основе Kubernetes, приложения и ресурсы в котором управляются в духе декларативной инфраструктуры. В частности, для этого реализованы операторы (Confluent Cloud Operator и Kafka Connect Operator) на основе на shell-operator. Подробнее об этом проекте можно почитать в блоге авторов [20], а совсем недавно они даже выпустили подкаст [21], где рассказывают о своём Kafka DevOps.

  • Образовательный проект edukates [22] подготовил практическое занятие по shell-operator [23], однако его дальнейшая судьба осталась для нас под вопросом (найти его в опубликованном виде на сайте проекта нам не удалось).

  • Docker Captain из Германии создал специальный контроллер [24] для обновления DNS-записей при рестарте pod’а с Traefik. Вскоре после этого он узнал про shell-operator и перевел свою разработку [25] на его использование.

  • Solution Architect из Red Hat занялся созданием r53-operator [26] — «оператора для кастомных доменов», который управляет доменами Ingress в AWS Route 53.

Если у вас тоже есть опыт применения shell-operator, будем рады соответствующим рассказам в GitHub Discussions проекта [27]: собирая такие примеры, мы надеемся помочь широкому сообществу инженеров. Случаи использования addon-operator — гораздо более редкое явление, так что им мы будем рады [28] вдвойне.

Заключение

Shell-operator и addon-operator давно используются нами в ежедневной работе. Основные проблемы изучены и устранены, а сейчас в проекты преимущественно добавляются новые возможности. В ближайших планах для shell-operator — поддержка conversion webhook [29] и возможность писать хуки «без побочных эффектов», т.е. не вызывать kubectl для изменений в кластере, а возвращать в shell-operator набор действий (см. #94 [30], #239 [31]).

Фактически оба проекта давно вышли из статуса beta, поэтому мы решили синхронизироваться с реальностью и представляем их версии rc1, а следующий релиз shell-operator в этом году может стать окончательным v1.0.0.

P.S. В ноябре прошлого года shell-operator преодолел рубеж в 1000 звёзд на GitHub [32], а addon-operator — более скромные 250 [33]. Спасибо всем, кто заинтересовался проектами!

P.P.S.

Читайте также в нашем блоге:

Автор: Иван Михейкин

Источник [37]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/open-source/360773

Ссылки в тексте:

[1] Shell-operator: https://github.com/flant/shell-operator

[2] addon-operator: https://github.com/flant/addon-operator

[3] рассказывали: https://habr.com/ru/company/flant/blog/509896/

[4] доклада на KubeCon EU’2020: https://habr.com/ru/company/flant/blog/519208/

[5] admission webhook: https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/

[6] 204-validating-webhook: https://github.com/flant/shell-operator/tree/master/examples/204-validating-webhook

[7] shell-хука: https://github.com/flant/shell-operator/blob/master/examples/204-validating-webhook/hooks/validating.sh

[8] документации: https://github.com/flant/shell-operator/blob/master/METRICS.md#example

[9] METRICS: https://github.com/flant/shell-operator/blob/master/METRICS.md

[10] любителям Raspberry Pi: https://habr.com/ru/company/flant/blog/513908/

[11] есть в примерах: https://github.com/flant/shell-operator/blob/master/examples/202-repack-build/

[12] #206: https://github.com/flant/shell-operator/issues/206

[13] libjq-go: https://github.com/flant/libjq-go

[14] Xbus: https://orus.io/xbus/xbus

[15] документации: https://github.com/flant/addon-operator/blob/master/VALUES.md#validation

[16] 700-go-hooks: https://github.com/flant/addon-operator/tree/master/examples/700-go-hook

[17] Tg-канал @kubeoperator: https://t.me/kubeoperator

[18] METRICS: https://github.com/flant/addon-operator/blob/master/METRICS.md

[19] Kafka DevOps: https://github.com/confluentinc/kafka-devops

[20] блоге авторов: https://www.confluent.io/blog/kafka-devops-with-confluent-kubernetes-and-gitops/

[21] выпустили подкаст: https://developer.confluent.io/podcast/mastering-devops-with-apache-kafka-kubernetes-and-confluent-cloud-ft-rick-spurgeon-and-allison-walther

[22] edukates: https://docs.edukates.io/en/latest/

[23] практическое занятие по shell-operator: https://github.com/eduk8s-tests/lab-shell-operator

[24] специальный контроллер: https://dille.name/blog/2020/09/26/writing-a-kubernetes-controller-to-handle-dns-for-traefik/

[25] свою разработку: https://github.com/nicholasdille/traefik-dns

[26] r53-operator: https://github.com/sjbylo/r53-operator

[27] GitHub Discussions проекта: https://github.com/flant/shell-operator/discussions/categories/show-and-tell

[28] будем рады: https://github.com/flant/addon-operator/discussions

[29] conversion webhook: https://github.com/flant/shell-operator/issues/41

[30] #94: https://github.com/flant/shell-operator/issues/94

[31] #239: https://github.com/flant/shell-operator/pull/239

[32] 1000 звёзд на GitHub: https://github.com/flant/shell-operator/stargazers

[33] более скромные 250: https://github.com/flant/addon-operator/stargazers

[34] Готовить Kubernetes-кластер просто и удобно? Анонсируем addon-operator: https://habr.com/ru/company/flant/blog/455543/

[35] Расширяем и дополняем Kubernetes (обзор и видео доклада): https://habr.com/ru/company/flant/blog/449096/

[36] Представляем shell-operator: создавать операторы для Kubernetes стало ещё проще: https://habr.com/ru/company/flant/blog/447442/

[37] Источник: https://habr.com/ru/post/537794/?utm_source=habrahabr&utm_medium=rss&utm_campaign=537794