Гайды по nxs-universal-chart v3.0: AI Inference контур на основе KServe. ai.. ai. deploy.. ai. deploy. DevOps.. ai. deploy. DevOps. helm.. ai. deploy. DevOps. helm. inference.. ai. deploy. DevOps. helm. inference. istio.. ai. deploy. DevOps. helm. inference. istio. KServe.. ai. deploy. DevOps. helm. inference. istio. KServe. Kubernetes.. ai. deploy. DevOps. helm. inference. istio. KServe. Kubernetes. machine learning.. ai. deploy. DevOps. helm. inference. istio. KServe. Kubernetes. machine learning. mlops.
Гайды по nxs-universal-chart v3.0: AI Inference контур на основе KServe - 1

Итак, вы обучили модель и она показывает ожидаемые результаты. Теперь осталось выкатить её на контур, однако для этого необходим ряд компонентов: нужна маршрутизация трафика, непосредственно инференс. Желателен autoscaling модели, передача чувствительных данных, например креды до хранилища моделей. Ну и мониторинг не помешал бы.

Каждый компонент – это отдельный Helm-чарт, отдельные CRD и отдельная документация. В итоге, вместо быстрого тестирования модели и гипотез, приходится заниматься YAML-инжинирингом и громко ругаться благим матом.

Всем привет, на связи Пётр, инженер компании Nixys. В этой статье я покажу, как собрать полноценный inference-контур из пяти Kubernetes-операторов в одном values.yaml размером в 120 строк, используя nxs-universal-chart.

Общая архитектура

Наш контур будет состоять из пяти слоёв:

Слой

Технология

Компоненты

Функция

NUC subchart

Serving

KServe

InferenceService

Развёртывает модель, обеспечивает V2 Inference Protocol

nuc-kserve

Networking

Istio

Gateway VirtualService

Маршрутизирует внешний трафик к предиктору, mTLS

nuc-istio

Runtime

Knative

Service

Serverless runtime, scale-to-zero, revision management

nuc-knative

Secrets

Vault Secrets Operator

VaultConnection
VaultAuth
VaultStaticSecret

Доставляет S3-креды для загрузки модели из Vault

nuc-vault-secret-operator

Monitoring

KubePrometheusStack

ServiceMonitor Rules

Метрики инференса, алерт на latency

nuc-kube-prometheus-stack

Обзор технологий: пять слоёв inference-контура

Прежде чем переходить к конфигурации, давайте кратко разберём каждую технологию и зачем она нужна.

Istio – service mesh для управления трафиком

Istio – open-source service mesh, который прозрачно интегрируется с Kubernetes через sidecar-прокси (Envoy). Каждый pod в mesh получает sidecar-контейнер, через который проходит весь входящий и исходящий трафик. Это позволяет реализовать mTLS-шифрование между сервисами, гранулярную маршрутизацию (canary, A/B, blue-green) и observability — без изменения кода приложения. Однако, в нашем примере мы не будем затрагивать функции service mesh, оставив это для следующих статей и будем использовать только Istio Gateway.

