Learning Platform
Глоссарий Troubleshooting
Урок 15.06 · 23 мин
Средний
deploymentkuberneteshelmautoscaling

Trino на Kubernetes: Helm chart, graceful shutdown, автоскейлинг

В уроке про конфигурационные файлы мы развернули кластер вручную — написали etc-файлы, запустили процессы. Для постоянного продакшена так не делают: кластер живёт в оркестраторе, и для большинства команд это Kubernetes. Kubernetes управляет жизненным циклом нод, перезапускает упавшие поды, масштабирует кластер.

Но Trino на Kubernetes требует учитывать особенности обоих миров: эфемерность подов против требований к идентичности нод, остановка пода против незавершённых запросов. Этот урок — про развёртывание Trino в Kubernetes: официальный Helm chart, graceful shutdown воркеров и горизонтальное автомасштабирование.


Официальный Helm chart

Helm — пакетный менеджер Kubernetes; Helm chart — шаблонизированный пакет, разворачивающий приложение в кластер. У Trino есть официальный Helm chart (репозиторий trinodb/charts).

Docker Compose: управление многоконтейнерными приложениями

Chart берёт на себя то, что при ручном развёртывании делалось руками: создаёт под координатора и поды воркеров, генерирует для них конфигурационные файлы etc, настраивает сетевые сервисы, монтирует каталоги. Всё это параметризуется одним файлом — values.yaml.

Минимальный пример параметров:

# values.yaml для Trino Helm chart
coordinator:
  jvm:
    maxHeapSize: "16G"

worker:
  replicas: 4
  jvm:
    maxHeapSize: "48G"

server:
  workers: 4

additionalCatalogs:
  tpch: |
    connector.name=tpch

Установка и обновление — стандартными командами Helm:

helm repo add trino https://trinodb.github.io/charts
helm install trino-prod trino/trino -f values.yaml
NAME: trino-prod
LAST DEPLOYED: Wed May 20 12:40:11 2026
NAMESPACE: data
STATUS: deployed
REVISION: 1

Проверка состояния кластера:

kubectl get pods -l app.kubernetes.io/name=trino
NAME                                READY   STATUS    RESTARTS   AGE
trino-prod-coordinator-7c9d8b6-xk2p4  1/1   Running   0          2m
trino-prod-worker-5f6c7d9b-aq3m1      1/1   Running   0          2m
trino-prod-worker-5f6c7d9b-bv8n2      1/1   Running   0          2m
trino-prod-worker-5f6c7d9b-cw1p3      1/1   Running   0          2m
trino-prod-worker-5f6c7d9b-dx4q5      1/1   Running   0          2m
Helm chart разворачивает кластер Trino в Kubernetes
values.yamlПараметры развёртывания: число воркеров, heap координатора и воркеров, каталоги, ресурсы подов
helm install
Helm chartОфициальный chart trinodb/charts. Шаблонизирует манифесты Kubernetes из values.yaml
разворачивает
Под координатора + поды воркеровKubernetes создаёт поды, конфиги etc, сервисы. Координатор и воркеры объединяются в кластер

Эфемерные поды против идентичности нод

Вспомним правила из урока про конфигурационные файлы: node.environment обязан быть одинаковым на всех нодах кластера, а node.id — уникальным и стабильным между перезапусками.

В Kubernetes это сталкивается с природой подов. Поды эфемерны: Kubernetes свободно убивает и пересоздаёт их — при обновлении, при сбое узла, при масштабировании. Если бы каждый новый под получал случайный node.id, кластер на каждое пересоздание видел бы «новую» ноду, а прежнюю считал потерянной — учёт узлов поплыл бы.

Helm chart решает это за тебя. Он держит node.environment одинаковым для всего деплоймента, а уникальность node.id обеспечивает на уровне пода так, чтобы пересоздание пода не выглядело появлением чужого нового узла. Это одна из причин использовать официальный chart, а не собирать манифесты с нуля: тонкости стыковки эфемерных подов с требованиями Trino к идентичности уже учтены.


Graceful shutdown воркера

Самая важная Kubernetes-специфика — graceful shutdown воркера. Это прямое следствие того, что мы знаем про Trino из модуля про fault tolerance.

