Паттерны Kubernetes для LLM-нагрузок: что меняется

Применение паттернов Kubernetes к нагрузкам с LLM

Как уже знакомые паттерны переносятся на LLM — и где у них появляются важные нюансы.

Несколько лет назад мы с Роландом Хуссом написали книгу Kubernetes Patterns — каталог повторно используемых решений для построения облачно-нативных (cloud-native) приложений на Kubernetes. Книга охватывает шесть категорий паттернов: фундаментальные, поведенческие, структурные, конфигурационные, безопасности и продвинутые — от проб работоспособности и init-контейнеров до контроллеров, операторов и эластичного масштабирования. Недавно Роланд вместе с Даниэле Зонкой написали новую книгу Generative AI on Kubernetes, посвящённую операционной стороне запуска больших языковых моделей (LLM) на Kubernetes. Я выступал рецензентом этой книги, и чем дальше я её читал, тем отчётливее узнавал паттерны из нашей оригинальной работы — только применённые к принципиально иному классу нагрузок. Deployment, StatefulSet, Init Container, DaemonSet — всё это было на месте. Просто с другим порядком цифр.

Ниже — краткий обзор того, как паттерны Kubernetes применяются к нагрузкам с LLM. Подробнее мы с Роландом разберём это на нашем предстоящем докладе на KubeCon + CloudNativeCon Europe 2026 в Амстердаме.

Тот же Kubernetes, другая нагрузка

Типичное облачно-нативное приложение на Kubernetes строится по хорошо известной схеме.

  • Ingress направляет HTTP-трафик к stateless-подам приложения, управляемым Deployment.

  • Init-контейнер выполняет миграции базы данных до старта приложения.

  • PostgreSQL работает как StatefulSet с постоянным хранилищем.

  • CronJob генерирует отчёты по расписанию.

  • Слой DaemonSet — например, Prometheus Node Exporter и Fluentd — обеспечивает мониторинг и сбор логов.

Итого шесть паттернов Kubernetes в действии: Controller, Stateless Service, Init Container, Stateful Service, Batch Job, Daemon Service.

Типовая архитектура облачно-нативного приложения на Kubernetes

Нагрузка с LLM использует те же паттерны, но представляет собой принципиально иной тип рабочей нагрузки.

Модель — это не бинарный файл приложения. Это десятки или сотни гигабайт выученных параметров, данные только для чтения, которые необходимо загрузить в память GPU, прежде чем сервер сможет обработать хотя бы один запрос. Llama 70B от Meta весит около 140 ГБ в полной точности (FP16) или 35–40 ГБ при 4-битном квантовании. Загрузка занимает минуты, а не секунды.

Модели требуется специальное железо: узел с нужным GPU, достаточный объём VRAM (Video RAM — память на GPU, где хранятся веса модели и промежуточные вычисления), а иногда и конкретная топология GPU-интерконнекта.

Инициализация тоже выглядит иначе. В традиционном приложении init-контейнер скачивает конфигурационный файл или выполняет миграцию — несколько мегабайт, дело секунд. В стеке с LLM аналогичный шаг загружает десятки или сотни гигабайт весов модели. После того как веса на месте, сервер модели (vLLM, TGI) проходит многофазный запуск: загружает веса в VRAM, компилирует CUDA-графы и предварительно выделяет KV-кэш (область памяти, где модель хранит вычисленные состояния механизма внимания, чтобы не пересчитывать их для каждого нового токена). Всё это занимает минуты. Ваш startup probe должен иметь failureThreshold: 60 при periodSeconds: 10 — то есть бюджет ожидания в 10 минут.

Профиль запросов тоже отличается. В традиционном веб-сервисе запросы имеют примерно одинаковую стоимость, и балансировка по round-robin работает. LLM-инференс нарушает это допущение: запрос на 10 токенов выполняется за 200 мс, а запрос на 4 000 токенов занимает GPU на 30 секунд. При этом оба приходят как идентичные запросы POST /v1/chat/completions. Round-robin создаёт горячие точки.

