CI/CD для Helm Charts

от автора

Задача

Helm мощный и гибкий инструмент управления ресурсами в Kubernetes.

А что если одним Helm Chart пользуются несколько команд для развертывания своих приложений в Kubernetes? Как гарантировать, что Helm Chart как минимум рендериться после внесения изменений, прежде чем публиковать Helm Chart в репозиторий артефактов? Как гарантировать, что новая версия Helm Chart не «сломает» установку приложения в Kubernetes в критический момент(например во время релиза целевого продукта)?

Этими вопросами задался и я при разработке подобного Helm Chart.

Дополнительные требования к задаче

Надо отметить, что в моем случае, в качестве хранилища артефактов используется JFrog Artifactory внутри организации.

Для репозиториев есть явное деление на группы, в которые разрешено публиковать артефакты. В большинстве случаев под группой понимается groupId из pom.xml файла проекта/модуля.

Аналогичное правило работает и для репозиториев хранения Helm Charts.

Выбор инструмента

В моих проектах используется Apache Maven как инструмент сборки, запуска тестов, упаковки и публикации артефактов.

Под артефактом понимается все то, что создается при сборке проекта: JAR/WAR/EAR-файлы, Docker образы, сопутствующие файлы конфигурации, и тп.

Ок, я умею в Maven.

Ок, я умею в Helm Charts.

Почему бы не совместить эти два инструмента?

Что предлагает сообщество, с точки зрения плагинов для Apache Maven, которые можно использовать для работы с таким зверем как Helm Charts?

Сообщество предлагает два плагина:

  1. https://github.com/kokuwaio/helm-maven-plugin

  2. https://github.com/deviceinsight/helm-maven-plugin

Первый позволяет:

  • довольно гибко настроить подготовку Helm Chart как артефакта

  • позволяет сделать как минимум прогнать Helm Chart через встроенный в Helm линтер

  • позволяет опубликовать Helm Chart в репозиторий таким образом, что Helm Chart будет использоваться только лишь в том случае, если при выполнении helm upgrade добавить аргумент --devel, в данном случае будет использоваться пред-релизная(или developement) версия Helm Chart

Второй — не удовлетворял некоторым моим требованиям, поэтому решил идти в бой с первым!

Настройка

Создадим простой проект типа maven, со следующей структурой каталогов/файлов:

./pom.xml ./src/helm/Chart.yaml ./src/helm/templates/config-map.yaml

Содержимое ./src/helm/Chart.yaml:

apiVersion: v2 name: sample-helm-chart version: 0.0.0

Тут важно отметить значения поля version — в исходном коде оно всегда будет равно 0.0.0

Содержимое ./src/helm/templates/config-map.yaml :

apiVersion: v1 kind: ConfigMap metadata:   name: sample-config-map data:   foo: bar

То есть Helm Chart создает объект типа ConfigMap с одним ключом foo и значением bar

А теперь самое интересное, содержимое pom.xml:

<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">     <modelVersion>4.0.0</modelVersion>      <groupId>org.example</groupId>     <artifactId>sample-helm-chart</artifactId>     <version>0.0.1-SNAPSHOT</version>     <packaging>helm</packaging>      <build>         <plugins>             <plugin>                 <groupId>io.kokuwa.maven</groupId>                 <artifactId>helm-maven-plugin</artifactId>                 <version>6.3.0</version>                 <extensions>true</extensions>                 <configuration>                     <chartDirectory>${project.basedir}/src/helm</chartDirectory>                     <chartVersion>${project.version}</chartVersion>                     <timestampOnSnapshot>true</timestampOnSnapshot>                     <addDefaultRepo>false</addDefaultRepo>                     <uploadRepoStable>                         <name>central</name>                         <url>https://example.org/artfactory/hlm-all</url>                         <type>ARTIFACTORY</type>                         <useGroupId>true</useGroupId>                     </uploadRepoStable>                 </configuration>             </plugin>         </plugins>     </build>  </project>

Давайте пройдемся по конфигурации плагина в секции <build>:

  • chartDirectory — указывает на корневой каталог, содержащий код Helm Chart

  • chartVersion — связываем версию Helm Chart и версию проекта/модуля

  • timestampOnSnapshot — в случае, если при сборке версия проекта/модуля имеет суффикс -SNAPSHOT — то суффикс будет заменен на текущее время в формате yyyyMMddHHmmss (формат по умолчанию)

  • addDefaultRepo — нам не нужен репозиторий по умолчанию, так как Helm Chart будет публиковаться в хранилище артефактов внутри организации.

  • uploadRepoStable/name — имя/идентификатор сервера из settings.xml . Необходимо в том числе для аутентификации в хранилище артефактов. В settings.xml должны быть заданы значения полей username и password для сервера указанного в данном поле.

  • uploadRepoStable/url — Адрес хранилища артефактов и базовый путь публикации артефакта.

  • uploadRepoStable/type — Тип репозитория. Плагин поддерживает три типа репозиториев.

  • uploadRepoStable/usegGroudId — согласно дополнительным требованиям к задаче, необходимо публиковать артефакты в свои группы. В случае если usegGroudId равен true , тогда, после публикации нашего Helm Chart в хранилище артефактов, Helm Chart из нашего примера можно будет скачать по адресу https://example.org/artfactory/hlm-all/org/example/0.0.1-SNAPSHOT/sample-helm-chart-0.0.1-20220701142516.tgz

Используя дополнительные плагины для Apache Maven, можно настроить автоматический инкремент версии, чтобы можно было выпускать релизные версии Helm Chart.

Пожалуй, самый важный параметр timestampOnSnapshot — зачем он нужен и как он помогает отделить мух от … в достижении цели?

Как было описано в описании параметров конфигурации плагина:

в случае, если при сборке версия проекта/модуля имеет суффикс -SNAPSHOT — то суффикс будет заменен на текущее время в формате yyyyMMddHHmmss (формат по умолчанию)

Что это дает?

Обратимся к справке по SemVer2:

A pre-release version MAY be denoted by appending a hyphen and a series of dot separated identifiers immediately following the patch version. Identifiers MUST comprise only ASCII alphanumerics and hyphens [0-9A-Za-z-]. Identifiers MUST NOT be empty. Numeric identifiers MUST NOT include leading zeroes. Pre-release versions have a lower precedence than the associated normal version. A pre-release version indicates that the version is unstable and might not satisfy the intended compatibility requirements as denoted by its associated normal version. Examples: 1.0.0-alpha, 1.0.0-alpha.1, 1.0.0-0.3.7, 1.0.0-x.7.z.92, 1.0.0-x-y-z.–.

То есть, если в значении версии, помимо главных атрибутов <MAJOR>.<MINOR>.<PATCH>, есть некий суффикс(в нашем случае текущее время), то это считается пред-релизной версией, или с точки зрения Helm — development версией, а значит, когда выполняется команда helm upgrade будет использоваться только релизная версия Helm Chart, если таковая имеется в репозитории.

Если есть необходимость использовать пред-релизную(или development) версию Helm Chart — надо явно «сказать» Helm’у с помощью аргумента: helm upgrade --devel .

Заключение

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

Но самое сложное было то, что плагин давно не выпускался и пришлось не мало «побегать» за владельцами плагина. Благо ребята оказались отзывчивые и мы дружно вдохнули новую жизнь в плагин!

Как вы считаете нужен ли релизный цикл для таких вещей как Helm Charts?


ссылка на оригинал статьи https://habr.com/ru/post/676002/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *