Презентации лучше смотреть с десктопа
Слайды рассчитаны на широкий экран, клавиатуру и формат 16:9. Откройте эту страницу на ноутбуке или компьютере.
Вернуться на сайтКак стартап на 500к
научил агента управлять Kubernetes
Эдгар Сипки//Founder EasyP && SIPKI Tech
Кто я и где мы
Эдгар Сипки
Senior golang developer, open-source. Founder EasyP.
Наш контекст
Маленький стартап. Мало денег, нет инфраструктурной команды.
О чём поговорим?
- 01Агент и MCP за пять минут
- 02Стартап против инфраструктуры
- 03Deckhouse и первый MCP-сервер
- 04spec-first и protoc-gen-mcp
- 05deckhouse-harness изнутри
- 06Сценарии и живое демо
О чём поговорим?
- 01Агент и MCP за пять минут
- 02Стартап против инфраструктуры
- 03Deckhouse и первый MCP-сервер
- 04spec-first и protoc-gen-mcp
- 05deckhouse-harness изнутри
- 06Сценарии и живое демо
АГЕНТ
И MCP
LLM умна, но безрука
- Модель отлично рассуждает
- Но сама по себе ничего не делает в реальном мире
- → чтобы действовать, ей нужны руки
Анатомия агента
LLM
рассуждает и принимает решения
Цикл
план → действие → наблюдение
Инструменты
руки во внешний мир
Контекст
что модель видит сейчас
MCP = USB-C для интеграций
- Один протокол вместо зоопарка кастомных коннекторов
- Агент видит и вызывает внешние действия через один стандарт
- MCP-сервер = руки агента
Три примитива
Tools 🔧
действия
Resources 📄
чтение
Prompts 💬
шаблоны
Как агент выбирает tool
Два транспорта
stdio
- агент запускает процесс локально
- один клиент = один процесс
- доступ - kubeconfig разработчика
SSE / HTTP
- сервер живёт в кластере
- много агентов одновременно
- доступ - RBAC от ServiceAccount
один бинарь - оба транспорта: TRANSPORT=sse LISTEN_ADDR=:8080
Аннотации: контракт безопасности
read_only_hint
только чтение - можно без подтверждения
destructive_hint
опасно - требует человека
idempotent_hint
повтор вызова безопасен
Клиент читает аннотации и понимает, где нужен человек.
О чём поговорим?
- 01Агент и MCP за пять минут
- 02Стартап против инфраструктуры
- 03Deckhouse и первый MCP-сервер
- 04spec-first и protoc-gen-mcp
- 05deckhouse-harness изнутри
- 06Сценарии и живое демо
СТАРТАП ПРОТИВ
ИНФРАСТРУКТУРЫ
Задача
- Продукту нужна настоящая инфраструктура: Kubernetes, деплои, TLS
- В команде - только бэкенд-разработчики
- DevOps-инженера нет и не будет
Что нам реально нужно
- Поднять и держать кластер
- Добавлять ноды, когда не хватает ресурсов
- Выпускать сервисы наружу: Ingress + TLS
- Понимать, что сломалось, быстро
- Обновлять платформу без страха
И всё это - без выделенной команды.
Экономика вопроса
столько подняли стартапы вокруг AI-инфры
наш бюджет на всё
Ставка
Не нанимаем DevOps.
Отдаём управление инфраструктурой агенту.
Попытка №1: готовый Kubernetes MCP
Agent<br> │<br> ▼<br>MCP (Kubernetes) ← готовый сервер с kubectl-тулами<br> │<br> ▼<br>kube-apiserverПочему не взлетело
- Сырой kubectl-уровень: агент тонет в низкоуровневых объектах
- Нет модели нашего домена: «добавь ноду» ≠ 20 kubectl-команд
- Опасные операции без ограничений и без аннотаций
- → нужен доменный MCP-сервер, а не обёртка над kubectl
О чём поговорим?
- 01Агент и MCP за пять минут
- 02Стартап против инфраструктуры
- 03Deckhouse и первый MCP-сервер
- 04spec-first и protoc-gen-mcp
- 05deckhouse-harness изнутри
- 06Сценарии и живое демо
DECKHOUSE И ПЕРВЫЙ
MCP-СЕРВЕР
Что такое Deckhouse
- Kubernetes-платформа: кластер + модули «из коробки»
- Мониторинг, ingress, cert-manager, автообновления - уже внутри
- Вся платформа управляется декларативно через CRD
CRD: декларативный интерфейс платформы
apiVersion: deckhouse.io/v1<br>kind: NodeGroup<br>metadata:<br> name: worker<br>spec:<br> nodeType: Static<br> staticInstances:<br> count: 3<br> labelSelector:<br> matchLabels:<br> role: workerВердикт
Для человека: платформа закрывает 90% рутины
Для агента: интерфейса нет - только kubectl и документация
Идея
Пишем свой MCP-сервер над Deckhouse:
доменные тулы вместо сырого kubectl.
Начали писать руками
- Каждый tool: схема + валидация + хендлер + описание
- Первые 5 тулов - нормально
- Дальше - копипаста и расхождение схем
Проблема масштаба
- Нужны десятки тулов: ноды, модули, релизы, конфиги, диагностика
- JSON Schema руками = ошибки в каждой второй
- Схема, код и описание живут отдельно и расходятся
Симптом
Агент вызывает tool с параметрами, которых нет в схеме.
Схема говорит одно, код делает другое.
Диагноз
Проблема не в коде.
Проблема в том, что нет единого источника правды.
О чём поговорим?
- 01Агент и MCP за пять минут
- 02Стартап против инфраструктуры
- 03Deckhouse и первый MCP-сервер
- 04spec-first и protoc-gen-mcp
- 05deckhouse-harness изнутри
- 06Сценарии и живое демо
SPEC-FIRST И
PROTOC-GEN-MCP
Нужен источник правды
- Одна спецификация → схема, код и описания генерируются
- Руками пишем только бизнес-логику хендлеров
- → подход называется spec-first
OpenAPI vs Protobuf
- Строгая типизация и компактный синтаксис
- Экосистема плагинов protoc
- Уже используем в продукте (EasyP!)
- Многословный YAML/JSON
- Слабая связь со структурами кода
- Генерация клиентов ≠ генерация MCP-серверов
Решение
Берём proto как единственный источник правды
и пишем свой генератор: protoc-gen-mcp.
Агент ужасно проектирует,
но неплохо кодит
Идея protoc-gen-mcp
- proto-сервис → набор MCP-тулов
- rpc → tool, message → JSON Schema, комментарий → description
- Опции метода → аннотации безопасности
rpc + опции = tool с аннотациями
service DiagnosticsAPI {<br> // Статус кластера: ноды, модули, алерты.<br> rpc GetClusterStatus(GetClusterStatusRequest)<br> returns (GetClusterStatusResponse) {<br> option (mcp.options.v1.method) = {<br> read_only_hint: true<br> };<br> }<br>}Пайплайн: от proto до сервера
.proto (источник правды)<br> │ easyp generate / buf generate<br> ▼<br>protoc-gen-mcp<br> ├─▶ JSON Schema для каждого tool<br> ├─▶ интерфейсы хендлеров<br> ├─▶ регистрация тулов + аннотации<br> └─▶ валидация входа из constraints<br> │<br> ▼<br>ваш код: только бизнес-логика хендлеровConstraints: валидация из спецификации
message AddWorkerNodeRequest {<br> string name = 1 [(mcp.options.v1.field) = {<br> string: { min_len: 1, max_len: 63,<br> pattern: "^[a-z0-9-]+$" }<br> }];<br> int32 cpu = 2 [(mcp.options.v1.field) = {<br> int32: { gte: 1, lte: 64 }<br> }];<br>}Почему это работает
- Схема и код не могут разойтись - они из одного файла
- Комментарий в proto = description для агента
- Новый tool = новый rpc + один хендлер
- Ревью спецификации вместо ревью бойлерплейта
Где болело: zero values
- В protojson «поле не передано» и «передан ноль» выглядят одинаково
- Агент пропускает поле → сервер видит 0 → логика ломается
- Решение: UNSET-sentinel в рантайме - явно различаем «нет значения» и «ноль»
Один proto - пять языков
| Язык | SDK | Особенность |
|---|---|---|
| Go | mcp-go | первый, самый зрелый |
| Python | official MCP SDK | dataclass- или protobuf-хендлеры |
| Kotlin | kotlin-sdk-server | JVM-мир |
| Java | mcp java sdk | энтерпрайз |
| TypeScript | @modelcontextprotocol/sdk | Protobuf-ES + Ajv |
Эволюция за полгода
Мета-уровень
Агент сам умеет пользоваться генератором:
агент пишет proto → генерирует себе руки
npx skills add easyp-tech/protoc-gen-mcp-skillРуками - только бизнес-логика
// Сгенерировано protoc-gen-mcp. Не редактировать.<br>type DiagnosticsAPIToolHandler interface {<br> GetClusterStatus(<br> ctx context.Context,<br> req *deckhousev1.GetClusterStatusRequest,<br> ) (*deckhousev1.GetClusterStatusResponse, error)<br><br> ListUnhealthyPods(<br> ctx context.Context,<br> req *deckhousev1.ListUnhealthyPodsRequest,<br> ) (*deckhousev1.ListUnhealthyPodsResponse, error)<br>}Генерация одной командой
generate:<br> plugins:<br> - name: go<br> out: gen<br> - name: mcp<br> out: gen<br> opts:<br> lang: goСборка сервера
srv := mcpruntime.NewServer("deckhouse-harness")<br><br>deckhousev1.RegisterDiagnosticsAPITools(<br> srv, diagnosticsHandler,<br>)<br>deckhousev1.RegisterNodesAPITools(<br> srv, nodesHandler,<br>)<br><br>if transport == "sse" {<br> return srv.ServeSSE(ctx, listenAddr)<br>}<br>return srv.ServeStdio(ctx)О чём поговорим?
- 01Агент и MCP за пять минут
- 02Стартап против инфраструктуры
- 03Deckhouse и первый MCP-сервер
- 04spec-first и protoc-gen-mcp
- 05deckhouse-harness изнутри
- 06Сценарии и живое демо
DECKHOUSE-HARNESS
ИЗНУТРИ
43 тула, 6 доменов
все read-only
самый опасный домен
вкл/выкл модулей
источники модулей
обновления платформы
ModuleConfig
Каждый домен = отдельный proto-сервис в proto/deckhouse/v1/
Тул ≠ один API-вызов
AddWorkerNode
- создать SSHCredentials
- создать StaticInstance
- ждать bootstrap ноды
DrainNode
- cordon ноды
- eviction подов с уважением PDB
- отчёт о том, что не выселилось
Один вызов агента = целый сценарий внутри хендлера
Один бинарь - два режима
# локально: stdio + kubeconfig разработчика<br>./deckhouse-harness<br><br># в кластере: Pod в d8-system, in-cluster auth<br>TRANSPORT=sse LISTEN_ADDR=:8080 ./deckhouse-harnessГраницы доверия
- Аннотации: read-only тулы агент зовёт свободно
- destructive-тулы - только с подтверждением человека
- RBAC: ServiceAccount ограничен тем, что реально нужно
- даже сломавшийся агент не сделает больше, чем разрешено
Боевая история: одна буква
deckhouserelease → deckhousereleases- Опечатка в GVR: resource в единственном числе
- 133 unit-теста с моками - все зелёные 🟢
- Поймали только интеграционные тесты на живом кластере
- → моки врут, кластер - нет
Как тестировать руки агента
unit-тестов: логика хендлеров
интеграционных: Kind + Deckhouse CE, оба транспорта
Интеграционные тесты гоняют реальные MCP-вызовы через оба транспорта.
О чём поговорим?
- 01Агент и MCP за пять минут
- 02Стартап против инфраструктуры
- 03Deckhouse и первый MCP-сервер
- 04spec-first и protoc-gen-mcp
- 05deckhouse-harness изнутри
- 06Сценарии и живое демо
СЦЕНАРИИ И
ЖИВОЕ ДЕМО
Сценарий A: диагностика
Сценарий B: новая нода
Сценарий C: HTTPS за один вызов
Сценарий D: разбор инцидента
Вся цепочка - read-only тулы: агент расследует без риска, решение принимает человек.
ЖИВОЕ ДЕМО
Что мы только что видели
- Диагностика без единой команды kubectl
- Сложные операции одним вызовом
- Объясняет, что и зачем делает
- Подтверждает destructive-операции
- Ставит границы через RBAC
- Отвечает за прод головой
Шесть тезисов
- Агенту нужны доменные руки, а не сырой kubectl
- Руки руками не масштабируются - нужен источник правды
- proto + protoc-gen-mcp: схема, код и описания из одного файла
- Агент ужасно проектирует, но неплохо кодит
- Один proto - пять языков MCP-серверов
- Доверие агенту = аннотации + RBAC + интеграционные тесты
Когда это вам подойдёт
- Маленькая команда без выделенного DevOps
- Уже есть proto или готовы его завести
- Операции типовые и описуемые
- Жёсткий комплаенс и аудит каждого действия
- Нет интеграционных тестов - сначала они
- Одноразовые уникальные операции
ЧТО ДАЛЬШЕ
Планы
Итог в цифрах
43 тула · 6 proto-сервисов
133+58 тестов · 5 языков
0 нанятых DevOps
Попробуйте сами
Эдгар Сипки//Спасибо!