Сигналы для масштабирования тоже перестают работать. Стандартный HPA по CPU плохо подходит для GPU-инференса. Нужно масштабирование по метрикам, специфичным для LLM: глубина очереди токенов (vllm:num_requests_waiting), время до первого токена (time-to-first-token), утилизация KV-кэша.

Масштабирование до нуля (scale-to-zero) практически нереализуемо, когда загрузка модели занимает пять минут.

Меняется и инфраструктурный слой. Вместо Node Exporter и Fluentd теперь запускаются: NFD (Node Feature Discovery) для маркировки железа, GFD (GPU Feature Discovery) для добавления меток модели GPU и объёма VRAM, NVIDIA device plugin для предоставления nvidia.com/gpu как планируемого ресурса и DCGM exporter (Data Center GPU Manager) для передачи GPU-метрик в Prometheus. Это ваш новый стек DaemonSet, формирующий GPU-инфраструктурный слой.

Такие проекты, как KServe (инкубируется в CNCF), решают эти задачи, применяя паттерн Controller к обслуживанию моделей. Вы описываете InferenceService CRD, декларируете модель, среду выполнения и политику масштабирования — а KServe выполняет согласование: создаёт Deployment, Service, инициализатор хранилища, настраивает startup-пробы и планирование на GPU.

Несмотря на всё это, фундамент остаётся прежним. Controller, Stateless Service, Init Container, Stateful Service, Batch Job, Daemon Service — все паттерны на месте. Параметры изменились, но паттерны выдержали.

Что остаётся неизменным в GenAI на Kubernetes

Многие паттерны Kubernetes применяются к нагрузкам с LLM без принципиальных изменений. Паттерн работает как есть — его просто нацеливают на другую нагрузку.

Таблица прямых соответствий паттернов Kubernetes для GenAI-нагрузок

Это прямые соответствия. Примитив Kubernetes остаётся тем же, но нагрузка за ним меняется: веб-приложения и базы данных уступают место серверам моделей, векторным базам данных и GPU-инфраструктуре.

Что меняется в GenAI на Kubernetes

Эти паттерны по-прежнему применимы к GenAI, но кое-что принципиальное в их работе меняется. Скелет паттерна остаётся прежним, однако параметры, масштаб или семантика выходят за рамки изначального замысла.

Таблица паттернов Kubernetes

Именно здесь LLM-нагрузки начинают растягивать привычные паттерны Kubernetes. Абстракция ещё держится, но операционная реальность меняется. Секунды становятся минутами. Мегабайты становятся гигабайтами. CPU-центричные допущения перестают работать.

Новые паттерны для AI-нагрузок

Некоторые паттерны не имеют явных предшественников в каталоге Kubernetes Patterns. Они возникают из специфики LLM-нагрузок.

Model Data Staging решает задачу доставки сотен гигабайт весов модели в поды без превращения каждого масштабирования в многоминутный простой.

Token-Aware Routing заменяет round-robin на маршрутизацию, основанную на метриках: глубине очереди и состоянии KV-кэша конкретного эндпоинта. Этот подход реализуется через Gateway API Inference Extension и проекты вроде llm-d.

RAG Composition связывает воедино четыре разных типа нагрузки в одно связное приложение: оркестратор, LLM, векторная база данных и конвейер индексации. Каждый компонент естественно отображается на свой примитив Kubernetes.

Disaggregated Serving разделяет вычислительно-интенсивную фазу prefill и память-интенсивную фазу decode, запускает их на разном железе и позволяет масштабировать независимо. Этот подход реализуют такие проекты, как llm-d.

Agentic Workflows вводят LLM-агентов, которые планируют, используют инструменты и работают итеративно. Они также стимулируют появление новых протоколов: MCP (Model Context Protocol) для интеграции агентов с инструментами и A2A (Agent-to-Agent Protocol) для коммуникации между агентами.

Все эти паттерны подробно разобраны в книге Роланда и Даниэле Generative AI on Kubernetes. На KubeCon Amsterdam мы с Роландом разберём три из них: Model Data Staging, Token-Aware Routing и RAG Composition.

Обложка книги Generative AI on Kubernetes
© 2026 meganuke