ADG Оставить заявку
Блог DevOps 5 мин чтения

Helm 2.8: stable-репозиторий закрывает типовые задачи, но Tiller беспокоит

Внедряем Helm 2.8 для управления деплоем в Kubernetes: stable charts работают, но широкие права Tiller - реальная проблема для production-кластеров.

Контекст момента

Helm 2.8 - стабилизация chart-репозиториев и улучшенный Tiller RBAC

Helm 2.8 вышел в конце февраля, и мы наконец взялись за его нормальную обкатку на клиентских кластерах. Задача у нас конкретная: перестать деплоить приложения через голые kubectl apply -f и ворох самодельных bash-скриптов и перейти на что-то управляемое. Helm выглядит очевидным кандидатом - вопрос насколько stable-репозиторий реально закрывает потребности и что делать с Tiller.

Что принесла 2.8

Сам релиз без сенсаций. Две вещи, которые нас интересовали в первую очередь:

  • Улучшения в helm upgrade --wait. Флаг ждёт пока все поды из деплоя перейдут в Ready перед тем как отдать управление. В предыдущих версиях это работало ненадёжно - команда могла завершиться успешно пока поды ещё раскатывались. В 2.8 механика стала аккуратнее, хотя timeout по умолчанию всё ещё пять минут и его часто приходится поднимать.
  • Chart testing и стабилизация репозитория. Команда Helm проделала работу по унификации chart-ов в stable и incubator - появился официальный процесс ревью, CI-тесты для chart-ов. Это видно по качеству: chart-ы стали чуть предсказуемее.

Плюс привычные мелочи: улучшенный вывод helm status, доработки в helm lint, несколько исправлений в логике rollback.

Stable-репозиторий: что реально работает

Честно говоря, мы ожидали больше возни. stable-репозиторий в 2.8 неплохо покрывает типовой стек:

  • nginx-ingress - ставится с первого раза, параметры через values достаточно гибкие чтобы не лезть патчить chart руками. Аннотации для ingress-объектов пробрасываются нормально.
  • Prometheus и grafana - отдельные chart-ы, разворачиваются без сюрпризов. Интеграция между ними через values нормальная, хотя придётся потратить час на понимание какие именно значения за что отвечают.
  • PostgreSQL - chart от stable достаточен для dev/test. Для production мы бы смотрели внимательнее на параметры persistence и resource limits - defaults явно рассчитаны на что-то скромное.
  • redis - аналогично, sentinel-режим есть, но требует внимательной настройки.

Incubator честнее - chart-ы там разного уровня зрелости, некоторые явно написаны «чтобы было». Прежде чем брать что-то из incubator в production - читать chart руками, не надеяться на автопилот.

Главная ценность stable-репозитория не в том что он идеален, а в том что он даёт отправную точку. Вместо написания деплойментов, сервисов и configmap-ов с нуля - берёшь chart, смотришь какие values поддерживает, и либо используешь их либо делаешь fork и дорабатываешь под себя. Экономит время.

Tiller: вот где болит

Архитектура Helm 2 такая: Tiller - это серверный компонент, который живёт в кластере и от своего имени применяет манифесты через Kubernetes API. Проблема в том, что по умолчанию Tiller устанавливается с правами cluster-admin. Это значит что Tiller может делать в кластере буквально что угодно.

Для тестового кластера - ладно. Для production - это неприятно. Любой кто может взаимодействовать с Tiller получает возможность влиять на весь кластер, даже если у самого пользователя Kubernetes ограниченные права.

Официальный ответ на это - RBAC для Tiller. В 2.8 документация и helm init стали чуть лучше объяснять как это настраивать:

apiVersion: v1
kind: ServiceAccount
metadata:
  name: tiller
  namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: tiller
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
  - kind: ServiceAccount
    name: tiller
    namespace: kube-system

Затем helm init --service-account tiller. Это стандартная рекомендация - создать отдельный ServiceAccount и привязать к нему роль.

Но подождите: мы только что привязали cluster-admin к ServiceAccount Tiller. Мы ничего не улучшили с точки зрения прав - Tiller по-прежнему может всё. Разница только в том что теперь это явно задокументировано в YAML, а не происходит по умолчанию. Это лучше чем совсем без ServiceAccount, но проблему не решает.

Более правильный подход - namespace-ограниченный Tiller: отдельный Tiller на каждый namespace, с правами только на этот namespace. Технически это возможно, но тогда теряется часть удобства: у вас несколько Tiller-экземпляров, и helm нужно явно указывать с каким работать через --tiller-namespace. Это неудобно и люди об этом забывают.

На наших managed-кластерах мы пока остановились на компромиссе: Tiller с cluster-admin, но в отдельном namespace, с ограниченным сетевым доступом и мониторингом кто и что через него деплоит. Неидеально, честно признаём.

Release management: что работает хорошо

Отвлечёмся от безопасности - там где Helm реально удобен, это управление релизами. helm history, helm rollback, helm diff (плагин) - это то с чем голые манифесты не конкурируют.

Типичный сценарий: деплоим новую версию приложения, что-то идёт не так, делаем helm rollback app 2 и через тридцать секунд кластер откатился к предыдущему состоянию. Причём Helm помнит историю - helm history app показывает все ревизии с временными метками и статусами. Для разбора инцидентов это полезно.

helm diff - отдельная радость. Плагин показывает что именно изменится в кластере перед применением upgrade - diff манифестов. Ревью деплоев стало понятнее.

Где мы сейчас

На двух клиентских кластерах Helm уже в работе. Типовые компоненты (nginx-ingress, prometheus, grafana) - через stable chart-ы, собственные приложения - через самописные chart-ы в git-репозитории.

Вопрос с Tiller остаётся открытым. Мы следим за дискуссиями в сообществе - там активно обсуждаются альтернативные подходы, в том числе идеи убрать Tiller из архитектуры совсем и сделать Helm чисто клиентским инструментом. Пока это обсуждения, не релизы - но направление понятно и разумное.

Пока работаем с тем что есть: Helm 2.8 решает реальные проблемы управления деплоем, но с Tiller нужно осознанно работать, а не принимать defaults как данность.

Контакт

Нужна такая же инженерная работа?

Опишите задачу и контекст. Ответим в течение рабочего дня, при необходимости подпишем NDA.