Проблема. Воркер исполняет задачи запросов. Kubernetes в любой момент может решить остановить под воркера — обновление деплоймента, освобождение узла, масштабирование вниз. Если просто резко убить под, все задачи на этом воркере оборвутся. А без FTE обрыв задачи роняет весь запрос — даже плановая остановка воркера убьёт идущие запросы пользователей.

Решение — graceful shutdown (корректное завершение). Вместо резкого убийства воркер останавливается по процедуре:

Graceful shutdown воркера: остановка без потери запросов
1. Воркер помечается как SHUTTING_DOWNВоркер переходит в состояние остановки. Координатор перестаёт назначать ему новые задачи
дренаж текущей работы
2. Воркер доисполняет уже идущие задачиВсе задачи, что уже выполняются на воркере, доводятся до конца. Новые не поступают — нагрузка дренируется
работа доделана
3. Под останавливаетсяТолько когда все задачи завершены, под действительно выключается. Идущие запросы не пострадали

Воркер сначала перестаёт принимать новые задачи (координатор больше их ему не шлёт), потом доисполняет уже идущие, и лишь затем под выключается. Идущие запросы не теряются — это и есть «корректное» завершение.

Чтобы это работало, Kubernetes и Trino должны быть согласованы. Kubernetes при остановке пода даёт ему grace period — время на корректное завершение перед принудительным убийством. Этот период должен быть достаточно длинным, чтобы воркер успел дренировать задачи. Если grace period короче времени дренажа, Kubernetes убьёт под недренированным, и смысл graceful shutdown потеряется.

WARNING

Termination grace period пода воркера должен быть согласован с реальной длительностью запросов. Если на кластере идут многоминутные запросы, а grace period — 30 секунд, Kubernetes оборвёт воркер посреди дренажа, и плановая остановка всё равно уронит запросы. Helm chart даёт настройку graceful shutdown воркеров; задавай grace period с запасом под самые долгие ожидаемые запросы.

Заметь связь с модулем про fault tolerance: graceful shutdown — это способ сделать плановую остановку безопасной без FTE. FTE спасает от внезапных сбоев; graceful shutdown — от предсказуемых остановок (обновление, масштабирование). Это два разных инструмента под два разных класса событий.


Горизонтальное автомасштабирование

Нагрузка на Trino неравномерна: днём — пик запросов, ночью — затишье, у batch-кластера всё наоборот. Держать постоянно максимальное число воркеров расточительно, постоянно минимальное — узко в пик. Решение — горизонтальное автомасштабирование: Kubernetes сам меняет число подов воркеров под текущую нагрузку.

Базовый механизм Kubernetes для этого — Horizontal Pod Autoscaler (HPA): он смотрит на метрику (например, загрузку CPU подов) и добавляет или убирает реплики воркеров, удерживая метрику в целевом диапазоне. Пошёл наплыв запросов, CPU воркеров вырос — HPA добавляет воркеров; нагрузка спала — убирает.

Автомасштабирование: число воркеров следует за нагрузкой
Низкая нагрузкаЗапросов мало, метрика ниже целевой. Автоскейлер держит минимум воркеров — не платим за простой
нагрузка выросла
Пик нагрузкиНаплыв запросов, метрика выше целевой. Автоскейлер добавляет реплики воркеров под спрос
нагрузка спала
Снова затишьеЗапросов снова мало. Автоскейлер убирает лишние воркеры — но только через graceful shutdown, чтобы не оборвать запросы

Ключевой нюанс — масштабирование вниз. Когда автоскейлер убирает воркер, под этого воркера останавливается. И тут снова работает graceful shutdown: убираемый воркер обязан корректно дренировать свои задачи, а не оборваться. Автомасштабирование и graceful shutdown — связка: без корректного завершения каждое уменьшение числа воркеров роняло бы запросы.

NOTE

Помимо базового HPA по CPU существуют и более продвинутые подходы к автоскейлингу Trino — например, масштабирование по событийным метрикам через KEDA, реагирующее на саму очередь запросов, а не только на CPU. Принцип общий: метрика нагрузки -> решение о числе реплик -> добавление или (через graceful shutdown) корректное убирание воркеров. Конкретику автоскейлинга сверяй с документацией Helm chart своей версии.


