Маршрутизация LLM в Kubernetes: как работает расширение Inference Extension для Gateway API
Развитие генеративного ИИ ставит перед инфраструктурными командами вызовы масштабирования. Традиционные балансировщики (например, Round-Robin) исходят из допущения, что все поды взаимозаменяемы и не сохраняют состояние (stateless). Однако бэкенды для обслуживания больших языковых моделей (LLM) являются стейтфул-системами (stateful), привязанными к ресурсам GPU. Каждый под инференса хранит в VRAM (VRAM) веса модели, кэши токенов (KV-cache) и LoRA-адаптеры (надстройки для конкретных задач). Неверная балансировка ведет к росту времени генерации первого токена (TTFT, Time to First Token), задержкам загрузки адаптера и перерасходу памяти.
Проблема «слепой» балансировки в эру генеративного ИИ
Традиционная маршрутизация распределяет запросы без оглядки на состояние приложения. Для LLM-инференса это неэффективно по трем причинам:
- Локальность KV-кэша (Cache Locality). При инференсе LLM модель генерирует токены последовательно. Для сохранения контекста диалога сервер кэширует промежуточные состояния активаций предыдущих токенов (KV-кэш). Если последующий запрос от того же пользователя попадет на другой под, кэш придется вычислять заново (prefill), что увеличит TTFT и создаст дополнительную нагрузку на GPU.
- LoRA-адаптеры. Для адаптации одной базовой LLM под разные задачи используются микро-модели LoRA. Базовая модель лежит в VRAM постоянно, а нужный адаптер динамически загружается в VRAM. Если балансировщик отправляет запрос на под, где данный адаптер еще не загружен, происходит задержка на чтение с диска и выделение VRAM.
- Неравномерное время выполнения. Длина ответов LLM непредсказуема, поэтому одни поды могут быть перегружены длительными вычислениями, в то время как другие простаивают.
Расширение Gateway API Inference Extension решает эту задачу нативно, встраивая интеллектуальную маршрутизацию в сетевой слой платформы.
Архитектурный сдвиг: переход от Service к InferencePool
Gateway API — это стандарт Kubernetes для управления входящим трафиком, пришедший на смену Ingress. Расширение Inference Extension дополняет его концепциями для работы с искусственным интеллектом.
Вместо направления трафика на стандартный Kubernetes Service, входящий запрос сопоставляется с ресурсом InferencePool. Это ключевая абстракция расширения, описывающая группу подов, на которых запущены серверы моделей (например, vLLM, Triton Inference Server или Hugging Face TGI). InferencePool содержит метрики и параметры целевых моделей.
Процесс обработки запроса выглядит следующим образом:
- Запрос поступает на шлюз (Inference Gateway) на базе Envoy или аналогичного прокси.
- Шлюз анализирует правила
HTTPRouteи с помощью компонента Body-Based Router (BBR) извлекает имя целевой модели и параметры сессии из URL, HTTP-заголовков или тела JSON-запроса (например, из поляmodelв API-запросе OpenAI). - Шлюз обращается к планировщику инференса (Inference Scheduler или Endpoint Picker), чтобы определить наиболее подходящий под в рамках ассоциированного
InferencePool. - Endpoint Picker, используя телеметрию от подов, выбирает оптимальный эндпоинт и перенаправляет запрос.
Отметим эволюцию проекта: компоненты маршрутизации по телу запроса (BBR), планировщик (EPP) и приоритизация трафика (InferenceObjective) вынесены в репозитории проекта llm-d под эгидой CNCF. Базовый репозиторий Gateway API Inference Extension сфокусирован на легкой реализации EPP, спецификации API InferencePool и conformance-тестах.
Метрики и сигналы для умной маршрутизации
Чтобы принять правильное решение о направлении запроса, планировщик должен анализировать состояние серверов моделей. Традиционные проверки готовности (Readiness Probes) здесь бесполезны. Вместо этого расширение использует телеметрию, собираемую непосредственно с движков инференса.
Главными сигналами для маршрутизации выступают:
- Глубина локальной очереди (Local Queue Depth): количество запросов, которые уже ожидают обработки на конкретном поде. Планировщик стремится минимизировать дисбаланс очередей (queue depth imbalance).
- Наличие LoRA-адаптера: если под уже держит в памяти нужный LoRA-адаптер, запрос будет отправлен именно на него, чтобы избежать «холодного старта».
- Локальность KV-кэша (Cache Locality): планировщик отслеживает хэши префиксов промптов. Если под уже обрабатывал этот диалог, повторный запрос направляется туда же, максимизируя KV Cache Hit Rate.
- Ограничения размера (Capacity Limits): если размер входящего контекста превышает свободную емкость KV-кэша, планировщик отбрасывает запрос с кодом
413 Payload Too Largeили ищет под с большим объемом свободной VRAM.
Flow Control и централизованные очереди
В Inference Extension шлюз буферизует запросы. При высокой нагрузке они оседают в центральной очереди шлюза и передаются на поды по мере их освобождения. Это решает проблему «шумных соседей» (noisy neighbors) и поддерживает высокую утилизацию GPU без перегрузки инстансов.
При перегрузке (saturation) шлюз сбрасывает избыточную нагрузку (Load Shedding) по политикам InferenceObjective. Интерактивные запросы (чат-боты) получают приоритет над фоновыми задачами (например, bulk summarization). Фоновый трафик задерживается в очереди или отклоняется с кодами 429 или 503. Для фоновых вычислений центральная очередь также делает жизнеспособной концепцию масштабирования до нуля (Scale-to-Zero). Первые запросы не падают по таймауту, а безопасно ожидают в очереди шлюза, пока Kubernetes запускает новые поды и выделяет им GPU.
Практический чек-лист по внедрению
Для развертывания интеллектуальной маршрутизации LLM в вашем кластере Kubernetes используйте следующий пошаговый план:
- Подготовка инфраструктуры кластера (Prerequisites):
- Убедитесь, что кластер использует Kubernetes v1.29+.
- Проверьте наличие LoadBalancer и активируйте поддержку sidecar-контейнеров (Native Sidecars, стандарт в K8s v1.29+) для развертывания серверов моделей.
- Выбор и установка шлюза:
- Выберите шлюз с поддержкой механизма внешнего контроля трафика
ext_proc(External Processing): Envoy Gateway, kgateway или GKE Gateway.
- Выберите шлюз с поддержкой механизма внешнего контроля трафика
- Развертывание серверов моделей и описание InferencePool:
- Разверните поды с LLM-движком (vLLM) и агентом сбора телеметрии. Опишите манифест
InferencePool, указав селекторы подов и параметры моделей.
- Разверните поды с LLM-движком (vLLM) и агентом сбора телеметрии. Опишите манифест
- Настройка извлечения модели (Model Extraction Routing):
- Сконфигурируйте правила
HTTPRouteдля разбора входящих HTTP-запросов. Настройте извлечение идентификатора модели из заголовков (например,X-Model-Name), пути запроса (например,/v1/models/gpt-4o) или тела запроса (body-based routing).
- Сконфигурируйте правила
- Интеграция планировщика (Endpoint Picker):
- Подключите планировщик (EPP) к шлюзу через интерфейс
ext_procдля распределения трафика.
- Подключите планировщик (EPP) к шлюзу через интерфейс
- Настройка сквозного мониторинга и верификация:
- Настройте сбор метрик. Отслеживайте распределение запросов по моделям, сигналы планировщика, HTTP-коды ответов, TTFT, KV Cache Hit Rate, дисбаланс очередей (queue depth imbalance), количество сброшенных запросов (shedding events 429/503), использование VRAM и здоровье физических нод.
- Тестирование аварийных сценариев (Failure Modes):
- Проведите симуляцию сбоев: отправьте запрос с несуществующим LoRA-адаптером, перегрузите пул для проверки сброса нагрузки (shedding), сымитируйте устаревание метаданных маршрутизации.
Ограничения и эксплуатационные риски
Несмотря на преимущества, использование Inference Extension сопряжено с рисками, которые необходимо учитывать при проектировании продакшн-систем.
Основное слабое место планировщика — актуальность телеметрии. При высокой интенсивности планировщик принимает решения на основе метрик, полученных с задержкой. В пиковые моменты это может привести к лавине: EPP видит под с нужным KV-кэшем и направляет туда все запросы. Если телеметрия не поспевает за потоком, под мгновенно переполняет свою локальную очередь, превращая кэш-локальность в проблему емкости (capacity problem).
Второй важный аспект — ограничения концепции масштабирования до нуля (Scale-to-Zero). В классическом веб-серверном окружении под запускается за доли секунды. Для LLM это невозможно: запуск контейнера, инициализация драйверов CUDA, выделение VRAM и копирование весов модели из сетевого хранилища в VRAM занимает от одной до нескольких минут. Поэтому для интерактивных сервисов реального времени масштабирование до нуля неприменимо. Данный механизм эффективен исключительно для пакетной фоновой обработки задач.
Реальная экономия ресурсов достигается только в том случае, если характер рабочей нагрузки позволяет эффективно утилизировать KV-кэш за счет повторных запросов пользователей в рамках одной сессии или если в кластере настроена динамическая работа с LoRA-адаптерами на общем пуле базовых моделей.

