Как развернуть модели искусственного интеллекта в Kubernetes с помощью KServe и nxs-universal-chart
Гайд по созданию инфраструктуры для запуска моделей ИИ в Kubernetes с помощью nxs-universal-chart
Для запуска обученной ML-модели в Kubernetes необходима инфраструктура, которая обеспечивает маршрутизацию трафика, выполнение инференса, автоматическое масштабирование, безопасную передачу учётных данных и мониторинг.
Каждый из этих компонентов может требовать отдельного Helm-чарта, собственных CRD и документации. nxs-universal-chart позволяет описать необходимые ресурсы в одном values.yaml и управлять ими в рамках единой конфигурации.
В этой статье рассмотрим, как собрать inference-контур на основе пяти Kubernetes-операторов и соответствующих субчартов nxs-universal-chart. Пример конфигурации занимает около 120 строк YAML.
Общая архитектура
Контур состоит из пяти слоёв, каждый из которых отвечает за отдельную функцию:
- Serving — KServe (nuc-kserve). Развёртывание модели через InferenceService и поддержка V2 Inference Protocol.
- Networking — Istio (nuc-istio). Маршрутизация внешнего трафика к предиктору с помощью Gateway и VirtualService, а также настройка защищённого взаимодействия между сервисами.
- Runtime — Knative (nuc-knative). Серверная среда выполнения, автоматическое масштабирование до нуля и управление ревизиями.
- Secrets — Vault Secrets Operator (nuc-vault-secret-operator). Передача учётных данных для загрузки модели из S3-совместимого хранилища с помощью ресурсов VaultConnection, VaultAuth и VaultStaticSecret.
- Monitoring — Kube Prometheus Stack (nuc-kube-prometheus-stack). Сбор метрик инференса и настройка оповещений через ServiceMonitor, PodMonitor и PrometheusRule.
Обзор технологий
Перед настройкой конфигурации рассмотрим назначение каждого компонента и его роль в inference-контуре.
Istio — управление сетевым трафиком
Istio — открытая платформа service mesh, интегрируемая с Kubernetes через прокси Envoy. В стандартной конфигурации service mesh каждый под получает дополнительный контейнер-прокси, через который проходит входящий и исходящий трафик.
Istio поддерживает взаимное TLS-шифрование (mTLS), гибкую маршрутизацию, в том числе canary-, A/B- и blue-green-развёртывания, а также сбор телеметрии без изменения кода приложения.
В рассматриваемом примере используются возможности Istio для управления входящим трафиком:
- Gateway определяет точку входа для внешних запросов и завершает TLS-соединение.
- VirtualService и DestinationRule задают правила маршрутизации к предиктору. При необходимости их можно расширить для canary-развёртывания, например направлять 90% запросов на версию модели v1 и 10% — на v2.
- AuthorizationPolicy ограничивает внешний доступ к API инференса: разрешает обращения к /v1/models/*, оставляя метрики и административные интерфейсы закрытыми.
Для более простых сценариев можно использовать Gateway API, поддерживаемый через субчарт nuc-native-gateway. Однако Istio широко применяется в inference-контурах благодаря исторической интеграции с KServe.
KServe — платформа для инференса ML-моделей
KServe предназначен для развёртывания моделей машинного обучения в Kubernetes. Основная абстракция — InferenceService: с её помощью задаются формат модели и путь к её артефактам, после чего KServe настраивает среду выполнения, сетевое взаимодействие и масштабирование.
KServe поддерживает два основных сценария:
- Predictive inference — обслуживание предсказательных моделей на основе sklearn, XGBoost, PyTorch, TensorFlow и других фреймворков. В примере используется InferenceService.
- Generative inference — обслуживание больших языковых моделей. Начиная с KServe v0.16 доступен LLMInferenceService с поддержкой vLLM и llm-d, включая KV-cache offloading, prefix caching и распределённое планирование.
Также предусмотрены два режима развёртывания:
- Standard — использование стандартных ресурсов Kubernetes, например Deployment. Для дополнительного автомасштабирования по пользовательским метрикам можно опционально установить KEDA.
- Knative — использование Knative для автоматического масштабирования на основе нагрузки.
Для генеративного инференса документация KServe рекомендует Standard-режим: он обеспечивает более прямой контроль над распределением ресурсов и предсказуемое масштабирование ресурсоёмких рабочих нагрузок. В этом примере используется Knative-режим, поскольку он поддерживает масштабирование до нуля.
Knative Serving — серверная среда выполнения
Knative Serving предоставляет серверную среду выполнения для Kubernetes с поддержкой масштабирования до нуля (scale-to-zero).
Когда запросов к модели нет, поды могут быть полностью удалены. При поступлении нового запроса компонент Activator буферизирует его и передаёт сигнал механизму автомасштабирования, который запускает под. Время от нуля до обработки запроса может составлять от нескольких секунд для моделей на CPU до минуты для GPU-моделей, которым требуется загрузить веса.
Такой подход помогает экономить ресурсы: например, нет необходимости постоянно держать GPU-узлы включёнными для модели, которая получает всего десять запросов в час.
Knative масштабирует поды с учётом количества одновременных запросов (concurrency) или числа запросов в секунду (RPS). Для инференса это может быть полезнее стандартного HPA, ориентированного на загрузку CPU и памяти.
KServe использует Knative как механизм масштабирования: при создании InferenceService автоматически появляется Knative Service. Дополнительно через nuc-knative можно развернуть собственный сервис для пользовательской среды выполнения — например, для предварительной и последующей обработки данных, последовательного выполнения нескольких моделей или вспомогательных операций.
Vault Secrets Operator — безопасное управление секретами
HashiCorp Vault предназначен для хранения секретов, управления шифрованием и предоставления доступа на основе идентификации. В рассматриваемом контуре используется Vault Secrets Operator — оператор Kubernetes, который синхронизирует данные из Vault с объектами Kubernetes Secret.
Для загрузки артефакта модели из S3-совместимого хранилища KServe использует компонент storage initializer, которому необходимы учётные данные. Хранить их непосредственно в Git, даже в зашифрованном виде с помощью SOPS, нежелательно.
Вместо этого секреты хранятся в Vault, а Vault Secrets Operator создаёт и обновляет Kubernetes Secret при изменении данных. Доступ к конкретным секретам регулируется политиками Vault.
Для аутентификации используется Kubernetes auth method. Такой подход не требует долгоживущих токенов в переменных CI/CD: токен ServiceAccount ротируется автоматически, а Vault выдаёт токен с ограниченным временем жизни.
Prometheus — мониторинг и оповещения
Prometheus — стандартный инструмент мониторинга в Kubernetes. Prometheus Operator упрощает его настройку с помощью CRD: вместо ручного редактирования prometheus.yml можно создавать ресурсы ServiceMonitor, PodMonitor и PrometheusRule.
Мониторинг необходим для контроля качества работы моделей: без метрик ухудшение времени ответа может остаться незамеченным до появления жалоб пользователей.
В примере предусмотрен сбор метрик на двух уровнях:
- ServiceMonitor собирает метрики через Service.
- PodMonitor обращается непосредственно к подам. Это важно для Knative, где поды динамически создаются и удаляются.
Для контроля задержки инференса используется PrometheusRule, в котором задаются правила оповещения на основе P99 latency — 99-го перцентиля времени ответа.
Как проходит запрос через inference-контур
Последовательность взаимодействия компонентов:
- Клиентский запрос поступает на Istio Gateway и маршрутизируется с помощью VirtualService.
- Запрос передаётся в KServe InferenceService, а затем — в под Knative.
- Vault Secrets Operator получает учётные данные из Vault и автоматически создаёт Kubernetes Secret, необходимый для загрузки модели из S3.
- Prometheus собирает метрики компонентов через ServiceMonitor и другие настроенные ресурсы мониторинга.
После определения архитектуры можно переходить к настройке ресурсов.
Предварительные требования
Предполагается, что в кластере Kubernetes уже установлены следующие операторы и соответствующие CRD:
- Istio;
- KServe Controller версии 0.14 или новее;
- Knative Serving версии 1.12 или новее;
- Vault Secrets Operator версии 0.5 или новее;
- Kube Prometheus Stack.
Также в Kubernetes должен быть установлен Vault.
Настройка установки перечисленных компонентов в эту инструкцию не входит: подробные руководства доступны в документации соответствующих проектов.
После установки зависимостей разверните nxs-universal-chart командой:
helm install ai-mesh oci://registry.nixys.ru/nuc/nxs-universal-chart \
-f values.yaml \
--version 3.0.17
Далее разберём основные секции values.yaml, которые описывают inference-контур.
Полный values.yaml с разбором
Общие настройки:
Зададим имя, которое будет использоваться для формируемых ресурсов:
nameOverride: ai-mesh
Параметр nameOverride задаёт базовое имя генерируемых ресурсов. Вместо длинных имён вида release-name-nxs-universal-chart-... будут использоваться имена с префиксом ai-mesh-.
Слой 1. Istio — маршрутизация и авторизация
nuc-istio:
enabled: true
gateways:
inference:
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- ai-mesh.example.local
virtualservices:
inference:
spec:
hosts:
- ai-mesh.example.local
gateways:
- inference
http:
- route:
- destination:
host: predictor.default.svc.cluster.local
port:
number: 80
destinationrules:
predictor:
spec:
host: predictor.default.svc.cluster.local
authorizationpolicies:
inference:
spec:
selector:
matchLabels:
app: predictor
rules:
- to:
- operation:
paths:
- /v1/models/*Конфигурация создаёт четыре ресурса Istio:
- Gateway задаёт точку входа для внешнего трафика. Он привязывается к существующему istio-ingressgateway и принимает HTTP-запросы на порту 80 для хоста ai-mesh.example.local. В производственной среде можно добавить завершение TLS с помощью cert-manager и субчарта nuc-certificates.
- VirtualService определяет правила маршрутизации: весь трафик, поступающий на ai-mesh.example.local через Gateway inference, направляется к сервису предиктора. Для canary-развёртывания здесь можно задать веса маршрутов с помощью параметра weight.
- DestinationRule описывает политики соединений. В минимальной конфигурации он объявляет адрес назначения. В производственной среде можно добавить trafficPolicy.tls.mode: ISTIO_MUTUAL, чтобы включить mTLS.
- AuthorizationPolicy управляет доступом к API. Политика разрешает обращения к эндпоинтам /v1/models/*, соответствующим V2 Inference Protocol. Остальные пути, включая проверки состояния, метрики и административные эндпоинты, остаются закрытыми для внешних клиентов.
Слой 2. KServe — запуск модели
nuc-kserve:
enabled: true
inferenceServices:
predictor:
spec:
predictor:
model:
modelFormat:
name: sklearn
storageUri: s3://models/predictor
Параметр modelFormat.name: sklearn указывает KServe использовать встроенную среду обслуживания моделей sklearn на базе MLServer. Помимо sklearn, KServe поддерживает PyTorch, TensorFlow, XGBoost, Hugging Face и другие фреймворки.
Параметр storageUri: s3://models/predictor указывает путь к артефакту модели в S3-совместимом хранилище. Перед запуском контейнера обслуживания KServe использует storage initializer, который скачивает модель. Для доступа к хранилищу требуются учётные данные, которые в следующем слое будут получены из Vault.
При развёртывании KServe автоматически создаёт ресурсы, необходимые для работы в режиме Knative:
- Knative Service для серверного выполнения и масштабирования;
- Revision для управления версиями;
- Route для распределения трафика между версиями;
- Service и VirtualService для организации доступа.
Слой 3. Knative — дополнительная среда выполнения
nuc-knative:
enabled: true
services:
runtime:
spec:
template:
spec:
containers:
- image: ghcr.io/nixys/inference-runtime:latest
Knative Service описывает дополнительную серверную нагрузку с поддержкой автоматического масштабирования до нуля. При отсутствии запросов поды удаляются, а при поступлении первого запроса Knative Activator буферизирует его и инициирует запуск пода.
В данном примере runtime — дополнительный сервис для пользовательской среды выполнения инференса. Если модель обслуживается стандартной средой KServe, например для sklearn, PyTorch или TensorFlow, этот блок можно не использовать.
Дополнительный Knative Service может понадобиться для:
- пользовательских конвейеров предварительной и последующей обработки данных (pre/post-processing);
- ансамблей моделей, в которых несколько моделей работают последовательно;
- вспомогательных контейнеров и сервисов для обогащения признаков, журналирования и трассировки.
Слой 4. Vault — безопасная передача секретов
nuc-vault-secret-operator:
enabled: true
vaultConnections:
default:
spec:
address: https://vault.example.local:8200
vaultAuths:
app:
vaultConnectionRef: default
method: kubernetes
mount: kubernetes
role: ai-mesh
serviceAccount: default
vaultStaticSecrets:
model-credentials:
spec:
vaultAuthRef: app
mount: kvv2
type: kv-v2
path: ai/predictor
destination:
name: predictor-secret
create: true
Конфигурация создаёт три ресурса Vault Secrets Operator:
- VaultConnection содержит адрес сервера Vault, к которому будет обращаться оператор: https://vault.example.local:8200.
- VaultAuth задаёт параметры аутентификации. Используется Kubernetes auth method: оператор обменивает токен ServiceAccount на токен Vault с ролью ai-mesh. Такой механизм безопаснее хранения токена Vault непосредственно в Secret: токен ServiceAccount автоматически ротируется, а токен Vault выдаётся с ограниченным временем жизни.
- VaultStaticSecret описывает получение данных из Vault. Оператор читает секрет по пути ai/predictor в хранилище KV версии 2 и создаёт Kubernetes Secret с именем predictor-secret. В нём находятся AWS_ACCESS_KEY_ID и AWS_SECRET_ACCESS_KEY, необходимые компоненту KServe storage initializer для доступа к S3.
Параметр destination.create: true указывает оператору создать Secret, если он ещё не существует. Оператор также отслеживает изменения секрета в Vault и обновляет Kubernetes Secret автоматически. При ротации учётных данных это позволяет обновлять секрет без пересоздания подов.
Слой 5. Prometheus — мониторинг и оповещения
nuc-kube-prometheus-stack:
enabled: true
serviceMonitors:
predictor:
enabled: true
name: predictor
spec:
selector:
matchLabels:
app: predictor
endpoints:
- port: http
podMonitors:
predictor:
enabled: true
name: predictor
spec:
selector:
matchLabels:
app: predictor
podMetricsEndpoints:
- port: http
prometheusRules:
predictor:
enabled: true
name: predictor
spec:
groups:
- name: inference
rules:
- alert: InferenceHighLatency
expr: vector(1)
for: 5m
В этом блоке описаны три ресурса Prometheus Operator:
- ServiceMonitor настраивает сбор метрик через Service. Prometheus будет собирать метрики с подов, у которых есть метка app: predictor, используя порт http.
- PodMonitor обеспечивает сбор метрик непосредственно с подов, без промежуточного Service. Это полезно для динамически создаваемых подов Knative Revisions, у которых не всегда есть стабильный Service.
- PrometheusRule задаёт правило оповещения о задержке инференса. В примере используется выражение-заглушка vector(1), которое необходимо заменить реальным запросом PromQL для производственной среды.
Например, правило для отслеживания P99 latency может выглядеть так:
# Production-ready алерт
- alert: InferenceHighLatency
expr: |
histogram_quantile(0.99,
sum(rate(revision_request_latencies_bucket{
service_name="predictor"
}[5m])) by (le)
) > 2.0
for: 5m
labels:
severity: warning
annotations:
summary: "P99 inference latency above 2s for 5 minutes"
В этом примере оповещение срабатывает, если 99-й перцентиль задержки запросов к предиктору превышает две секунды в течение пяти минут.
Заключение
Пример ai-inference-mesh демонстрирует базовую архитектуру inference-контура. Для использования в производственной среде рекомендуется дополнительно настроить TLS с помощью cert-manager, расширить мониторинг моделей и проработать политики безопасности.
Inference-контур в Kubernetes состоит из нескольких операторов, собственных CRD и множества взаимосвязанных ресурсов. nxs-universal-chart упрощает управление такой инфраструктурой: конфигурация ресурсов описывается в одном values.yaml, а модульная архитектура позволяет подключать только необходимые субчарты.
Полный пример values.yaml доступен в репозитории проекта.
Оставьте заявку, чтобы обсудить проект
Спасибо за обращение
Мы свяжемся с вами в ближайшее время.