Helm 3 alpha: прощай, Tiller - первый взгляд на tillerless-деплои
CNCF анонсировала Helm 3 с удалением Tiller: тестируем alpha-сборку, смотрим на RBAC без service account с cluster-admin и client-side рендеринг чартов.
Helm 3 alpha - CNCF объявила об удалении Tiller и переходе на client-side рендеринг как официальную архитектуру следующей версии
В сообществе CNCF наконец зафиксировали то, о чём инженеры шептались на конференциях последние полтора года: Helm 3 выйдет без Tiller. Официально. В alpha-сборке это уже можно потрогать руками, что мы и сделали.
Новость хорошая. Мы работаем с Helm 2 во всех managed-проектах, и Tiller - это тот компонент, вокруг которого у нас накопилось больше всего «ну и ладно, так сойдёт» решений, которые на самом деле не сойдут.
Почему Tiller был проблемой
Если кратко: Tiller - это серверный компонент Helm 2, который живёт в кластере как Deployment в namespace kube-system и выполняет реальные операции с ресурсами Kubernetes по команде клиента. Звучит разумно, пока не думаешь о правах.
Чтобы Tiller мог создавать что угодно в любом namespace - а именно это нужно для нормальной работы - ему нужен ServiceAccount с правами cluster-admin. Это значит, что любой, кто может достучаться до gRPC-порта Tiller внутри кластера, имеет полный контроль над кластером. Не над namespace, не над конкретными ресурсами - над всем кластером.
В теории можно ограничить Tiller на уровне RBAC, запустить отдельный экземпляр на каждый namespace, завязать TLS. Это называется «Tiller с ограниченными правами» и выглядит примерно как обезвредить гранату, завязав её в носок. Мы пробовали. Это долго, хрупко, и при обновлении Helm что-нибудь обязательно ломается.
Фактически в большинстве кластеров Tiller стоит с cluster-admin и живёт так, потому что иначе слишком больно. И это знают все.
Что изменится в Helm 3
Client-side рендеринг. Helm 3 рендерит манифесты локально, на машине инженера или в CI-агенте, и напрямую применяет их через Kubernetes API - точно так же как kubectl apply. Никакого серверного посредника.
RBAC становится прозрачным. Права на деплой теперь определяются правами того, кто запускает helm install - то есть kubeconfig и ServiceAccount пользователя или пайплайна. Хотите дать команде разработки права только на staging namespace - выдаёте нормальный RBAC-биндинг, и это работает без дополнительных телодвижений. Никакого Tiller с отдельными настройками на каждый namespace.
Хранение состояния. Вместо ConfigMap-ов в kube-system под управлением Tiller, Helm 3 хранит релизы как Secret-ы в том же namespace, где живёт приложение. Это разумнее - права на чтение релизов привязаны к namespace, а не выданы глобально всему что умеет обращаться к Tiller.
Что мы потрогали в alpha
Alpha-сборка доступна, мы взяли несколько наших стандартных чартов и прогнали через неё. Впечатления:
helm installбез--name. В Helm 3 имя релиза - обязательный позиционный аргумент, а не флаг. Мелочь, но надо переписать все скрипты.- Скорость. Деплой заметно быстрее - нет round-trip до Tiller, нет ожидания gRPC. На крупных чартах разница ощутима.
helm templateработает идентично. Рендеринг чартов для превью или передачи в ArgoCD - без изменений. Это хорошо, потому что мы именно так и используем его в CI.- Хуки работают.
pre-install,post-upgrade- всё срабатывает. ArgoCD, который сам запускаетhelm templateбез хуков, тут в стороне, но для прямых деплоев черезhelm installвсё на месте.
Что сломалось: несколько чартов использовали helm get с форматом вывода, который изменился в API. Это alpha, ожидаемо.
Про RBAC на практике
Это, пожалуй, самый ощутимый сдвиг. Когда мы разбирали RBAC-харденинг в январе, одним из неудобных мест был как раз Tiller - невозможно было нормально ограничить его права не сломав при этом половину деплоев.
Теперь схема выглядит так: CI-пайплайн получает ServiceAccount с правами только на конкретный namespace, запускает helm install, и Kubernetes сам применяет манифесты с правами этого ServiceAccount. Если чарт пытается создать ClusterRole - это провалится, потому что у пайплайна нет прав на кластерные ресурсы. Никакого обходного пути через привилегированный Tiller.
Это именно то, как это должно работать. Принцип минимальных привилегий не требует отдельного танца с Tiller-ом на каждый namespace.
Текущее состояние
Alpha есть alpha. В продакшн мы это не несём, но в тестовых кластерах уже гоняем регулярно. Полноценный релиз Helm 3 - вопрос нескольких месяцев по ощущениям, API ещё стабилизируется.
Основной вопрос сейчас - миграция существующих Helm 2 релизов. Там будет отдельный инструментарий, судя по обсуждениям в репозитории, но пока его нет. Переезд придётся планировать аккуратно, особенно если релизов много и они в разных namespace-ах.
Tiller не жалко.
- ArgoCD 0.x: GitOps-контроллер для Kubernetes, первое знакомство · 14 января 2019
- Kubernetes RBAC-харденинг: убираем wildcard-биндинги и включаем audit-log · 10 января 2019