
Команда VK Cloud перевела разбор запуска self-hosted (размещаемого на собственных мощностях), read-only ИИ-агента внутри кластера Kubernetes, где всю цепочку CI/CD обслуживают GitHub Actions и Argo CD Image Updater. Никакие данные не покидают кластер, облачные ИИ-провайдеры не задействованы.
Почему кластер-осведомлённый агент — интересный паттерн
Большинство сегодняшних инструментов «ИИ для Kubernetes» — это размещённый SaaS, который забирает данные кластера и возвращает советы. Модель живёт где-то ещё. Данные покидают сеть.
Эта статья разбирает противоположный дизайн: агент работает внутри кластера, наблюдает живое состояние через API Kubernetes и рассуждает с помощью локальной LLM. Каждый слой виден, каждый набор учётных данных ограничен по области действия, а единственный исходящий сетевой трафик — загрузка модели при запуске.
Чем этот паттерн интересен платформенным инженерам:
|
Свойство |
Что даёт |
|
Кластер-осведомлённость |
Агент читает живые поды, события и логи и рассуждает о реальном состоянии, а не об общих фактах про Kubernetes. |
|
Read-only by design |
Выделенный |
|
Просто ещё одна нагрузка K8s |
Агент — это |
|
Полный GitOps |
Промпты, выбор модели и RBAC живут в Git. Argo CD согласует их. Поведение агента проверяется через |
Исходный код: github.com/MaryamTavakkoli/local-k8s-ai-agent
LLM против ИИ-агента: важное различие
Large Language Model (большая языковая модель) отвечает только из обучающих данных. Она не знает среду, в которую развёрнута. Агент в том смысле, который используется здесь, выполняет дополнительный шаг перед рассуждением: он наблюдает реальный мир и включает это наблюдение в промпт.
Разница в выводе конкретна. Обычный вызов LLM возвращает «CrashLoopBackOff обычно означает, что контейнер не проходит health-проверки или неожиданно завершается…» Вызов агента возвращает «Pod api-7b8d перезапускался 14 раз за последний час с ImagePullBackOff против registry.local. Запустите kubectl describe pod api-7b8d, чтобы подтвердить.»
Второй ответ конкретен и опирается на факты. Первый корректен, но к этому кластеру неприменим.
Проект показывает оба режима через два REST-эндпоинта:
-
POST /ask— LLM в одиночку, полезно для общих вопросов вроде «Что такое StatefulSet?» -
POST /diagnose— агент: читает живое состояние кластера, затем рассуждает над ним
Архитектура
Система состоит из двух половин: цепочка CI/CD наверху и рантайм Kubernetes внизу.
Сторона рантайма:
-
Pod Ollama отдаёт локальную модель Mistral 7B на порту 11434
-
Pod FastAPI предоставляет HTTP API агента и чат-интерфейс на порту 8000
-
PersistentVolumeClaimхранит веса модели, чтобы загрузки не повторялись -
Выделенный
ServiceAccount, смонтированный в pod FastAPI, имеетClusterRoleтолько на чтение подов, событий, логов, сервисов и деплойментов
Сторона доставки:
-
Push исходного кода приложения в Git запускает GitHub Actions для сборки мультиархитектурного образа (
linux/amd64 + linux/arm64) с тегом из 7-символьного commit SHA -
Argo CD Image Updater (из argoproj-labs) опрашивает Docker Hub каждые 2 минуты, находит новые теги по настроенной регулярке и коммитит новый тег обратно в
kustomization.yamlрепозитория -
Argo CD замечает изменение манифеста и согласует кластер
Две половины не связаны. Argo CD не знает про реестр. GitHub Actions не знает про кластер. Image Updater — маленький оператор, который их связывает, и делает это записью в Git, сохраняя единый источник правды.
Концепции ИИ, которых вам реально пригодятся
Вот несколько концепций, которые ИИ-инженеры используют каждый день.
1. LLM (Large Language Model)
Статистическая модель, обученная на огромных объёмах текста. Она не «знает» факты — она предсказывает наиболее вероятное следующее слово с учётом всего, что было до этого. Вот и всё. Магия в том, что эта простая задача в масштабе выдаёт нечто, что ощущается как рассуждение.
Проект использует Mistral 7B — open source модель с 7 миллиардами параметров. «Параметры» — числа, которые модель выучила во время обучения, как сила связей в мозге.
2. Локальная LLM
Большинство коммерческих ИИ-сервисов отправляют ваш текст удалённому облачному провайдеру. Плата за это — возможности: локальная модель 7B не так обширна, как массивная фундаментальная модель на облачной инфраструктуре. Но для экспериментов её более чем достаточно. И ничто не покидает вашу сеть.
3. Ollama (рантайм для обслуживания моделей)
Ollama — не ИИ-модель. Это сервер, который запускает ИИ-модели. Считайте его веб-сервером для LLM: он загружает файлы модели, помещает их в память и предоставляет REST API на порту 11434, чтобы любой клиент (включая наше FastAPI-приложение) мог отправлять промпты и получать ответы.
Без Ollama пришлось бы сражаться с PyTorch, CUDA и библиотеками токенизаторов. С ним запуск LLM — это ollama pull mistral, а за ним HTTP POST.
4. System Prompt (системный промпт, личность)
Это самая важная концепция ИИ для разработчиков приложений, и освоить её можно минут за десять.
System prompt — это инструкции, которые вы даёте модели перед вопросом пользователя. Модель читает их первыми и формирует по ним каждый ответ.
В нашем проекте system prompt для /ask такой:
«Вы — DevOps-ассистент, специализирующийся на Kubernetes.
Получив ошибку или вопрос, вы:
1. Чётко объясняете, что это означает
2. Даёте точные kubectl-команды для диагностики или исправления
3. Объясняете, почему исправление работает
Будьте кратки и практичны.»
Без этого промпта Mistral — обычный ассистент. С ним Mistral — специалист по Kubernetes, который всегда возвращает структурированные ответы. Переобучения не потребовалось. Это называется prompt engineering (инженерия промптов), и именно так построен почти каждый ИИ-продукт, которым вы пользуетесь.
5. RAG (Retrieval-Augmented Generation)
Модный термин для того, что делает /diagnose. RAG означает: перед тем как спросить модель, извлеки данные из реального мира и дополни ими промпт.
RAG — причина, по которой работают современные ИИ-ассистенты. Code-ассистент читает репозиторий вашего локального рабочего пространства. Наш агент читает живое состояние вашего кластера. Тот же паттерн, другой источник данных.
Два режима: где агент становится настоящим
Режим 1: Ask (LLM в одиночку)
Вы вводите вопрос, FastAPI добавляет в начало system prompt и отправляет его Ollama. Модель отвечает из своих обучающих данных. Полезно для общих вопросов по K8s вроде «Что такое StatefulSet?»
Режим 2: Diagnose Cluster (настоящий агент)
Вы вводите вопрос и namespace. FastAPI делает кое-что новое: вызывает API Kubernetes и читает:
-
Все поды в этом namespace (фаза, счётчик перезапусков, причина ожидания)
-
Последние 10 событий
-
Последние 20 строк логов из любого пода не в состоянии Running
Весь этот контекст вставляется в промпт. Затем Mistral рассуждает — но теперь о вашем реальном кластере, а не об общих знаниях про Kubernetes.
Чат-интерфейс даже показывает точный контекст, который прочитал агент, в сворачиваемой панели под каждым ответом.
Read-only by design
Агент работает с ServiceAccount, привязанным к ClusterRole, который даёт только глаголы чтения:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: ai-devops-api-reader
rules:
- apiGroups: [""]
resources: ["pods", "pods/log", "events", "services", "configmaps", "namespaces"]
verbs: ["get", "list"]
- apiGroups: ["apps"]
resources: ["deployments", "replicasets", "statefulsets", "daemonsets"]
verbs: ["get", "list"]
Это самое важное проектное решение в проекте, и оно работает не только для ИИ-нагрузок. Агент, который может удалить pod по собственному рассуждению, — это инцидент в продакшене, ожидающий своего часа. Галлюцинации в паре с доступом на запись — плохая комбинация.
Read-only RBAC переворачивает модель доверия. Агенту позволено ошибаться, потому что ошибка ничем не грозит. API-сервер Kubernetes держит границу, и вывод LLM её не обойдёт. Перебирать промпты и модели становится дёшево, потому что поведение в худшем случае ограничено.
Тот же паттерн масштабируется: начинайте каждого агента с read-only, затем добавляйте каждую новую возможность по одному глаголу за раз — каждый со своим RBAC-правилом и ревью.
Цепочка CI/CD
Сторона доставки в архитектуре использует три независимых компонента, у каждого одна зона ответственности.
GitHub Actions собирает и пушит образ. Workflow использует docker buildx с эмуляцией QEMU, чтобы собрать список манифестов под linux/amd64 (раннеры на GitHub) и linux/arm64 (машины разработчиков на Apple Silicon). Тег — 7-символьный commit SHA, неизменяемая ссылка.
Argo CD Image Updater опрашивает реестр каждые 2 минуты. Конфигурация живёт в Custom Resource ImageUpdater, который называет целевое Argo CD Application, образ для отслеживания, регулярку allowTags (^[0-9a-f]{7}$) и стратегию обновления (newest-build). Найдя новый подходящий тег, оператор переписывает поле newTag в k8s/kustomization.yaml и коммитит изменение в ветку main.
apiVersion: argocd-image-updater.argoproj.io/v1alpha1
kind: ImageUpdater
metadata:
name: local-k8s-ai-agent
namespace: argocd
spec:
writeBackConfig:
method: git
gitConfig:
branch: main
writeBackTarget: "kustomization:."
applicationRefs:
- namePattern: "local-k8s-ai-agent"
images:
- alias: api
imageName: marytvk/local-k8s-ai-agent
commonUpdateSettings:
updateStrategy: newest-build
allowTags: "regexp:^[0-9a-f]{7}$"
Argo CD следит за репозиторием и согласует кластер на каждом коммите. Поскольку исходными манифестами управляет Kustomize, Argo CD применяет отрендеренный вывод — теперь уже с обновлённым тегом образа.
Попробуйте сами: это отправная точка, а не пункт назначения
Репозиторий здесь: github.com/MaryamTavakkoli/local-k8s-ai-agent
Пошаговая настройка с точными командами есть в README. Полное время от git clone до работающего чат-интерфейса — около 30 минут (большую часть займёт загрузка Mistral).
Если вы DevOps- или платформенный инженер, который слышал «ИИ-агенты идут» и гадал, что это значит на практике, — это ваша отправная точка, а не финишная черта. Как только вы увидите рабочий цикл агента, вам будет гораздо проще двигаться дальше.
Автор: GRADDATA


