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

Если у нас есть 5 вариантов решений, то новичку трудно понять, какой из них лучше.

Здесь я попробовал создать список общих указаний и рекомендаций, чтобы получить представление об оптимальных способах работы с helm-чартами.

Здесь будет 7 тем в 3-х постах, и в основном это есть в документации Helm по ссылке https://helm.sh/docs/chart_best_practices/


Начнем с названий чартов

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

Хорошо

nginx
wordpress
wordpress-on-nginx

Нехорошо

Nginx
Wordpress
wordpressOnNginx
wordpress_on_nginx

Что касается номеров версий чарта, то Helm рекомендует нотацию SemVer2 или Семантическое Версионирование 2.0.0.

Тебе может быть не знакомо это название, то ты уже много раз с этим встречался.

Вкратце, номера версий имеют вид MAJOR.MINOR.PATCH.

Первое число представляет старший номер версии, второе — младший, третье — номер патча.

Допустим, вчера ты создал совершенно новое приложение и присвоил ему версию `0.1.0`.

Сегодня ты нашел нашел ошибку безопасности и исправил ее. Вместе с приложением изменится и его версия, она станет `0.1.1`.

Позже ты находишь другую ошибку и исправляешь ее. Версия вновь изменится и станет `0.1.2`.

Ок, дальше ты вносишь небольшие изменения в свое приложение, например, меняешь функцию, убирая лишние циклы, благодаря чему она начинает потреблять на 5% меньше памяти. Это может стать версией `0.2.0`.

Обрати внимание, что когда ты обновляешь минорный номер в версии, номер патча сбрасывается до 0.

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

Вот в этом случае изменится мажорная версия и становится `1.0.0`.

Этот подход к версионированию справедлив и в проектировании своих helm-чартов.


Теперь давай поговорим о файле `values.yaml`

Все имена переменных в файле `values.yaml` должны начинаться со строчных букв.

Также тире и подчеркивания не поддерживаются.

Очень часто переменная должна содержать несколько слов, чтобы было понятно о чем идет речь.

Используй регистр `camelCase`, когда первое слово начинается со строчной буквы, а все последующие начинаются с заглавной.

Здесь я показал как верно и неправильно.

Хорошо

replicaCount:   3
wordpressSkipInstall:   false
wordpressUsername:   user

Нехорошо

ReplicaCount:   3
wordpress_skip_install:   false
wordpress-username:   user

При этом первые две неверные строки, те что с первой заглавной буквой и подчеркиваниями все же будут приняты, но с тире — совсем никак.

Что касается самой структуры переменных, у нас есть плоский и вложенный форматы.

Вложенный

image: 
    repository:   nginx
    pullPolicy:   IfNotPresent
    tag:   "1.16.0"

Плоский

imageRepository:   nginx
imagePullPolicy:   IfNotPresent
imageTag:   "1.16.0"

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

Мы можем переработать это в плоский формат, как ты видишь ниже.

Ок, если возможно, нам следует предпочесть плоский формат.

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

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

Теперь поговорим о самих значениях полей.

Вот такой булев параметр `enable: false` мы далее будем проверять в шаблоне с помощью блока if или with.

values.yaml

enable:   "false"

startTS:   1670843898

templates/timer.yaml

{{- with .Values.enable }}

startTimeStamp:  {{  $.Values.startTS  }}

{{- end  }}

release-name/templates/timer.yaml

…
startTimeStamp:   1.670843898e+09
…

Внизу результат рендеринга шаблона.

Так вот, значение `enable` будет ложным в том случае, если оно будет указано так:
— `false` маленькими буквами,
— `FALSE` большими,
— `False` с заглавной
— и в значении 0.

Если ты установишь `enable: FalSe` символами из разных регистров как видишь здесь, то цикл `with` по `.Values.enable` успешно выведет содержимое блока.

Что касается кавычек в значениях, то `enable: false` и `enable: “false”` присвоит переменной разные типы.

В первом случае присваивается логический булев тип. Во втором случае присваивается строковое значение, которое будет понято как истина.

Всегда заключай строковые значения между знаками двойных кавычек, если не уверен в них.

С целыми числами тоже есть особенности.

Скажем, у нас число epoch timestamp в поле `startTS`.

При парсинге файла шаблонов его значение будет преобразовано в экспоненциальное представление. В итоге получится дробное число со степенью.

При работе с большими числами ты обязательно столкнешься с этой проблемой.

Просто определи число как строку, добавив двойные кавычки, как видишь здесь.

После этого в файлах шаблонов, когда потребуется использовать эту переменную, добавь к ней префикс функции преобразования типа int для больших или int64 для очень больших чисел.

values.yaml

enable:   "false"

startTS:   "1670843898"

templates/timer.yaml

{{- with .Values.enable }}

startTimeStamp:  {{  int  $.Values.startTS  }}

{{- end  }}

release-name/templates/timer.yaml

…
startTimeStamp:   1670843898
…

Таким образом, строка `167 и т.д.` будет преобразована в число 167… и т.д., а не в его экспоненту.

Также, в современных версиях можно просто установить int без преобразования значения в строку, это уберет экспоненту.

Ок, хорошим тоном считается документирование файлов `values.yaml`.

Когда пользователь открывает файл значений, все, что он получает, — это длинный список переменных.

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

values.yaml

…

## replicaCount Number of NGINX replicas to deploy
##
replicaCount:   1
## updateStrategy.type NGINX deployment strategy type
## updateStrategy.rollingUpdate NGINX deployment rolling update config
## ref: https://kubernetes.io/docs/concepts/workloads/controllers/deployment/
##
updateStrategy:
    type:   RollingUpdate
    rollingUpdate:   {}
## podLabels Additional labels for NGINX pods
## ref: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/
##

…

Обрати внимание, как мы начинаем комментарий. Мы пишем с фактического имени переменной. Это рекомендуемый подход, поскольку и упрощает поиск, и особенно помогает инструментам авто-документирования сопоставить наши примечания с параметрами, которые они описывают.

Прежде чем мы перейдем к шаблонам, у нас остаются файлы LICENSE и README.md.

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

Файл README представляет собой инструкцию формате Markdown и обычно содержит:

  • описание приложения в чарте

  • команды, как установить чарт

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

  • описания параметров файла values.yaml и значения по умолчанию

  • особенности установки, настройки и дебага чарта

На эту информацию ориентируется автоматика репозиториев, когда отображает данные о чартах, а также с ним работает команда `helm show readme`.

Ок, это все в этом посте, продолжим в следующем.

Комментарии (0)