Комментарии 58
Сомнительное заявление.
Когда нужно применить один манифест, то достаточно kubectl apply. А когда у тебя чарт с несколькими сабчартами и values на несколько страниц, то одними cli утилитами не отделаешься.
А если вспомнить про версионирование и откат то и подавно.
Это базовые задачи, которые успешно решались еще 80-ые годы. Можно включать сколько угодно make файлов с помощью директивы include. Можно делать constrains – валидировать параметры прямо на месте, чего Helm не может, потому что он слишком приметивен. Не все стандарты хороши, то что Helm превратился в нечто похожее на стандарт – это скорее казус истории, чем какая-то веха. Так получилось, что миллионы инженеров дебажат корявую поделку под названием Helm, которая не имеет отношения к кодовой базе Kubernetes.
Не ну поддерживать своё решение, которое нигде потом не будет нужно, это, конечно, не казус.
Я уж молчу про то, что весь набор доступных чартов как-то организовывать самому.
А про валидацию параметров вообще мне непонятно, там же есть values.schema.json
Поддерживать helm сложнее hello world, особенно если там несколько десятков сервисов и есть vault и istio – это не тривиальная задача, но не из-за сложности, а из-за костыльного синтаксиса Helm. Все делается на угад, «на глазок» именно поэтому каждые несколько месяцев появляются «убийцы» Helm. Крупные игроки либо не используют его, либо хотят его заменить другими инструментами.
Ничего специфического для Vault в этом примере нет, можно использовать его как библиотеку – подключить и сделать Make для nginx-ingress-controller. Кстати если вы скажите, что знаете хорошо чарты для Nignx или например GitLab – то я вряд ли поверю, потому что чтобы разбираться в этой куче YAML и go templates нужно постоянно работать с конкретным чартом.
Вот так вы никогда не сможете сделать с помощью YAML:
# Validate memory ranges (e.g., 128Mi <= MEMORY_REQUEST <= 4096Mi)
MEMORY_REQUEST_VALUE := $(subst Mi,,$(subst Gi,,$(MEMORY_REQUEST)))
MEMORY_REQUEST_UNIT := $(suffix $(MEMORY_REQUEST))
ifeq ($(MEMORY_REQUEST_UNIT),Gi)
MEMORY_REQUEST_VALUE := $(shell echo $$(($(MEMORY_REQUEST_VALUE) * 1024)))
endif
ifeq ($(shell [ $(MEMORY_REQUEST_VALUE) -ge 128 ] && [ $(MEMORY_REQUEST_VALUE) -le 4096 ] && echo true),)
$(error Invalid MEMORY_REQUEST value '$(MEMORY_REQUEST)'. It must be between 128Mi and 4096Mi.)
endif
хтонический ужас, вобравший в себя все "прелести" shell scripting вроде слабой устойчивости к спецсимволам и слабой отчуждаемости. helm + external secrets operator + gitops operator это хорошая качественная отчуждаемая база для большинства решений
Для политик есть kyverno.
В целом да, но нет. Helm, ненужный уровень абстракции. Я в подконтрольной мне инфраструктуре избавился от него в пользу kustomize и очень этим доволен
Практически все ключевые сервисы имеют свой helm chart и это позволяет не заниматься изобретениями велосипедов при инсталляции всего нужного. Свои приклады большинство также деплоят через свои универсальные application helm-chart, т.к. получается массовое единообразие, благодаря встраиваемой развесистой логике в шаблонах и динамически подключаемым per-app и per-env values.
Если использовать argocd, который по факту использует только helm template, пользуясь всеми удобствами зонтичных чартов и генерации сложных вещей со всеми циклами, переменными, включениями файлов, эпизодически применяя kustomize там, где нужно пропатчить готовые манифесты, в том числе внешние, то всё очень удобно. Argocd тут в том числе ради OAuth2 и RBAC при работе с целевым решением, каковые упрощают использование построенного.
Не исключено, что есть немало тривиальных случаев, когда достаточно kustomize и десятка манифестов на всё про всё. Но при росте дяже небольшие масштабы требуют унификации, развесистой скриптуемой логики и отчуждаемости и тут сложно предложить что-то универсальнее стандарта де-факто, каковым является helm.
Я это говорю на базе собственного опыта подъёма, развития и поддержки нескольких крупных облачных инфраструктур разных компаний, в том числе с helm, kustomize, flux, argocd, шелла и голых манифестов с, прости господи, cat manifest.yaml|envsubst|kubectl apply -f -.
В статье пишут:
Kustomize применяет преобразования к базовому набору манифестов Kubernetes
Вопрос. Откуда рождается этот самый базовый набор манифестов и в каком виде мне, как разработчику приложения, его публиковать?
Helm дает ответ на этот вопрос. А потом девопс, устанавливающий моё приложение, может обмазывать его Kustomize'ом сколько душе угодно.
Немножко не понял сути вопроса. По умолчанию Helm создает болванку чарта в которой почти ничего нет с помощью команды helm create. Больше он сам ничего не делает. Сначала надо сделать манифесты для Куба, потом шаблонизировать их Helm. Никакой стандартизации между организациями на Западе или в России. нет. Кто-то может использовать Helm, а кто-то Ansible или ytt & carvel, helmfile и так далее.
Я предлагаю использовать и изучать стандарт – Kubernetes API и его манифесты YAML, а для шаблонизации использовать стандартный инструментарий UNIX систем.
Кстати, для того, чтобы сделать канареечные релизы/blue-green развертывание, тоже не нужны сторонние инструменты, только K8s и Istio:
https://github.com/avkcode/vault/blob/main/CANARY.md
Мы «завязываемся» на сторонние инструменты, которые легко заменить и готовим специалистов по установке Vault-of-Banks и Helm. А на реальные задачи ни укого не хватает времени и ресурсов.
Большинство людей которые критикуют Bash и Make не имеют представления как делается сосики. Они думают что их завозят в магазин уже готовыми.
Мне вчера нужно было скомпилировать python их исходного кода с glibc и musl. При определенных условиях glibc может давать 50% производительности любой программе на питоне.
И как вы думаете как делается эта сосика? Все правильно, с помощью make и bash скриптов на десятки тысяч строк кода.
Вы не знаете как делается сосика, поэтому если вам рассказать что из фарша можно делать не только сосики но котлетки, это может привести человека в ужас.
Можно сейчас попросить ChatGPT написать на make проверку, которая будет проверять версию образа докер – «Можно использовать Istio версий «1.21 - 1.23 не ниже и не выше». И ChatGPT легко это сделает, потому что код стал дешевым, а дебаггинг в некоторых случаях непростительно подорожал.
Я начинал свой unix-путь с FreeBSD 2.2.5 и уже 10 лет живу внутри Emacs в unix-среде и что хочу сказать: я отлично умею и в C, и в развесистый shell scripting и make не брезгую, но точно знаю когда их не нужно использовать. Удел make это сборка одного проекта уровня системной библиотеки/сервиса/приклада на C++ и т.д.. На уровне Infrastructure as Code со всеми их облаками, терраформами/crossplane и деплоями 100500 микросервисов из 100500 источников места для shell остаётся крайне мало: внутри пайплайнов и как клей для небольших скриптиков без особой логики. Как только появляется логика и качественная обработка ошибок, то просто переход на python уже сильно упрощает устойчивость и развиваемость решений. Иначе получаются глючные монстры, которые слабо отчуждаются от авторов и которые регулярно неожиданно падают в недрах этого всего при внезапном заносе спецсимволов откуда-нибудь, в том числе с пользовательским участием. А уж про обеспечение идемпотентности на shell-решениях можно угробить море ресурсов и всё равно не достичь её в полной мере: ел, достигал, плевался. Все эти helm, terraform, ansible, пайплайны, gitops-операторы не просто так появились: они действительно эффективно решают проблемы управляемости при масштабировании и отчуждаемости. Я в этом активно и с удовольствием варюсь и вижу воочию.
И ChatGPT точно не панацея: оно способно решить узенькую задачку, но "почини вот это вот всё" с прицелом в инфру оно точно не может.
Это не очень хорошая аргументация, вы «апеллируете к власти». Раз придумали, значит надо. Несколько лет назад пиком моды в Java экосистеме был XML – во имя отчуждаемости миллионы Java разработчиком строчили корпоративного уровня портянки на XML которые сейчас превратились в тех. долг. Уйдут годы прежде чем этого кода можно будет избавится. Helm-чарты и YAML – это тот же самый XML\XSLT.
Большинство людей которые критикуют Bash и Make не имеют представления как делается сосики. Они думают что их завозят в магазин уже готовыми.
А разве сосиски не завозят в магазин уже готовыми?
Антипаттерн это использовать инструменты, предназначеные для сборки, в качестве инструментов для развёртывания.
Helm хорошо решают свою задачу - управление зависимостями в рантайме - когда у систем может быть over 9k разных параметров.
Программирование на шаблонах это действительно отдельный вид мазохизма. Но если руки чешутся заморочиться, то можно использовать кодогенерацию - в конце-концов это просто yaml.
Так это и есть по сути генерация кода -мы генерируем обычный манифест K8s и это есть способ который рекомендует документация Kubernetes. А вот о Helm там ничего нет.
так Вы добавьте пару десятков опций деплоя и попробуйте сделать это понятным для использования программистами. Helm templates и его легко документируемые примерами values-файлы легки к совместному использованию и развитию. А иные варианты нет, и всех делов: даже pulumi не взлетает.
Это новая для меня информация, обычно все говорят, что Helm – это неизбежное зло и с ним приходится мирится, потому что якобы альтернативы нет. Чтобы Helm кому-то кроме DevOps инженеров нравился это для меня новость.
Берем и импортируем так называемые values файлы. На самом деле просто файл с параметрами.
ENV ?= dev
# This allows users to override the ENV variable by passing it as an argument to make
.
ALLOWED_ENVS := global dev sit uat prod
# Define a list of allowed environments. These are the valid values for the ENV variable.
ifeq ($(filter $(ENV),$(ALLOWED_ENVS)),)
$(error Invalid ENV value '$(ENV)'. Allowed values are: $(ALLOWED_ENVS))
endif
Можем ограничить этот список, и можем импортировать глобальные параметры. На выходит просто генерируется обычный манифест Kubernetes.
.PHONY: dump-manifests
dump-manifests: template convert-to-json
@echo "Dumping manifests to manifest.yaml and manifest.json..."
@make template > manifest.yaml
@make convert-to-json > manifest.json
@echo "Manifests successfully dumped to manifest.yaml and manifest.json."
И это почти все что делает Helm. А такие инструменты как Argo вполне могут использовать обычный манифест Kubernetes без Helm.
Кстати, а если вам нужно реализовать что-то нестандартное вы будете открывать issue или PR на GitHub? Потом ждать аппрува от разработчиков и безов – они ведь просто так кастомную версию Helm в прод не пропустят.
Все это можно сделать гораздо проще и эффективнее.
Проблема в том, что каждое логическое условие удваивает сложность для понимания кода. Вы можете хоть сотню раз запускать make для сборки, неделями, пока найдёте ошибку.
В случае с деплоем обычно нет такой роскоши. Здесь проблемы нужно исправлять быстро и уверенно. Любая нестыковка, если исполнение вдруг пойдет не по той ветке, может иметь катострофические последствия. Поэтому код здесь максимально линейный. Ради этого можно мириться с копипастом и прочими грехами, о которых у нормальных программистов встают волосы дыбом.
Сгененерировать хелмы мейком - ради б-га, если вам так удобнее. Потом все равно отсмотрите глазками, потратив столько же времени, сколько бы писали вручную. Но использовать мейк с логикой в качестве инструмента для развёртывания это игра в русскую рулетку.
Ну почему, это и есть то самое «грамотное программирование» по Дональду Кнуту – когда код, документация и тесты находятся в одном месте. И это тестирование, которым DevOps инженеры обычно даже не заморачиваються, а в лучшем случае перекидывают это тестировщикам – они в свою очередь не разбираются в Kubernetes и CI/CD.
Я не совсем почему вы думаете, что есть такая экспоненциальная сложность в Helm. Helm это не Kubernetes, он сам по себе почти ничего не делает, а то что делает реализовано крайне «костыльно», сторонними разработчиками.
Есть Кубик, и есть все остальное - что вокруг него было накручено.
добавьте на вход своему make словари произвольного устройства (кусочки куберовых конструкций, вроде томов, схем обновления, topologespreadconstraints) и покажите как пользователям с ними работать. helm ведь именно это облегчает: управляемый сложный темплейтинг на основе сложных данных.
Деплоим с помощью Ansible. В кубер он умеет на отлично ходить и подход очень простой. Проще только манифесты пулять, но нам надо переменные и тд. 🙂
Можно Ansible, можно Pulumi и Terraform и многое другое. В умелых руках может взлететь все что угодно.
Но я убежден, что между кодом, тестами и деплоем не должно быть барьеров и предпочтительно если это все хранится в одном репозитории, а развернуть это все может разработчик через PR, без специально выделенных devops и qa отделов.
С мейкфайлов перешел на https://github.com/casey/just, рекомендую, гораздо удобнее.
А ещё task, сами используем, после make небо и земля.
кстати, а как насчёт атомарного обновления и отката при неудаче при использовании makefile: они ведь не видят ничего глубже "кубер сказал configured" и не могут понять что деплоймент сфэйлился и откатиться назад по таймауту. Опять писать 100500 шеллскриптов на все пограничные состояния? Так точно хуже helm получится.
Хельмом просто 100% приложений катится в куб опенсорсных, нельзя же просто взять и сказать, что это плохо))
Под свои приложения, конечно, тяжко каждый раз хельм писать. Тем более все частные чарты в пределе стремяться к универсальному, который описывает всё и просто настраивается конфигом. То есть helm chart это просто приложение которое деплоит другие приложения))
Для примера, тут (https://github.com/nixys/nxs-universal-chart) ребята сделали универсальный чарт для которого конфиг это та же самая структура сущностей куба
services:
app:
type: ClusterIP
ports:
- name: web
protocol: TCP
port: 80
targetPort: 8080
Бери готовый чарт, корми ему свой конфиг и всё задеплоено.
В больших компаниях Helm используется реже, тот же RedHat с OpenShift до сих пор рекомендует oc + ansible и именно так деплоят многие финансовые организации.
Но дело в том, что большинство DevOps инженеров не сталкиваются с такими проблемами, потому что разворачивают они веб-приложения в стартапах, когда взять готовый чарт, который они зачастую не понимаю и просто накатить в прод.
Helm install это новый yum install или apt-get install. Есть мизерный процент людей которые могут делать свои пакеты.
Разнится в том, что на дебаг в Kubernetes тратится огромное количество времени, которое можно было бы израсходовать на более важные задачи.
Ну в целом такой подход и работает, что некоторый процент популяции понимают шаблоны golang или абстракции terraform и пишут общие чарты/модули которыми все потом пользуются. Я думаю что всем не обязательно погружаться в sed, awk, jq чтобы просто приложений в куб деплоить))
Я бы не стал смешивать helm и terraform/HCL Это два разных по уровню и качеству проекта. Что в принципе не удивительно, учитывая что за Terraform стоит известная компания, Helm писали энтузиасты чтобы быстро решить свои проблемы.
Это как разница между покупкой полуфабриктов в магазине и собственной готовкой. Если вы совсем не умеете готовить, то лучше покупать из магазина, хоть это и не очень полезно. Но это никогда не сравнится с тем, что может приготовить хороший шеф.
Конечно, если у вас много денег, то можно заказывать доставку из ресторана. )
kubectl apply
— не решение. Над kubectl нужна абстракция, которая будет отслеживать переименования, удаления ресурсов, регулировать порядок выката и т. п. Например, если у вас пользователь переименует Ingress с myapp-org
на myapp
, то старый Ingress myapp-org
не удалится и перестанет обновляться.
Критика Helm оправдана, но не вижу ни одной решенной проблемы Helm. Вы всё также шаблонизируете YAML как текст. Чем make/bash/jq/... удобнее Helm-шаблонов не очень понятно. Дистрибуция шаблонов и входной конфигурации (values) исчезла. Тысячами опенсорсных Helm-чартов больше не воспользоваться. Новые люди в среднем быстрее разберутся с Helm, чем с вашим решением, т. к. многие Helm уже знают.
Вашу б энергию в полезное русло. Принесите нам в Nelm PR какой-нибудь лучше, если в Helm что-то не нравится.
Helm ничего отслеживает. Это вы наверное с Argo перепутали. Helm просто устанавливает манифесты через API и создает JSON в kubernetes secrets. А потом удаляет.
Values - это файл с параметрами, он просто называется по другому в примере – dev.param.
Новым людям лучше не набивать helm install в gitlab пайплайнах, а лучше разбирать по косточкам чарты для nginx controller и переделать их в обычный манифест Kubernetes. Новые люди не очень хорошо знают что они заносят в прод. Они знают как менять переменные в values файлах и редактировать чужие образы Docker в Docker файлах. Не учите новых людей плохому.
Конторка у вас неплохая (я имею ввиду Флант) но учитывая количество сотрудников, мы ожидаем немного большего, чем очередной command line инструмент и надстройку на Istio и Kubernetes. Ваши бы ресурсы да проекты уровня RedHat.
хорошо что Вы есть: тем больше высокооплачиваемой работы для меня по выпиливанию подобной дичи :)
Вас очень много таких, и вы в основном не выпиливаете, а копипастите из интернета. )
Вам виднее :) А я успешно строю большие отчуждаемые решения, всячески избегая NIH-синдрома, чего и другим желаю от чистого сердца.
NIH-синдром или «Not invented here» присущ обычно таким компаниям как Google, Amazon, Meta – и так далее. То есть лучшим из лучших. Учится нужно у лучших, а не у тех кто хорошо научился пользоваться чужим.
И раз уж в России решили заняться (вольно или не вольно) импортозамещением, то не мешало бы начать придумывать свое, а не копировать слепо чужое.
Helm ничего отслеживает. Это вы наверное с Argo перепутали. Helm просто устанавливает манифесты через API и создает JSON в kubernetes secrets. А потом удаляет.
Ну вообще таки отслеживает, но не совсем так, как представляется сходу.
Он объектам аннотации проставляет, за которыми потом следит, чтобы понять консистентность, версию и все такое. В общем это не обычный темплейтер. Но то ладно.
Вы лучше вот что скажите - вот ваша штука как-то работает, хелм как-то работает.
Какая польза от вашей штуки бизнесу в сравнении с хелмом? Почему нужно человеко-дни на это тратить, что он принципиально решает из того, что хелм решить не может? Или решает настолько эффективно, что это окупится?
С хелмом понятно. Внешний софт обычно с ним идет, внутренний софт - ну тут есть выбор.
Почему нужно сделать выбор в сторону де-унификации то (я уж не говорю о том, чтобы внешние чарты выкинуть и ваше решение использовать)?
То что вы описали – это не «отслеживает» – это обычный pattern matching по аннотациям или лейблам Kubernetes. Если бы helm был контроллер или демон, тогда можно было бы говорить об отслеживании.
Это не деунификация потому-что helm – это не стандарт. О Helm нет ничего в доках Kubernetes и это не просто так.
Стандарт это RFC, ieee или включение в кодовую базу Linux. Helm – это просто инструмент который набрал популярность.
Стандарт это манифесты Kubernetes, его API схема. В моем примере мы получаем стандартный манифест Kubernetes а распространяем архив с исходным кодом.
make package & make bundle
И это кстати требование PCI DSS. Там где ошибка может стоить денег или человеческих жизней, тестирование и верификация имеет значение. Там нельзя просто копирнуть из апстрима чужой чарт и накатить его на прод. Мой подход помогает обеспечивать гарантии безопасности и качества для бизнеса.
Если бы helm был контроллер или демон, тогда можно было бы говорить об отслеживании.
Это не связанные между собой вещи. Кстати - в Helm 2 был демон :)
Мой подход помогает обеспечивать гарантии безопасности и качества для бизнеса.
Ответы то где? Это же просто стейтмент. Вы же не ответили на заданные мной вопросы.
И это кстати требование PCI DSS.
PCI DSS кстати не регламентирует использование make. Он вообще напрямую инструменты не регламентирует. Там за уши можно притянуть только пункт 10.2.4, где есть требования к отслеживанию изменений (которые вообще не решаются ни хелмом, ни вашей пачкой мэйков) и 6.4.3 про верификацию и тестирование (хелм умеет в тесты). Считаете иначе - несите пункт стандарта и объясните почему и как ваше решение помогает его имплементации (само по себе и в сравнении с хелмом), тогда и поговорим.
Кстати, я не говорил ничего о стандартах, я говорил о реальности.
Helm ничего отслеживает
Отслеживает, как же не отслеживает. Он в релизный секрет сохраняет список выкаченных манифестов, потом сравнивает со списком на выкат при следующем релизе. Но давайте не про формулировки, вы же поняли, о чем речь. Давайте про суть: у вас нельзя ни переименовать, ни удалить ресурс, а в Helm можно. Кроме этого у вас еще десятков жизненно необходимых вещей нет, и это только про выкат речь.
Values - это файл с параметрами, он просто называется по другому в примере – dev.param.
Я не говорил, что у вас параметры не поддерживаются. Я сказал, что дистрибуция параметров (и логики) исчезла.
Вот вы когда добавите возможность переименовывать и удалять лишние ресурсы. Да ролбэки бы ещё, а значит нужен стейт, как в Helm/Argo. А ещё так, чтобы RoleBinding не падал через раз с ошибкой "указанной Role нет" из-за race между выкатом Role и RoleBinding в следствие отсутствия очередности. А потом ещё тридцать других штук пофиксите/имплементируете, без которых можно только hello world деплоить. И получите Helm на make и bash, где багов в 10 раз больше, фич в 10 раз меньше, а контрибьютить в него сможет только один человек на планете.
Ну это попытка в частностях и деталях запутать суть вопроса, которая очень проста – Helm ничего не «отслеживает». Он так не умеет, для этого многие используют Argo.
Helm сохраняет информацию о релизе в JSON. Я показал что это очень просто можно реализовать с помощью скрипта и в отличии от Helm мы ничем не ограничены и можем использовать переменные из Git, сохранять информацию во внешних базах данных, к примеру.
Документация Kubernetes тоже показывает все на простом примере guest-book и Helm create создает простую «болванку» nginx чарта. Мы с вами прекрасно знаем, что реальные манифесты и чарты для K8s гораздо сложнее.
Но это уже делается индивидуально под организации и конкретные проекты. Для helm делаются library чарты, которые отличаются от апстримных и иногда добавляется еще и логика через pre и post хуки и CI/CD.
Да сложные кодовые базы требуют относительно сложные сборочные системы и CI/CD. Универсальных простых решений для всего – не бывает.
Если вы хотите закоминить в кодовую базу Kubernetes – будьте готовы изучать сборочную систему и тесты Kubernetes.
https://github.com/kubernetes/kubernetes/blob/master/build/root/Makefile
Но и для деплоя любой не тривиальной кодовой базе в большой организации понадобится нечто большее чем простой чарт из интернета.
Посмотрите, например на зонтичный чарт GitLab – это примерно 90 тысяч строчек кода.
Теперь добавьте сюда тестовые среды DEV,SIT,UAT,PROD; Vault и Istio. Получится примерно 150-200k LOC убористого YAML с go templates.
Мой подход не просто дает лучшие гарантии качества и безопасности, но и уменьшает количество строчек в несколько раз. То что вам придется для этого немного подучить Bash, Python и Make – ну что ж такова жизнь. Когда придется научится готовить самому, а не покупать заморозку из магазина, особенно если речь идет о таком шлаке как YAML.
Helm сохраняет информацию о релизе в JSON. Я показал что это очень просто можно реализовать с помощью скрипта
Можно человека в космос на shell-скриптах отправить, вполне вероятно. Но зачем? В Helm ~25к строк кода на Go (без учета библиотек, тестов, комментов, пустых строк). Вы вот когда все ваши "это очень просто реализовать" реализуете, вы что получите-то? 25к строк на make/bash? И это без учета самих манифестов и их параметризации. А сколько времени потратите, несколько лет? Зачем? В чём профит? Почему вы не хотите это на нормальном языке написать?
Если вы хотите закоминить в кодовую базу Kubernetes – будьте готовы изучать сборочную систему и тесты Kubernetes.
Да чего там изучать, там простейший Makefile на 500 строк. Я против Makefile'ов как таковых ничего не имею, у нас у самих их аналог есть в каждом репе. Но я ни разу не видел, чтобы в Makefile на bash-скриптах изобретали Helm.
Посмотрите, например на зонтичный чарт GitLab – это примерно 90 тысяч строчек кода.
А каким образом у вас получится в несколько раз меньше строк? Чарт это логика в go-шаблонах + параметры в values. Вам и то и другое придется повторить на make/bash, и вдобавок ещё на make/bash переписать Helm.
В Helm гораздо больше строчек кода – то что вы назвали это без сторонних библиотек. Я думаю, что не нужно никому объяснять, что Bash, Make и Python по умолчанию гораздо «лаконичнее» Go и требуют гораздо меньше строчек кода для описания логики. У Go есть свои преимущества, но лаконичность в них точно не входит.
Релизная логика в Helm – элементарно простая. Может строчек на 50-100.
Helm – не надо изобразить – это пакетный менеджер для Куба и не очень хороший. Примерно на том же уровне, что и поделки для разных дистрибов на Linux. Можно написать лучше, а можно не писать а заменить его Make, как это сделано на BSD системах например.
Helm это не ArgoCD и не Sinnaker, это просто очень костыльный шаблонизатор. От него можно и нужно избавляться.
Релизная логика в Helm – элементарно простая. Может строчек на 50-100.
Если здесь вы подразумевали логику выката в Helm, то вы ошиблись на несколько порядков. Говорю как человек, который половину хелмовой кодовой базы переписывал.
Остальное не вижу смысла комментировать, вы попробуйте сначала сами сделать то, за что агитируете. hello world на make/bash, где даже переименовать ресурс нельзя, не считается.
Занимаемся outsource Web-разработкой и также хостим сайты клиентов. Платформа - в основном PHP, Laravel. Для каждого сайта деплоится само приложение (php-fpm, nginx, redis), очередь для него (отдельный worker и redis для очереди), cronjob для периодических задач, а также некоторые дополнительные специфические контейнеры для каждого проекта (elasticsearch, websocket server, nodejs и т.д).
Тоже начинали с kubectl apply, bash, envsubst, makefile, однако быстро поняли что в каждом проекте огромные манифесты, которые на 95% повторяют друг друга. После этого в отдельной репозитории создали helm чарты, подключили их в каждом проекте и вместо кучи манифестов получили один values.yaml файл в репозитории, с помощью которого можно всё настроить: какие сервисы нужны на этом проекте, а какие нет, прописать ресурсы, образы.
Можно ли было сделать это без helm? Да. Но тогда бы пришлось в ci/cd писать кучу скриптов, чтобы скачать манифесты из общего хранилища (git clone/curl/wget), вручную с помощью env переменных управлять сборкой манифестов, использовать кучу тулзов для работы с текстом... И для чего?
Вывод как всегда простой - у каждого инструмента есть своя сфера применения и если он не подошел вам, то это не значит что он не подходит всем остальным. У helm есть куча применений где он облегчает работу, так что заявлять что это анти-паттерн - это ошибка
Описанный пример, очень просто реализовать с помощью kubectl и make include. Могу продемонстрировать как, а также показать чего точно нельзя сделать с помощью helm.
Представьте себе у вас один Helm chart включает другой subchart, который использует образы Docker от сторонних разработчиков. То есть либо вы ждете пока 3 разных владельца обновят свой код, либо закатываете рукава – форкаете три разных чарта и начинаете рабоать в поте лица.
А если вам надо делится кодам между командами в большой компании вы будете писать library chart?
А можете вот сделать:
https://github.com/avkcode/vault/commit/702a7a0785380f66962457a78aa992bb8bded51a
Я добавил diff utils и теперь если установить утилиты diff и bats => потом создать скопировав dev.param файлы с values для прода – prod.params => поменять в нем например namespace по умолчанию для установки на «CHANGEME»
теперь для того, чтобы получить diff с подстветкой и пагенацией достаточно набрать:
make diff-params
https://radikal.host/i/IWxBkW
На это ушло 30 минут. Человекагоды потеряны на дебаг чартов Helm только из-за отсутствия нормального diff.
Насколько я понимаю этот подход, вы описали все ресурсы (rbac, config map, stateful set, service), создали Makefile и задеплоили один единственный сервис. А теперь представьте, что в вашей организации 200+ микросервисов и им всем нужны одни и те же k8s ресурсы. Отличаются они только именем образа Docker и возможно переменными окружения. Что вы сделаете в этом случае? Будете копировать одинаковые файлы для каждого сервиса? Helm позволяет упаковывать k8s ресурсы для простого переиспользования и этим он хорош.
В большой организации есть специальные команды, которые пишут эти пакеты, а разработчики сервисов лишь применяют их. Кроме того там есть версионирвоание, то есть можно применить разные версии одного и того же пакета.
Так или иначе эту функциональность вам придётся создать вашим инструментом. Только зачем, если есть готовый?
Это все уже было реализовано именно под микросеврсную архитектуру в огромной организации с очень строгими требованиями безопасности. Vault это просто пример который я могу показать.
Этот метод позволил в x4 уменьшить количество кода и несколько раз ускорил деплой, я не говорю уже о тестировании, о котором российский DevOps даже не задумывался.
А выше я показал как можно добавлять фичи, которых у Helm никогда не было и не будет за 20 минут, особо не напрягаясь.
Откуда взялось уменьшение кода в 4 раза, если в обоих случаях нужно написать одни и те же базовые манифесты, только в вашем случае вы судя по всему ещё и создали свой собственный аналог helm?
Ну строго говоря я создал инструмент обладающий гораздо более широкими возможностями чем Helm.
Количество строчек уменьшается благодаря DRY и SOLID.
Helm такого не умеет, как только вам нужно сделать что-то сложнее if/else в шаблонах, начинаются извращения с go-templates.
90% коммитов в популярные Helm чарты это фиксы неправильной интендации
Каждые несколько месяцев появляются новые инстурменты и языки на замену Helm: cue, jasonnet, Glasskube и так далее..
Большинство из тех кто использует этот инструмент на масштабных проектах не довольны Helm, просто нет альтернативы
Но я показываю другой подход к решению этой задачи
Представьте что у вас есть несколько десятков меток или аннотаций, который нужно динамически
добавлять к каждому сервису в чарте.
Как с помощью Helm динамически добавлять списки лейблов? Kastomize так точно не умеет.
https://github.com/kubernetes-sigs/kustomize/issues/964
Make – поскольку это обычный task и command runner не позволяет это сделать легко:
https://dev.to/avkr/replace-helm-with-kiss-456a
Секция "Labels"
Тулзы не никогда не смогут сделать например динамическую генерацию лейвлов и аннотаций на основе целевой среды - DEV/PROD/STAGE/TEST SLA:
app.team:devops app.critical:false app.sla:best-effort
make validate-configmap
---
apiVersion: v1
kind: ConfigMap
metadata:
labels: app.environment:dev app.git/branch:main app.git/commit:af4eae9 app.git/repo:https://github.com/avkcode/nginx.git app.team:devops app.critical:false app.sla:best-effort
name: release-name-ingress-nginx-controller
namespace: default
Если указать env = PROD из CLI или в CI то добавится лейблы с SLI:
app.team:devops app.critical:true app.sla:tier-1
ENV=prod make validate-configmap
---
apiVersion: v1
kind: ConfigMap
metadata:
labels: app.environment:prod app.git/branch:main app.git/commit:af4eae9 app.git/repo:https://github.com/avkcode/nginx.git app.team:devops app.critical:true app.sla:tier-1
name: release-name-ingress-nginx-controller
namespace: default
Вещи которые казались сложными становятся простыми и доступными. Потому что на самом деле это просто манипуляция строками и эти проблемы были решены задолго до нас.
Код:
# Validate and set environment
VALID_ENVS := dev sit uat prod
ENV ?= dev
ifeq ($(filter $(ENV),$(VALID_ENVS)),)
$(error Invalid ENV. Valid values are: $(VALID_ENVS))
endif
# Environment-specific settings
ifeq ($(ENV),prod)
APP_PREFIX := prod
EXTRA_LABELS := app.critical:true app.sla:tier-1
else ifeq ($(ENV),uat)
APP_PREFIX := uat
EXTRA_LABELS := app.critical:false app.sla:tier-2
else ifeq ($(ENV),sit)
APP_PREFIX := sit
EXTRA_LABELS := app.critical:false app.sla:tier-3
else
APP_PREFIX := dev
EXTRA_LABELS := app.critical:false app.sla:best-effort
endif
# Extract Git metadata
GIT_BRANCH := $(shell git rev-parse --abbrev-ref HEAD)
GIT_COMMIT := $(shell git rev-parse --short HEAD)
GIT_REPO := $(shell git config --get remote.origin.url)
ENV_LABEL := app.environment:$(ENV)
GIT_BRANCH_LABEL := app.git/branch:$(GIT_BRANCH)
GIT_COMMIT_LABEL := app.git/commit:$(GIT_COMMIT)
GIT_REPO_LABEL := app.git/repo:$(GIT_REPO)
TEAM_LABEL := app.team:devops
LABELS := \
$(ENV_LABEL) \
$(GIT_BRANCH_LABEL) \
$(GIT_COMMIT_LABEL) \
$(GIT_REPO_LABEL) \
$(TEAM_LABEL) \
$(EXTRA_LABELS)
define generate_labels
$(shell printf " %s\n" $(patsubst %:,%: ,$(LABELS)))
endef
Helm это анти-паттерн