Kapitan за штурвалом Kubernetes

Автор оригинала: Alessandro De Maria
  • Перевод


Знакомьтесь — Kapitan. Он поможет вам навести красоту и порядок в конфигурации Kubernetes.


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


На kubernetes.slack.com #kapitan успел собрать небольшое, но преданное сообщество (присоединяйтесь!), поэтому мы гордимся своей работой :)


Многие до сих пор считают, что Kapitan — это смесь jsonnet и jinja, но они упускают суть.
В этом посте я расскажу, как Kapitan управляет деплоями Kubernetes, но вообще-то он способен не только на это. Это важно: Kapitan универсален и не зациклен на одном Kubernetes. Kubernetes — это просто один из множества вариантов использования.


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


Что мне не нравилось


Я начал экспериментировать с Kubernetes в 2015 и сразу влюбился.
Правда, есть несколько недостатков, с которыми я не хочу мириться:


  • Контекст. Как по мне, это одна из самых сложных для понимания концепций Kubernetes — и одна из самых опасных. Контекст относится к клиенту, в нем трудно разобраться, он путано называется и создает неразбериху при запуске команд kubectl. Терпеть не могу контексты в kubectl!
  • Многословная вложенная конфигурация (yaml!). Пришлось попотеть, чтобы разобраться в каждом уровне конфигурации yaml в манифесте. Какой смысл повторять ярлыки по два–три раза в нескольких местах?
  • Бардак с императивными и декларативными командами. Новичков в Kubernetes побуждают учить императивные команды, хотя понятно же, что нормальные люди их не используют. По-моему, так только сложнее вписать Kubernetes в правильную стратегию деплоя для своей компании. Спойлер: нет никакой единой «правильной стратегии».
  • Конфигурация рантайма. Прав Джесси Суэнь (Jesse Suen), когда советует не передавать параметры конфигурации в командную строку helm (или kubectl и иже с ними). С параметрами одна и та же команда может каждый раз выполняться по-разному.
  • Конфигурация приложения. Мы научились управлять манифестами yaml в Kubernetes, мы молодцы. Вот только под и деплой — это пустая посудина. На ней еще должно плыть приложение со всей своей конфигурацией.
  • Разработчики хотят праздника, а рабочий процесс в Kubernetes до сих пор какой-то невнятный. Фанаты Kubernetes заставляют всех прямо там и девелопить. А надо ли? Послушаемся Келси Хайтауэра (Kelsey Hightower)!
  • Операторы. К ним у меня смешанные чувства, так что пока оставим эту тему :) Скажу только, что ими часто злоупотребляют.
  • Идемпотентность. Вернее, ее отсутствие. Если сложить все недостатки выше, мы получаем недостаточно идемпотентные рабочие процессы, что печально для Kubernetes.

Что делать?


Я пытался решить эти проблемы и собрал маленькую систему шаблонизации, которая использовала j2cli и пару bash-скриптов, чтобы управлять конфигурациями Kubernetes.


Система засовывала все в файл environmentA.yaml и использовала его в шаблоне Jinja2. Деплоить приложения в стиле микросервисов из нескольких компонентов можно было простой командой:


bin/apply.sh environments/environmentA.yaml

Круто! В yaml было все о деплое. Очень удобно, ведь я мог использовать тот же файл как источник информации для чего-нибудь другого. Скажем, для… bash-скриптов!


Я додумался, как импортировать в скрипты значения из yaml, чтобы выполнять подобные команды:


bin/create_kafka_topics.sh environments/environmentA.yaml

А потом все разом вышло из-под контроля:


  • Я ничего не мог поделать со структурой в файле yaml. Получалась мешанина из одинаковых полей, значений, спутанной конфигурации.
  • Никогда не узнаешь, как поведет себя деплой в среде, пока не попробуешь. Часто это было связано с изменениями в шаблонах jinja2 из-за нового значения инвентаря (допустим, feature_X), который не работал в средах, где эта функция не определена.
  • Такая же беда со скриптами: не попробуешь — не узнаешь.
  • Иногда Kubernetes менялся так быстро, что меня доставало постоянно менять манифесты под разные версии, особенно возиться с аннотациями к значениям.
  • Внешний фактор: команда разработчиков перешла с файлов конфигурации на параметры командной строки. Такое мелкое изменение спутало нам все карты, и пришлось задуматься о новом решении.
  • Самое главное: шаблонизация yaml с Jinja (или шаблонами Go) — это НЕ ВЕСЕЛО! У нас тогда была загадка: «Что выглядит, как текст, читается, как текст, пахнет, как текст, но не текст?». Или, как метко выразился Ли Бриггз (Lee Briggs): «Какого рожна мы шаблонизируем yaml?»

Kapitan: становление


Мы собрали весь свой горький опыт и вместе с Рикардо Амаро (Ricardo Amaro) стали фантазировать об идеальной системе управления конфигурацией. Тогда у нас еще не было четкой картинки, но мы знали, что любим и что не любим.


