Shell-operator и addon-operator Open Source-проекты компании Флант для администраторов Kubernetes, представленные в апреле 2019 года. Первый призван упростить создание K8s-операторов: для этого с ним достаточно писать простые скрипты (на Bash, Python и т.п.) или любые бинарники, которые будут вызываться в случае наступления определённых событий в Kubernetes API. Второй (addon-operator) его старший брат, цель которого упростить установку Helm-чартов в кластер, используя для их настройки хуки shell-operatorа.
В последний раз мы рассказывали о возможностях shell-operator по состоянию на релиз v1.0.0-beta.11 (летом прошлого года), если не считать последовавшего доклада на KubeCon EU2020, который знакомил с проектом тех, кто о нём ещё не знает. (К слову, этот доклад мы по-прежнему рекомендуем всем желающим разобраться, как shell-operator облегчает жизнь при создании операторов, и увидеть наглядные примеры его применения.)
За минувшее время и shell-operator, и addon-operator получили множество интересных новшеств, которым и посвящена эта статья.
Изменения в shell-operator v1.0.0-rc1
Хуки для shell-operator
теперь можно использовать как обработчики для
ValidatingWebhookConfiguration
одного из
вариантов
admission webhook. Т.е. хук может
проверить ресурс Kubernetes во время создания или редактирования и
отклонить операцию, если ресурс не соответствует каким-то правилам.
Таким правилом может быть такая политика: можно создавать только
ресурсы с образом из repo.example.com. Пример реализации подобной
политики можно посмотреть в директории
204-validating-webhook. Shell-operator поддерживает
такие хуки для кластеров Kubernetes с версией не ниже 1.16.
Иллюстрация того, как происходит конфигурация такого хука (фрагмент shell-хука из примера выше):
function __config__(){ cat <<EOFconfigVersion: v1kubernetesValidating:- 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"}
Это удобно, когда пропадают объекты, сведения о которых были в метриках. Подробный пример разобран в документации.
Остальные значимые нововведения в shell-operator разбиты на категории:
1. Улучшения в потреблении ресурсов и производительности
-
Период ресинхронизации информеров теперь случайно распределён во времени. Без распределения все информеры одновременно обращались к API-серверу, что периодически создавало лишнюю нагрузку.
-
Введена экспоненциально возрастающая задержка между повторными запусками ошибочного хука.
-
В операциях на чтение в очередях сделаны read-only-локи вместо общего лока и на запись, и на чтение.
-
Добавлены метрики с процессорным временем и с потреблением памяти для каждого хука (см.
shell_operator_hook_run_sys_cpu_seconds
в METRICS).
2. Изменения в сборке образа
-
Теперь
flant/shell-operator
это образ с поддержкой архитектур AMD64, ARM и ARM64 (привет любителям Raspberry Pi!). -
Бинарный файл
shell-operator
собирается статически и должен работать в любом Linux-дистрибутиве. -
Образ
flant/shell-operator
с Bash, kubectl и jq теперь только на основе Alpine. Если требуется другой дистрибутив, то бинарный файл можно взять из основного образа, а Dockerfile есть в примерах. -
Убрана директория
.git
, попавшая в образ по ошибке. -
Обновлены версии инструментов: Alpine 3.12, kubectl 1.19.4, Go 1.15.
-
Бинарный файл jq собран из того же коммита, что и libjq*, чтобы устранить проблемы производительности jq-1.6 (#206).
* Кстати, libjq-go это наш небольшой Open Source-проект, предлагающий CGO bindings для jq. Он был создан для нужд shell-operator, но недавно мы встретили и другой пример его использования в проекте Xbus. Это платформа французской компании для интеграции enterprise-систем, построенная поверх NATS. Здорово видеть, когда Open Source сам делает своё полезное дело даже в небольших проектах, от которых ничего особого не ожидаешь.
3. Менее значимые изменения
-
В лог при старте записываются предупреждения про файлы хуков без флага исполнения (+x).
-
Проект можно собирать без включения CGO. Теперь удобно использовать shell-operator в других проектах, если быстрый обработчик
jqFilter
не нужен. -
Добавлен
shell_lib.sh
, чтобы подключать shell framework одной строкой. Пример использования этой библиотеки мы демонстрировали в уже упомянутом докладе на KubeCon.
Новости addon-operator
Последний релиз addon-operator состоялся в начале прошлого года, с тех пор в нем было по-настоящему много изменений.
Одно из главных поддержка схем OpenAPI для values. Можно задавать контракты для values, которые нужны для Helm, и для config values, которые хранятся в ConfigMap и используются для конфигурации модулей пользователем.
Например, такая схема определяет два обязательных поля для
глобальных values (project
и
clusterName
), а также два опциональных поля (строка
clusterHostname
и объект discovery
без
ограничений по ключам):
# /global/openapi/config-values.yamltype: objectadditionalProperties: falserequired: - project - clusterNameminProperties: 2properties: project: type: string clusterName: type: string clusterHostname: type: string discovery: type: object
Подробнее см. в документации.
Ещё одно знаковое событие экспериментальная поддержка написания хуков на языке Go. Для их работы придётся компилировать свой addon-operator, добавив импорты с путями к хукам. Пример их использования можно найти в каталоге 700-go-hooks.
Иллюстрация глобального хука на Go из примера выше:
package global_hooksimport "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: v1onStartup: 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.
Среди других ключевых изменений в addon-operator выделим следующие:
-
Поддержка установки модулей с помощью Helm 3.
-
Введены понятия сходимости и сходимости при старте это название цикла рестарта всех модулей. Добавлен endpoint для readiness-пробы: Pod addon-operatorа переводится в состояние Ready, когда прошёл первый старт всех модулей, т.е. сходимость при старте достигнута.
-
Возможность включать модули из глобальных хуков, благодаря чему теперь проще регулировать состав модулей (ранее отключить модуль можно было только enabled-скриптом самого модуля).
-
Запуск информеров и запуск Synchronization для Kubernetes-хуков теперь производится в отдельных очередях, а также появилась возможность отключить ожидание выполнения таких хуков при старте.
-
Сборка образа изменена аналогично shell-operatorу: Alpine в качестве основы, мультиплатформенный образ, статический бинарный файл и т.д.
-
Доступно больше метрик для мониторинга состояния подробнее в METRICS.
Также в addon-operator перекочевали многие улучшения из shell-operator, была актуализирована документация и сделаны другие мелкие правки. В данный момент заканчиваются работы по поддержке схем OpenAPI, после чего будет опубликован релиз v1.0.0-rc1.
Новые применения shell-operator
За минувшее время shell-operator обрёл не только новые возможности, но и новых пользователей. Среди них отметим следующие известные нам проекты:
-
В Confluent сделали проект Kafka DevOps. В нём реализована модель production-окружения, в котором запущено streaming-приложение, пишущее в Apache Kafka на Confluent Cloud. Это окружение построено на основе Kubernetes, приложения и ресурсы в котором управляются в духе декларативной инфраструктуры. В частности, для этого реализованы операторы (Confluent Cloud Operator и Kafka Connect Operator) на основе на shell-operator. Подробнее об этом проекте можно почитать в блоге авторов, а совсем недавно они даже выпустили подкаст, где рассказывают о своём Kafka DevOps.
-
Образовательный проект edukates подготовил практическое занятие по shell-operator, однако его дальнейшая судьба осталась для нас под вопросом (найти его в опубликованном виде на сайте проекта нам не удалось).
-
Docker Captain из Германии создал специальный контроллер для обновления DNS-записей при рестарте podа с Traefik. Вскоре после этого он узнал про shell-operator и перевел свою разработку на его использование.
-
Solution Architect из Red Hat занялся созданием r53-operator оператора для кастомных доменов, который управляет доменами Ingress в AWS Route 53.
Если у вас тоже есть опыт применения shell-operator, будем рады соответствующим рассказам в GitHub Discussions проекта: собирая такие примеры, мы надеемся помочь широкому сообществу инженеров. Случаи использования addon-operator гораздо более редкое явление, так что им мы будем рады вдвойне.
Заключение
Shell-operator и addon-operator давно используются нами в ежедневной работе. Основные проблемы изучены и устранены, а сейчас в проекты преимущественно добавляются новые возможности. В ближайших планах для shell-operator поддержка conversion webhook и возможность писать хуки без побочных эффектов, т.е. не вызывать kubectl для изменений в кластере, а возвращать в shell-operator набор действий (см. #94, #239).
Фактически оба проекта давно вышли из статуса beta, поэтому мы решили синхронизироваться с реальностью и представляем их версии rc1, а следующий релиз shell-operator в этом году может стать окончательным v1.0.0.
P.S. В ноябре прошлого года shell-operator преодолел рубеж в 1000 звёзд на GitHub, а addon-operator более скромные 250. Спасибо всем, кто заинтересовался проектами!
P.P.S.
Читайте также в нашем блоге:
-
Go? Bash! Встречайте shell-operator (обзор и видео доклада с KubeCon EU'2020);
-
Простое создание Kubernetes-операторов с shell-operator: прогресс проекта за год;
-
Готовить Kubernetes-кластер просто и удобно? Анонсируем addon-operator;
-
Представляем shell-operator: создавать операторы для Kubernetes стало ещё проще;