В нашем inference-контуре Istio отвечает за три задачи. Во-первых, Gateway определяет точку входа для внешнего трафика и терминирует TLS. Во-вторых, VirtualService и DestinationRule описывают правила маршрутизации к предиктору, что даёт возможность реализовать canary-деплой новых версий модели (например, 90% трафика на v1, 10% на v2). В-третьих, AuthorizationPolicy ограничивает доступ к API инференса: только эндпоинты /v1/models/* открыты для внешних клиентов, а метрики и admin-панели остаются закрытыми.

Альтернативой для более лёгких сценариев может быть Gateway API (поддерживается NUC через субчарт nuc-native-gateway). Однако для inference-контуров Istio остаётся стандартом де-факто, поскольку KServe исторически построен на его базе.

KServe – платформа ML-инференса

KServe – платформа для развёртывания ML-моделей на Kubernetes. Ключевой абстракцией является InferenceService: с ее помощью мы можем указать формат модели и путь к артефакту, а KServe автоматически развернут serving-runtime, настроит сеть, реализует autoscaling и обеспечит поддержку V2 Inference Protocol.

KServe поддерживает два основных сценария. Для predictive inference (sklearn, XGBoost, PyTorch, TensorFlow) используется InferenceService, как в нашем примере. Для generative inference (LLM) в KServe v0.16 появился LLMInferenceService с поддержкой vLLM и llm-d для оптимизированного обслуживания больших языковых моделей с KV-cache offloading, prefix caching и распределённым scheduling.

Также стоит упомянуть о двух режимах развертывания: Standart, в котором мы оперируем стандартными ресурсами Kubernetes, такими как Deployment и serverless режим Knative, который использует Knative для обеспечения автоматического масштабирования на основе объема запросов. По сравнению с Knative режимом, который зависит от Knative для автомасштабирования, в Standard режим KEDA может быть установлен опционально, чтобы обеспечить автоматизацию на основе любых пользовательских метрик.

Сама документация рекомендует использовать стандартный режим для генеративного инференса, так как он предоставляет полный контроль за распределением ресурсов для моделей и более предсказуемое масштабирование для ресурсоемких рабочих нагрузок. Однако, мы будем использовать в этой статье Knative режим из-за его функции scale-to-zero.

Knative Serving – serverless на Kubernetes

Knative Serving – платформа для запуска serverless-workloads в Kubernetes. Главная суперсила – это scale-to-zero: когда запросов к модели нет, все поды удаляются полностью. Когда приходит новый запрос, компонент Activator буферизирует его, сигнализирует об этом autoscaler-у, тот поднимает pod. Весь процесс – от нуля до обработки запроса – занимает от нескольких секунд (CPU-модели) до минуты (GPU с загрузкой весов).

Для inference-контура это критическая экономия: GPU-ноды стоят дорого, и держать их 24/7 для модели с 10 запросами в час – расточительство. Knative масштабирует поды на основе concurrency (количество одновременных запросов) или RPS, что лучше подходит для inference-нагрузок, чем стандартный HPA на основе CPU/memory.

KServe использует Knative как движок автоскейлинга «под капотом» – при создании InferenceService автоматически создаётся Knative Service. Через nuc-knative мы дополнительно можем создать собственный Knative Service для кастомного runtime (pre/post-processing, ensemble-логика), работающего рядом с основным предиктором.

VaultSecretOperator – управление секретами

Vault – индустриальный стандарт управления секретами, шифрованием и identity-based доступом. Мы используем его практически на всех проектах и пока что не видим альтернатив. В связке с ним мы используем Vault Secrets Operator (VSO) – официальный Kubernetes-оператор от Hashicorp, который синхронизирует секреты из Vault в Kubernetes Secrets автоматически.

В нашем inference-контуре Vault решает конкретную задачу: KServe storage initializer нуждается в credentials для загрузки артефакта модели из S3 (или Harbor, если мы используем OCI). Хранить эти credentials в Git (даже зашифрованные через SOPS) – идея так себе.

Поэтому, логика работы будет следующей: все креды хранятся в Vault, а VSO создаёт и обновляет Kubernetes Secret при каждой ротации, безопасно забирая их по строгим политикам, которые предоставляют конкретному VaultAuth доступ до конкретного секрета в Vault. Для аутентификации мы будем использовать Kubernetes auth method. Это наиболее удобный и безопасный вариант: нет долгоживущих токенов, нет секретов в CI/CD переменных.

Prometheus – мониторинг и алертинг

Prometheus – стандарт мониторинга в Kubernetes. Prometheus Operator упрощает конфигурацию через CRD: вместо правки prometheus.yml вы создаёте ServiceMonitor, PodMonitor и PrometheusRule как Kubernetes-ресурсы.

Для inference-контура мониторинг – обязательный слой. ML-модель может деградировать незаметно и без мониторинга вы узнаете об этом от пользователей. В нашем контуре Prometheus собирает метрики на двух уровнях: через ServiceMonitor (стабильные эндпоинты) и PodMonitor (прямой скрейпинг подов – критично для Knative, где поды создаются и удаляются динамически). PrometheusRule определяет алерты на P99 latency инференса.

Визуально поток трафика будет выглядеть следующим образом:

Гайды по nxs-universal-chart v3.0: AI Inference контур на основе KServe - 2
  • Клиентский запрос проходит попадает на Istio Gateway и маршрутизируется через VirtualService

  • Затем попадает на KServe InferenceService, а от туда на Knative Pod

  • VaultSecretOperator доставляет S3-credentials из Vault через автоматическое создание нативного Kubernetes Secret

  • Prometheus собирает метрики со всех слоёв через ServiceMonitor

Разобравшись с общей архитектурой, можно переходить к реализации.

Предварительные требования

Предполагается, что в вашем кластере уже установлены следующие операторы и их CRD:

  • Istio

  • KServe controller (v0.14+)

  • Knative Serving (v1.12+)

  • Vault Secrets Operator (v0.5+)

  • kube-prometheus-stack

Также нам будет необходим установленный в Kubernetes Vault. Действия по установке операторов мы не будем расписывать здесь – установка всех компонентов выше отлично расписана в документациях проектов.

Затем нам будет необходимо установить сам nxs-universal-chart через стандартный helm install:

helm install ai-mesh oci://registry.nixys.ru/nuc/nxs-universal-chart 
  -f values.yaml 
  --version 3.0.17

А теперь – к самому интересному: разберём каждую секцию, который описывает весь 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. В production сюда добавляется TLS-терминация через cert-manager (субчарт nuc-certificates).

  • VirtualService – задает правила маршрутизации. Весь трафик, приходящий на ai-mesh.example.local через Gateway inference, направляется к сервису предиктора. Если бы у нас были canary-версии модели, здесь можно было бы добавить weight-based routing.

  • DestinationRule – политики соединений. В минимальной конфигурации он просто объявляет destination. В production сюда добавляется trafficPolicy.tls.mode: ISTIO_MUTUAL для включения mTLS.

  • AuthorizationPolicy – контроль доступа. Разрешает обращения только к эндпоинтам /v1/models/*, что соответствует V2 Inference Protocol. Всё остальное (health checks, метрики, admin endpoints) блокируется для внешних клиентов.

Слой 2: KServe — serverless inference

nuc-kserve:
  enabled: true

  inferenceServices:
    predictor:
      spec:
        predictor:
          model:
            modelFormat:
              name: sklearn
            storageUri: s3://models/predictor

KServe InferenceService — абстракция, которая объединяет модель, runtime, autoscaling и networking в одном ресурсе.

modelFormat.name: sklearn говорит KServe использовать встроенный sklearn serving runtime (на базе MLServer). KServe поддерживает sklearn, PyTorch, TensorFlow, XGBoost, Hugging Face и другие фреймворки из коробки.

storageUri: s3://models/predictor — путь к артефакту модели в S3-совместимом хранилище. KServe автоматически инициализирует sidecar-контейнер (storage initializer), который скачивает модель перед запуском serving-контейнера. Для доступа к S3 нужны credentials — их мы получаем из Vault (см. слой 4).

При деплое KServe создаёт под капотом:

  • Knative Service для serverless-поведения

  • Revision для версионирования

  • Route для traffic splitting

  • Service и VirtualService для доступа

Слой 3: Knative — serverless runtime

nuc-knative:
  enabled: true

  services:
    runtime:
      spec:
        template:
          spec:
            containers:
              - image: ghcr.io/nixys/inference-runtime:latest

Knative Service объявляет serverless workload с автоматическим scale-to-zero. Когда запросов нет, поды полностью удаляются (экономия GPU-ресурсов). Когда приходит первый запрос, Knative activator буферизирует его и поднимает под.

В этом примере runtime – дополнительный сервис для кастомного inference-runtime-а. Если ваша модель обслуживается стандартным KServe-рантаймом (sklearn, pytorch, tensorflow), этот блок можно опустить. Он нужен для:

  • кастомных pre/post-processing pipeline-ов

  • ensemble-моделей, где несколько моделей работают в цепочке

  • sidecar-сервисов (feature enrichment, logging, tracing)

Слой 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

Этот блок создаёт три CRD-ресурса Vault Secrets Operator:

  • VaultConnection – адрес Vault-сервера. Оператор будет обращаться к https://vault.example.local:8200.

  • VaultAuth – настройки аутентификации. Используется Kubernetes auth method: оператор обменивает ServiceAccount token пода на Vault token с ролью ai-mesh. Это безопаснее, чем хранить Vault token в Secret-е: ServiceAccount token ротируется автоматически, а Vault token выдаётся с коротким TTL.

  • VaultStaticSecret – непосредственно сами данные. Оператор читает секрет по пути ai/predictor в KV движке Vault и создаёт Kubernetes Secret predictor-secret. Этот секрет содержит AWS_ACCESS_KEY_ID и AWS_SECRET_ACCESS_KEY для доступа KServe storage initializer к S3.

Ключевое: create: true в destination говорит оператору создать Secret, если его нет. Оператор также следит за изменениями в Vault и обновляет Secret автоматически — rotate credentials без пересоздания подов.

Слой 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 будет собирать метрики со всех подов, label которых содержит app: predictor, через порт http.

  • PodMonitor – прямой скрейпинг подов без использования Service. Полезно, когда поды создаются динамически (в нащем случае – это поды от Knative Revisions) и не всегда имеют стабильный Service.

  • PrometheusRule – алерт на latency. В примере используется заглушка vector(1), которую в production нужно заменить на реальное выражение. Например:

# 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"

Заключение

Пример ai-inference-mesh – это только отправная точка для примера и старта. Для production-использования рекомендуется добавить TLS сертифкацию через cert-manager, полноценный мониторинг моделей и правила безопасности.

Inference-контур в Kubernetes – это не один ресурс. Это конструкция из 5-7 операторов, каждый со своими CRD, и десяток ресурсов, которые должны корректно ссылаться друг на друга. В этой статье мы попыталсиь упростить это, использовав nxs-universal-chart как общую абстрацию: все CRD-ресурсы описываются в одном values.yaml, чарт обеспечивает консистентность имен и лейблов, а модульная архитектура позволяет включать только нужные subchart.

Полный пример values.yaml из этой статьи доступен в репозитории проекта. Как и ранее, будем рады услышать ваши мысли и увидеть предложения по улучшению на GitHub, а также в нашем сообществе в Telegram. Увидимся!

Автор: RukInDaHouse

Источник