Любим:


  • Git.
  • Шаблонизацию в общем: данные/значения отдельно от шаблонов.
  • Отдельные значения для разных аспектов (приложение, Kubernetes, рантайм...).
  • Объектно-ориентированный подход.
  • Упрощенный yaml как интерфейс, куда спрятать сложности Kubernetes.
  • Четкое понимание, что творится и зачем.
  • Повторное использование значений в разных компонентах.
  • А еще у скриптов должен быть доступ к значениям.

Не любим:


  • Контексты kubectl.
  • Движки текстовых шаблонов для создания yaml.
  • Подсчет отступов: {{ toYaml .Values.resources | indent 10 }}.
  • Магию: все должно быть четко и ясно. Никаких фокусов.
  • Ручное управление паролями и секретами приложения.
  • Подход Tiller: мы хотели контролировать применение манифестов.
  • Подход git-crypt: секреты на диске не зашифрованы.
  • Конвейер шаблонов прямо в kubectl.
  • Передачу параметров командной строки.

И тогда случилось две вещи:


  1. Мы открыли для себя jsonnet Дейва Каннингема (Dave Cunningham) для шаблонизации yaml/json на объектно-ориентированном языке.
  2. Густаво Буриола (Gustavo Buriola) показал нам reclass, и без него мы бы далеко не уехали.

Рикардо Амаро взялся за работу, и скоро вся команда засела за Kapitan — одни работали над основным функционалом, другие — над его использованием в наших внутренних проектах. Управление секретами, поддержка gpg\kms, пользовательские функции: теперь Kapitan — это полноценный продукт, который делает больше, чем обещал.


Кто такой Kapitan?


Kapitan пытается решить все (ну или почти все) проблемы, о которых я говорил.


С технической точки зрения Kapitan очень прост:


  • Инвентарь: иерархическая коллекция значений, описывающих деплой, на базе yaml. На основе reclass. Как Hiera.
  • Шаблонизаторы: сейчас это Jinja2, Jsonnet, Kadet. Они берут инвентарь и создают файлы (yaml, json, документация или bash-скрипты).
  • Секреты: шаблонизируйте секреты, и Kapitan ими займется.

Мы вовсю используем jsonnet для шаблонизации манифестов и Jinja — для всего остального.


Иногда люди жалуются, что файл jsonnet совсем не похож на такой же yaml, поэтому им сложно перейти на jsonnet.

Мы попытались решить эту проблему с помощью Kadet, обернув yaml в Python. Возьмите за основу свой любимый yaml и прибавьте к нему Python.

Считайте, что это экзоскелет Python для yaml! Как-нибудь расскажу об этом.

В рабочем процессе Kapitan сразу показывает характер:


  • Свобода выбора: мы не навязываем никакие рабочие процессы и технологии, но обычно работаем по описанным ниже принципам. Вообще-то Kapitan можно использовать как угодно. Вы не обязаны использовать git, не должны компилировать в нем файлы и даже можете обойтись без jsonnet! Делайте что хотите.
  • GitOps до мозга костей: все в git, все в master-ветке, которая отражает наш замысел.
  • Декларативность: Kapitan приветствует компиляцию шаблонов манифестов в конкретных представлениях. И вы компилируете свои скрипты.
  • Контролируемый контекст: мы используем скомпилированные скрипты, чтобы упрощать себе работу, например, когда задаем контексты и конфигурируем кластеры.
    Конфигурация Kubernetes: compiled/target_A/setup/setup.sh
    Применение изменений: compiled/target_A/setup/apply.sh
  • Идемпотентность: Kapitan позволяет менять шаблоны и инвентарь для рефакторинга кода. Скомпилированные манифесты и код не изменятся без вашей команды, так что вам нечего бояться при рефакторинге.
  • Причина и следствие: мы за рабочий процесс, где изменения инвентаря или шаблонов и скомпилированные файлы входят в один мерж-реквест. Так проверяющий сможет оценить ваши изменения и их фактические последствия. Полезно знать, повлияет изменение в шаблоне на один, два или несколько целевых объектов.
  • И наконец: Kapitan не привязан к Kubernetes. Он просто создает файлы. Деплоем изменений занимается kubectl. Мы только даем оболочку для команд, чтобы они выполнялись согласованно.

Оно мне надо?


Давайте проясним: вам, наверное, Kapitan (еще) не нужен.


Но все зависит от того, что вы пытаетесь сделать и насколько сложная у вас система.


Kapitan — это мощный инструмент, требующий инвестиций. Используйте его в сложных сценариях, где придется деплоить кучу приложений в куче кластеров.


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


Я себе представляю Helm как apt-get для Kubernetes, а Kapitan — что-то типа Puppet.


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


Спасибо Яцеку Гружевскому (Jacek Gruzewski).

Southbridge
253,00
Обеспечиваем стабильную работу серверов
Поделиться публикацией

Похожие публикации

Комментарии 1

    –1
    del

    Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

    Самое читаемое