Helm без хайпа. Трезвый взгляд
Helm — это менеджер пакетов для Kubernetes.
На первый взгляд, неплохо. Этот инструмент значительно упрощает процесс релиза, но порой может и хлопот доставить, ничего не попишешь!
Недавно Helm официально признали топовым проектом @CloudNativeFdn, он широко используется коммьюнити. Это говорит о многом, но я бы хотел коротко рассказать о неприятных моментах, связанных с этим менеджером пакетов.
В чем истинная ценность Helm?
На этот вопрос я до сих пор не могу ответить уверенно. Helm не предоставляет каких-либо особенных возможностей. Какую пользу приносит Tiller (серверная часть)?
Многие чарты Helm далеки от совершенства, и, чтобы использовать их в кластере Kubernetes, нужны дополнительные усилия. Например, у них отсутствует RBAC, ограничения ресурсов и сетевые политики. Просто взять и установить чарт Helm в двоичном виде — не думая о том, как он будет работать, — не выйдет.
Мало нахваливать Helm, приводя простейшие примеры. Вы объясните, чем он так хорош — особенно с точки зрения безопасной мультитенантной рабочей среды.
Слова — пустое. Вы мне код предъявите!
—Линус Торвальдс
Дополнительный уровень авторизации и контроля доступа
Помню, кто-то сравнивал Tiller с «огромным сервером sudo». На мой взгляд, это просто очередной уровень авторизации, который при этом требует дополнительных сертификатов TLS, но не предоставляет возможностей для контроля доступа. Почему бы не использовать API Kubernetes и существующую модель безопасности с поддержкой функций аудита и RBAC?
Перехваленный инструмент для обработки шаблонов?
Дело в том, что для обработки и статического анализа файлов шаблонов Go используется конфигурация из файла values.yaml
, а затем применяется обработанный манифест Kubernetes с соответствующими метаданными, хранящимися в ConfigMap.
А можно использовать несколько простых команд:
$ # render go-template files using golang or python script
$ kubectl apply --dry-run -f .
$ kubectl apply -f .
Я заметил, что разработчики обычно использовали один файл values.yaml
на среду или даже получали его из values.yaml.tmpl
перед использованием.
Это не имеет смысла при работе с секретами Kubernetes, которые часто зашифровываются и имеют несколько версий в репозитории. Чтобы обойти это ограничение, потребуется использовать плагин helm-secrets или команду --set key=value
. В любом случае добавляется еще один уровень сложности.
Helm как инструмент управления жизненным циклом инфраструктуры
Забудьте. Это невозможно, особенно если речь — об основных компонентах Kubernetes, таких как kube-dns, поставщик CNI, cluster autoscaler и т.д. Жизненные циклы этих компонентов различаются, и Helm в них не вписывается.
Мой опыт работы с Helm показывает, что этот инструмент отлично подходит для простых деплоев на базовых ресурсах Kubernetes, легко осуществимых с нуля и не предполагающих сложного процесса релиза.
К сожалению, с более сложными и частыми деплоями, включающими Namespace, RBAC, NetworkPolicy, ResourceQuota и PodSecurityPolicy, Helm не справляется.
Понимаю, поклонникам Helm мои слова могут не понравиться, но такова реальность.
Состояние Helm
Сервер Tiller хранит информацию в файлах ConfigMap внутри Kubernetes. Ему не нужна собственная база данных.
К сожалению, размер ConfigMap не может превышать 1 МБ из-за ограничений etcd.
Надеюсь, кто-нибудь придумает способ улучшить драйвер хранилища ConfigMap, чтобы сжимать сериализованную версию до перемещения на хранение. Впрочем, так, я думаю, настоящую проблему все равно не решить.
Случайные сбои и обработка ошибок
Для меня самая большая проблема Helm — его ненадежность.
Error: UPGRADE FAILED: "foo" has no deployed releases
Это, ИМХО, одна из самых раздражающих проблем Helm.
Если не удалось создать первую версию, каждая последующая попытка завершится с ошибкой, сообщающей о невозможности обновления из неизвестного состояния.
Следующий запрос на включение изменений «исправляет» ошибку, добавляя флаг --force
, что фактически просто маскирует проблему, выполняя команду helm delete & helm install —replace
.
Впрочем, в большинстве случаев, вам придется заняться полноценной чисткой релиза.
helm delete --purge $RELEASE_NAME
Error: release foo failed: timed out waiting for the condition
Если отсутствует ServiceAccount или RBAC не разрешает создание определенного ресурса, Helm вернет следующее сообщение об ошибке:
Error: release foo failed: timed out waiting for the condition
К сожалению, первопричину этой ошибки увидеть невозможно:
kubectl -n foo get events --sort-by='{.lastTimestamp}'
Error creating: pods "foo-5467744958" is forbidden: error looking up service account foo/foo: serviceaccount "foo" not found
Фейлы на ровном месте
В самых запущенных случаях Helm выдает ошибку, вообще не совершая каких-либо действий. Например, иногда он не обновляет ограничения ресурсов.
helm init запускает tiller с одной копией, а не в конфигурации HA
Tiller по умолчанию не предполагает высокую доступность, а запрос на включение изменений по ссылке все еще открыт.
Однажды это приведет к даунтайму...
Helm 3? Операторы? Будущее?
В следующей версии Helm будут добавлены некоторые многообещающие функции:
- односервисная архитектура без разделения на клиент и сервер. Больше никакого Tiller;
- встроенный движок Lua для написания скриптов;
- рабочий процесс DevOps на основе запросов на включение и новый проект Helm Controller.
Для получения дополнительной информации см. Предложения по проекту Helm 3.
Мне очень нравится идея архитектуры без Tiller, а вот скрипты на базе Lua вызывают сомнения, поскольку могут усложнить чарты.
Я заметил, что в последнее время популярность набирают операторы, которые гораздо больше подходят для Kubernetes, нежели чарты Helm.
Очень надеюсь, что коммьюнити в скором времени разберется с проблемами Helm (с нашей помощью, конечно), но сам я пока постараюсь как можно меньше использовать этот инструмент.
Поймите правильно: эта статья — мое личное мнение, к которому я пришел, создавая гибридную облачную платформу для развертываний на базе Kubernetes.