Картина развёртывания Trino на Kubernetes

Соберём урок воедино. Продакшен-Trino на Kubernetes стоит на трёх опорах:

  1. Официальный Helm chart — разворачивает кластер из values.yaml, генерирует конфиги, и, что важно, корректно стыкует эфемерность подов с требованиями Trino к node.id и node.environment.
  2. Graceful shutdown воркеров — делает плановую остановку (обновление, масштабирование) безопасной: воркер дренирует задачи перед выключением; termination grace period согласован с длительностью запросов.
  3. Горизонтальное автомасштабирование — число воркеров следует за нагрузкой; масштабирование вниз работает только в связке с graceful shutdown.

Вместе это даёт кластер, который Kubernetes ведёт сам: разворачивает, обновляет без потери запросов, масштабирует под спрос — при условии, что особенности стыка Trino и Kubernetes учтены.


Попробуй сам

Разверни Trino в Kubernetes (понадобится локальный кластер — kind, minikube или k3s).

  1. Добавь Helm-репозиторий Trino и установи кластер с values.yaml: координатор плюс 2-3 воркера, каталог tpch. Проверь kubectl get pods — все поды в статусе Running.
  2. Подключись к координатору (через kubectl port-forward) и выполни пробный запрос по tpch.
  3. Проверь graceful shutdown: запусти достаточно долгий запрос и во время его исполнения уменьши число воркеров (helm upgrade с меньшим replicas или удали под воркера). Понаблюдай, дренирует ли воркер задачи перед остановкой и переживает ли запрос плановое уменьшение кластера.
  4. Поразмышляй: если на кластере бывают запросы по 10 минут, какой termination grace period ты зададишь подам воркеров и почему слишком короткий период обесценит graceful shutdown.

Цель — увидеть Trino под управлением Kubernetes и прочувствовать, почему graceful shutdown обязателен для безопасного обновления и автоскейлинга.


Проверка знанийKnowledge check
Зачем воркеру Trino в Kubernetes нужен graceful shutdown, и почему termination grace period пода должен быть согласован с длительностью запросов? Как graceful shutdown связан с автомасштабированием?
ОтветAnswer
Graceful shutdown нужен потому, что Kubernetes-поды эфемерны — Kubernetes в любой момент может остановить под воркера при обновлении деплоймента, освобождении узла или масштабировании вниз. Воркер при этом исполняет задачи запросов, а без FTE обрыв задачи роняет весь запрос. Если просто резко убить под воркера, все идущие на нём задачи оборвутся, и даже плановая остановка убьёт запросы пользователей. Graceful shutdown делает остановку корректной: воркер сначала помечается как останавливающийся и перестаёт принимать новые задачи (координатор больше их ему не шлёт), потом доисполняет уже идущие задачи, и лишь затем под выключается — идущие запросы не теряются. Termination grace period должен быть согласован с длительностью запросов, потому что это время, которое Kubernetes даёт поду на корректное завершение перед принудительным убийством. Если grace period короче, чем нужно воркеру на дренаж задач — например, период 30 секунд, а на кластере идут многоминутные запросы, — Kubernetes оборвёт под посреди дренажа, и смысл graceful shutdown потеряется: плановая остановка всё равно уронит запросы. Поэтому grace period задают с запасом под самые долгие ожидаемые запросы. С автомасштабированием graceful shutdown связан напрямую через масштабирование вниз: когда автоскейлер решает убрать лишний воркер при спаде нагрузки, под этого воркера останавливается, и убираемый воркер обязан корректно дренировать свои задачи, а не оборваться. Без graceful shutdown каждое уменьшение числа воркеров роняло бы запросы — поэтому автомасштабирование и graceful shutdown работают только в связке. При этом graceful shutdown и FTE решают разные задачи: graceful shutdown делает безопасными предсказуемые, плановые остановки (обновление, масштабирование), а FTE спасает от внезапных сбоев — это два разных инструмента под два разных класса событий.

Проверьте понимание

Результат: 0 из 0
Концептуальный
Вопрос 1 из 4. Почему официальный Helm chart Trino полезнее, чем сборка манифестов Kubernetes с нуля, в части идентичности нод?

Закончили урок?

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

Войдите чтобы оценить урок

Прогресс модуля
0 из 7