Шаблонизируй это

Насколько я понимаю в Гугле 200M+ строчек кода написано на Borgcfg/GCL. Нечто похожее, но может быть в меньших масштабах происходит в любой крупной компании.

Архитекторы Borg и K8s что управление конфигурациями это одна из ключевых проблем.

Из всех проблем, с которыми мы сталкивались, наибольшее количество умственных усилий, чернил и кода было потрачено на управление конфигурациями — набором значений, предоставляемых приложениям, а не жестко встроенных в них. По правде говоря, мы могли бы посвятить этой теме всю статью и всё равно не исчерпать её. Ниже приведены несколько ключевых моментов.
Во-первых, конфигурация приложения становится универсальным местом для реализации всего, что (пока) не делает система управления контейнерами. За всю историю Borg это включало:

• Сокращение шаблонного кода (например, установка политик перезапуска задач по умолчанию, подходящих для типа нагрузки, такой как сервисные или пакетные задания).
• Настройка и проверка параметров приложения и флагов командной строки.
• Реализация обходных решений для отсутствующих API-абстракций, таких как управление пакетами (образами).
• Библиотеки шаблонов конфигураций для приложений.
• Инструменты управления выпусками.
• Указание версий образов

Запомнили все требования, которые предъявляли архитекторы k8s к инструментам управления конфигурациями? Ни один инструмент ее до сих пор до конца так и не решил.

Jsonnet, Dhall, Cue,   Helm, ytt & kapp, kustomize — вот лишь не полный список языков и инструментов которые призваны были решить эти задачи. Список этот продолжает расширятся, но все равное медленнее чем гигабайты YAML генерируемые Kubernetes.

Хотя на самом деле эта проблема была решена 40 лет назад Unix хакерами из Bell Labs.

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

Давайте посмотрим как можно использовать GNU make для работы с манифестами k8s.

Структура

https://github.com/avkcode/vault

В данном случае мы рассматриваем работу с Hashicrop Vault — потому что один их ключевых компонентов инфраструктуры, но при этом ничего специфичного для Vault здесь нет.

Dockerfile		README.md		docker-compose.yml	keys.json
LICENSE			unseal.py
Makefile		dev.param		global.param

В корне репозитория Makefile в котором описаны и манифесты и основные операции для работы с образами и развертыванием приложения Kubernetes. Документация тоже встроена в Makefile. В каком-то смысле это и есть «Грамотное программирование» по Кнуту.

Если запустить make без аргументов то появится help:

Available targets:
  template          - Generate Kubernetes manifests from templates
  apply             - Apply generated manifests to the Kubernetes cluster
  delete            - Delete Kubernetes resources defined in the manifests
  validate-%        - Validate a specific manifest using yq, e.g. make validate-rbac
  print-%           - Print the value of a specific variable
  get-vault-ui      - Fetch the Vault UI Node IP and NodePort
  build-vault-image - Build the Vault Docker image
  exec              - Execute a shell in the vault pod
  logs              - Stream logs from the vault pod
  switch-namespace  - Switch the current Kubernetes namespace
  archive           - Create a git archive
  bundle            - Create a git bundle
  clean             - Clean up generated files
  release           - Create a Git tag and release on GitHub
  get-vault-keys    - Initialize Vault and retrieve unseal and root keys
  show-params       - Show contents of the parameter file for the current environment
  interactive       - Start an interactive session
  create-release    - Create a Kubernetes secret with VERSION set to Git commit SHA
  remove-release    - Remove the dynamically created Kubernetes secret
  dump-manifests    - Dump manifests in both YAML and JSON formats to the current directory
  convert-to-json   - Convert manifests to JSON format
  validate-server   - Validate JSON manifests against the Kubernetes API (server-side)
  validate-client   - Validate JSON manifests against the Kubernetes API (client-side)
  list-vars         - List all non-built-in variables, their origins, and values.
  package           - Create a tar.gz archive of the entire directory
  help              - Display this help message

Открываем makefile.

Создаем мультистроковые переменные с помощью define:

define
define

Создаем массив строк:

array
array

С помощью функции foreach проходим по массиву строк:

foreach
foreach

Мы можем обработать массив так как нам необходимо или сохранить манифесты kubernetes на диск:

манифесты
манифесты

Parameters

В файлах *.param задаются переменные для разных окружений

params
params

Мы можем ограничить файлы с параметрами которые могут быть использованы прямо в коде:

params
params

Validation

С помощью встроенных в k8s возможностей валидируем манифесты.

validation
validation

Команда validate-% проверяет отдельные манифесты (в данном случае мультистроковые переменные) на наличие ошибок с помощью утилиты yq/jq:

validate
validate

Проверяем configmap:

configmap
configmap

Constraints

Гибкость make позволяет нам проверять значения параметров «in situ». В данном случае мы проверяем что значение MEMORY_REQUEST находится в пределах допустимых значений.

constraints
constraints

Release

Ни что не останавливает нас от того, чтобы реализовать такой же функционал:

release
release

В отличии от Helm мы ни чем не ограничены и можем вместо номера релиза использовать например GIT_COMMIT, а сохранять эти данные можно в любое внешнее хранилище, к примеру в Clickhouse.

PS.

  • Для небольших организаций, когда из интернета выкачиваются готовые операторы K8s например Strimzi и Helm чарты из Bitnami. И потом это с небольшими правками разворачивается на прод, то что я показал может быть слишком сложным.

  • Данные метод работы с манифестами скорее предназначен для организаций с сотнями и тысячами команд, где есть особые требования к безопасности (istio).

  • Данный пример был призван показать насколько просто заменить тот же Helm используя лишь стандартный инструментарий Unix. Это говорит о том, что назрела необходимость создания средств автоматизации «умнее» чем Helm.

© Habrahabr.ru