Kubernetes-контролери для Platform Engineering та AI-агентів

💡 Усі статті, обговорення, новини про DevOps — в одному місці. Приєднуйтесь до DevOps спільноти!

Моя мета — мотивувати усіх охочих почати вивчати та використовувати Kubernetes API та контролери (controllers), тому що як на мене, це найкращий спосіб підвищити свій рівень як software engineer, Kubernetes-експертизу та навички (true-)SRE. А ми знаємо, що це наша впевненість на співбесідах, цікаві проєкти та високі зарплати.

У статті ми розглянемо власний досвід розробки кастомного Kubernetes-контролера для реліз-системи, а саме управління промоушеном аплікацій (application promotion). Система побудована на основі Kubernetes-контролерів: Flux, Application CRD та ed210 (наш реліз контролер, назва походить від ED-209).

Поговоримо про архітектурні особливості, цікавий досвід та практичні аспекти розробки подібних систем на прикладі реального проєкта. Це відкриває можливості інтеграції з Kubernetes від автоматизації у пайплайн та системах Platform Engineering до управління інфраструктурою натуральною мовою.

Додаткову увагу приділимо реалізації MCP (Model Context Protocol)-сервера прямо в контролері, що дозволяє використовувати AI MCP-агентів (наприклад, розгорнутих у kagent) для управління інфраструктурою.

Згадаємо архітектуру Kubernetes, зазирнемо під капот контролера, вивчимо основні терміни, компоненти та функціональність.

Кластер Kubernetes складається з control plane та набору робочих машин, які називаються вузлами (nodes) і запускають контейнеризовані застосунки. Кожен кластер потребує щонайменше одного робочого вузла для запуску Pod — найменшої абстрактної одиниці ресурсу в Kubernetes.

Компоненти control plane ухвалюють глобальні рішення щодо кластера (наприклад, планування), а також виявляють і реагують на події в кластері.

kube-apiserver — це компонент control plane, який забезпечує доступ до Kubernetes API. Це головна точка входу до кластеру, через яку всі інші компоненти, користувачі та зовнішні системи взаємодіють із Kubernetes. Саме kube-apiserver відповідає за обробку запитів — як внутрішніх, так і зовнішніх.

etcd — це надійне, консистентне сховище типу «ключ-значення», яке Kubernetes використовує для зберігання всієї конфігурації та стану кластера. Воно виконує роль системи збереження «єдиної правди» (source of truth) для всіх даних, необхідних для роботи control plane.

kube-scheduler — це компонент control plane, який відповідає за розподіл новостворених Pods на доступні вузли. Він відстежує Pod’и без призначеного вузла, оцінює ресурси та обирає найкращий варіант для розміщення кожного Pod.

kube-controller-manager — це частина control plane, яка запускає різноманітні контролери. Контролери — це фонові процеси, що підтримують бажаний стан системи, реагуючи на події у кластері. Серед них: Node controller — виявляє та реагує на ситуації, коли вузли стають недоступними або Job controller — відповідає за об’єкти типу Job: він створює Pod’и для виконання одноразових задач і стежить за їх завершенням.

cloud-controller-manager — компонент control plane, який дозволяє Kubernetes інтегруватися з хмарними провайдерами (GCP, AWS і так далі). Він відокремлює cloud-логіку від загальних механізмів Kubernetes. Завдяки цьому компоненту кластер може напряму взаємодіяти з API хмари.

До контролерів, які мають залежність від cloud провайдера, належать, наприклад, Route controller — відповідає за налаштування маршрутів у хмарній інфраструктурі або Service controller — створює, оновлює та видаляє балансувальники навантаження (loadbalacers) на стороні провайдера.

Як працюють контролери Kubernetes

Контролери в Kubernetes — це контрольні цикли (control loops) — безперервні циклічні процеси, що регулюють стан системи. Вони постійно спостерігають за поточним станом кластера й, за потреби, ініціюють зміни, щоб привести систему до бажаного стану.

Кожен контролер прагне наблизити поточний стан кластера до заданого (desired) стану. Контролер працює принаймні з одним типом ресурсу Kubernetes (CRD). Ці об’єкти мають спеціальне поле, яке визначає бажаний стан. Наприклад, це може бути версія контейнерного образу, яку потрібно запустити.

Коли ми створюємо Custom Resource (CR) у Kubernetes, ми фактично визначаємо новий тип об’єкта, який Kubernetes нативно не розпізнає. Щоб зробити його відомим кластеру, ми створюємо Custom Resource Definition (CRD) — опис цієї нової сутності.

Але просто визначити ресурс недостатньо. Потрібен компонент, який буде спостерігати за станом таких об’єктів і реагувати на зміни. Саме цю роль і виконують контролери — вони відстежують ресурси та приводять їх у відповідність до бажаного стану.

За своєю суттю контролери — це код на будь-якій мові (по замовченню golang), що реалізує клієнта Kubernetes API та додаткову логіку обробки подій Kubernetes-ресурсів.

List / Watch / Reconciliation

У центрі кожного контролера Kubernetes — цикл узгодження (Reconciliation Loop). Саме тут і відбувається «магія»: цикл постійно порівнює поточний стан кластера з бажаним і, у разі відхилення, виконує необхідні дії для їх узгодження.

Але як контролер дізнається про зміни?

  • API Server виступає центральним вузлом, який зберігає весь стан кластера, включаючи Custom Resources (CR) та їхні визначення (CRD), у etcd.
  • Контролер не опитує API Server безперервно — це було б неефективно. Замість цього він використовує механізм List/Watch, щоб отримувати оновлення лише тоді, коли щось змінюється.

Як працює client-go

Перейдемо до правої частини діаграми, де показано client-go — клієнтську бібліотеку Kubernetes на Go.

  • Reflector — ефективно спостерігає за ресурсами через API Server і надсилає оновлення у робочу чергу.
  • Informer — замість того, щоб кожного разу звертатися до API Server, Informer слідкує за ресурсами Kubernetes і кешує їх локально.
  • Indexer — організовує кешовані дані для швидкого доступу, що значно пришвидшує роботу контролерів.
  • Event Handler — коли відбувається зміна, обробник подій (event handler) реагує на неї й додає відповідне завдання до черги для повторного узгодження.

У підсумку, контролер підхоплює зміни й запускає Reconciliation Loop, щоб переконатися, що фактичний стан системи відповідає бажаному.

Уся ця механіка дозволяє Kubernetes залишатися самовідновлюваною системою, яка підтримує декларативне управління станом із мінімальними витратами ресурсів.

Flux: GitOps у дії завдяки Kubernetes-контролерам

Flux — яскравий приклад використання кастомних контролерів для реалізації принципів GitOps у Kubernetes. Він побудований на основі GitOps Toolkit — набору спеціалізованих інструментів і контролерів, розроблених для безперервного розгортання (continuous delivery).

Наприклад, Image Reflector та Image Automation Controllers є компонентами, які забезпечують автоматизацію оновлень образів шляхом сканування репозиторіїв і відповідного оновлення конфігурацій.

Завдяки цим контролерам Flux постійно відстежує та узгоджує поточний стан кластера з бажаним, який визначено у Git чи інших джерелах. Таким чином Flux за допомогою контролерів втілює саму суть GitOps-підходу — декларативне, кероване управління станом кластерів.

Власний досвід реалізації контролера для управління релізами

Уявіть собі таке...

Десятки команд розробляють сотні застосунків і реалізують нові функції щодня. Середовище має доволі високу складність через залежності. Реліз команді потрібно випустити release bundle (пакет артефактів і метаданих, готових до релізу — release candidates) з двох десятків аплікації в прод. Реліз може містити бізнес-застосунки (мікрофронтенди, бекенди), Argo Workflows і Rollouts, різні допоміжні сервіси та інфраструктурні компоненти, такі як Jobs та Cron Jobs, а також інфраструктурний код.

Завдання надійно провести всі пов’язані деплойменти та ресурси через середовища (environments), відстежити прогрес і переконатися, що стан релізу відповідає очікуванням.

Команда релізу потребує прозорого стану кожного компонента після деплою — чи він «живий», чи повністю «мертвий». Це критично для підтримки стабільності в умовах великої кількості сервісів, залежностей і частих релізів (декілька разів щодня).

Зростання випереджає ручні операції

У 2022 році ми зіткнулися з важливим викликом: інфраструктура росла швидше, ніж могли встигати процеси напівручного управління. Команда SRE підтримувала все більшу кількість застосунків, і стало очевидно, що існуючі підходи більше не масштабуються.

Більшість інфраструктурних компонентів усе ще управлялися мануально. Процеси промоушн-застосунків були складними, трудомісткими й базувалися переважно на скриптах. Крім того, повністю бракувало підходу self-service, через що інженери SRE були змушені витрачати багато часу на рутинні дії.

Перехід до автоматизованої платформи

Стало зрозуміло, що для того, щоб масштабуватись далі, потрібна зміна парадигми — від «оперейшн» до автоматизованої платформи. Kubernetes вже був фундаментом нашої інфраструктури, і його декларативна модель дозволила представити всі інфраструктурні об’єкти як ресурси Kubernetes. Це дало змогу стандартизувати опис конфігурації, спростити управління та впровадити контроль змін через git.

Існуючі open source-рішення, зокрема FluxCD, Application CRD та Vault Secrets Operator, уже демонстрували переваги такого підходу. Вони стали відправною точкою для побудови більш масштабованої архітектури на базі Kubernetes-контролерів.

Побудова власних контролерів

Щоб реалізувати кастомну логіку, адаптовану під наші потреби, ми почали інтенсивно вивчати та застосовувати golang — мову, на якій побудований Kubernetes. Далі ми звернули увагу на Kubebuilder — фреймворк, що значно спрощує створення контролерів і Custom Resource Definitions, а також на Operator SDK — набір інструментів для побудови Kubernetes-операторів, який зробив розробку доступною навіть без глибокого експертного досвіду в Kubernetes.

Цей перехід дозволив нам закласти основу для повністю автоматизованої платформи з self-service можливостями. Контролери стали ключовим механізмом, який дозволив реалізувати контроль над інфраструктурою, автоматизацію життєвого циклу застосунків та масштабування без втрати якості чи швидкості розгортання.

Чому просто не використати Jenkins?

Так, ми можемо використовувати feature flags, progressive delivery через Flagger, пайплайни CI/CD або навіть мануальний реліз. Але ми пішли іншим шляхом — створили API-first дизайн на базі Kubernetes native підходу.

Це означає, що інтегрувати рішення можна будь-де:

  • системи Platform Engineers, як-от Port, Backstage.
  • ChatOps платформи: Slack, Microsoft Teams чи Discord.
  • сучасні системи MCP-style серверів, агентів та інструментів (tools).

Замість того, щоб перейматися процесом релізу, ви просто робите пуш (push) коду і спостерігаєте, як він автоматично та безпечно розгортається з повною спостережуваністю (observability) та прозорістю, незалежно від кількості кандидатів в релізі.

Що ми реалізували (вже скоро в open source)

Ми розширили Kubernetes за допомогою кастомних ресурсів (CR) та контролерів:

  • Applications — метадані застосунка, application-level health checks, запити та розуміння пов’язаних ресурсів.
  • PromotionPlan — список release candidates, готових до промоушн.
  • Environments — мультикластерне управління застосунками.
  • PromotionFlow — конфігурація релізів в розрізі окремого сервісу.
  • Notifications — будь-які зовнішні виклики, автоматизація та webhooks.
  • RBAC — гранульований доступ на рівні аплікації або сервісів команди.

Процес починається з того, що ми автоматично отримуємо версії сервісів з кожного environment, зберігаємо їх у внутрішній in-memory cache, застосовуємо фільтри, формуємо результат і повертаємо відповідь у вигляді списку реліз-кандидатів — custom resource Promotion Plan.

Коли реліз затверджується (apply), контролер виконує реконсиляцію Promotion Plan:

  • синхронизацію образів між реєстрами одночасно у будь-якому оточені: dev, preview, train, stable, prod..
  • автоматичне унікальне тегування образів, наприклад: присвоєння v1.0.1 timestamp.
  • відслідковує статус розгортання ресурсів в реальному часі (List/Watch).
  • забезпечує нотифікацію визначених каналів щодо статусу релізу.

Всі зміни відстежуються через Flux Image Reflector Controller, який у зв’язці з Image Automation оновлює HelmRelease у git-репозиторії.

Це, своєю чергою, запускає узгодження (reconciliation) Flux Controller, гарантуючи, що стан кластера Kubernetes відповідає бажаній конфігурації. Узгодження відбувається, і в результаті кожен застосунок у Promotion Plan отримує новий стан: успішний або невдалий, а також повний або неповний реліз (success or fail and complete or incomplete release).

З цією архітектурою ми відмовились від статичних списків релізів та генеруємо їх динамічно, забезпечили (дуже) швидкий доступ до актуального стану сервісів за допомогою кешу контролера, додали телеметрію на всі ключові події релізу.

Ключові можливості системи:

  • API для будь-яких інтеграцій — від месенджерів і чат-ботів, внутрішніх систем автоматизації та сповіщень до MCP-агентів.
  • Observability процесу релізу з інтеграцією OpenTelemetry.
  • High Availability через Leader Election, реалізоване через Kubernetes Lease.
  • Рекурсивна синхронізація (reconciliation loop) всіх середовищ (envs) за допомогою Informer для кожного з кластерів.
  • GitOps-автоматизація, яка базується на Flux Controllers.

Інтеграція з рішеннями Platform Engineering та MCP

Port

Гарним прикладом застосування контролерів для систем Platform Engineering є інтеграція з Port. Ми можемо використати crds-exporters контролери, які працюють безпосередньо в кластерах Kubernetes. Один експортер відповідає за певну групу API. Найцікавіше тут те, що експортери працюють на базі тих самих принципів, про які ми говорили раніше: це застосунки на Go, побудовані за класичною схемою з інформерами та контролерами, які відстежують зміни у CRD та передають ці зміни у зовнішні системи.

Ми можемо визначити, які ресурси потрібно експортувати, за допомогою параметра crdsToDiscover. Наприклад, якщо ми хочемо експортувати всі ресурси з API-групи apps.gfk.com, достатньо додати відповідну конфігурацію crd auto discovery.

Контролер виявляє зміни й експортує їх у Port. Це легко перевірити через UI — де можна відстежувати всі зміни об’єктів. Таким чином ми досягаємо повної консистентності між системами.

Developer Portal та автоматизація з Port

Developer-портал містить важливу інформацію про технологічний стек організації, середовища та залежності. Платформа Port дозволяє використовувати ці дані для автоматизації робочих процесів та реалізації бізнес-логіки. Це значно спрощує рутинні завдання і робить організацію більш ефективною та безпечною.

Автоматизація в Port запускається у відповідь на події в інфраструктурі — саме тут і починається «магія» Platform Engineering. Наприклад, коли створюється новий сервіс, додається новий application-ресурс або розгортається PromotionPlan. Ці події можуть запускати заздалегідь визначені бекенд-процеси, що виконують будь-яку логіку — оновлення каталогу застосунків, надсилання сповіщень або provision нових ресурсів.

Це API автоматизація та інтеграція дозволяє:

  • спостерігати за будь-якими CRD через UI.
  • повністю автоматизувати створення, перегляд, моніторинг статусу ресурсів.
  • запускати дії (actions) через API та плагіни на будь-які події (events) в кластерах.

Інтеграція можливостей MCP-сервера в Kubernetes-контролер

Уявіть собі світ, де ваші застосунки можуть «спілкуватися» з AI-агентами, автоматично плануючи свої оновлення та оптимізуючи розгортання.

Це не фантастика — це реальність з Kubernetes -контролером та розширеними можливостями MCP (Model Control Protocol) сервера. Ця інтеграція відкриває нові горизонти для Platform Engineering, перетворюючи рутинні завдання на інтелектуальні процеси.

MCP (Model Context Protocol) — це міст між світом AI та інструментами розробки. Він дозволяє застосункам або інженерним платформам взаємодіяти з мовними моделями або іншими агентами штучного інтелекту через стандартний API, вбудований безпосередньо в інфраструктуру Kubernetes. У поєднанні з кастомним контролером це надає можливість налаштувати «розумну» взаємодію між станом вашого кластера, планом оновлення і відповіддю моделі, що аналізує ризики, пріоритети та залежності.

Завдяки MCP можна реалізувати:

  • AI-асистоване управління релізами: перед промоушн нової версії система надсилає запит до AI, який оцінює вплив змін, можливі конфлікти, пропонує ідеальний час для розгортання.
  • Self-healing сценарії: при виявленні помилки в проді система запускає агент, який аналізує логи, пропонує rollback або патч і оновлює Helm-реліз.
  • Інтелектуальний чат-інтерфейс для розробників: через Slack або Discord розробник може задати питання на кшталт «який статус релізу?», «що змінилось з останньої версії?», «є проблеми в stable?» — і отримати відповідь на основі реального стану ресурсів кластера.

По суті, ви отримуєте повноцінного AI copilot для вашого Kubernetes-контролера — як частину control loop, що бере участь у прийнятті рішень.

Приклад реалізації MCP-серверу вбудованого у реліз-контролер

github.com/mark3labs/mcp-go

MCP — це універсальний словник для AI-агентів. Він забезпечує:

  • Зрозумілу мову спілкування.
  • Чіткі правила взаємодії.
  • Елегантну обробку помилок.
  • Відстеження прогресу.

Кожен інструмент (tools) — це як розумний фільтр, який можна налаштувати під ваші потреби: вибір середовища (dev/stable/prod), тип ресурсу (apps/jobs/argo), пошук за шаблоном, гнучкі фільтри.

У нашому MCP-server, наприклад, ми надаємо три основні інструменти:

  • List: розумний каталог, який показує стан всіх ваших ресурсів.
  • Diff: експерт з порівняння, який допомагає планувати релізи.
  • State: постійний монітор, який відстежує стан ваших застосунків.

MCP-server реалізує інструменти і це виглядає як внутрішній виклик API функцій контролера, але викликає їх за вас MCP-агент, який може бути розміщений будь-де, як в периметрі (kagent), так і поза ним, а також спілкуватися з MCP-серверами та з іншими агентами.

MCP-агент — це ваш інтелектуальний помічник, який «розуміє» як запити користувача, так і складну структуру Kubernetes, GitOps, CI/CD, container registry тощо. Ви можете взаємодіяти з агентом через:

  • CLI.
  • Чат-бот (Slack, Discord, Teams).
  • API.
  • Інтегровану платформу, як-от Port.

Ви просто ставите завдання, а агент самостійно з’ясовує, які кроки треба виконати, які інструменти використати, як перевірити статуси та де отримати актуальні дані. В данному випадку агент може зʼясувати стан версій будь-якого сервісу, зробити накат (promotion), відкат (rollback) або, підключивши додаткових агентів, провести траблшутінг та, найголовніше, пофіксити проблему на інфраструктурі самостійно і незалежно.

Про це я більш детально розповідаю у відео, присвяченому Kagent youtu.be/NHgAttlTTgc.

Сьогодні я активно експериментую з MCP-серверами та агентами, що надають єдину інтелектуальну точку керування інфраструктурою та релізами. Використовуючи LLM/SLM-моделі та отримані від MCP-серверів інструменти, агенти можуть автоматизувати складні SRE-процеси, інтегруватися з чатами, платформами та CI/CD, забезпечувати прозорість завдяки OpenTelemetry.

Усе це дозволить командам швидко, безпечно та ефективно управляти життєвим циклом застосунків та інфраструктурою вже у найближчому майбутньому!

👍ПодобаєтьсяСподобалось11
До обраногоВ обраному8
LinkedIn
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

Дякую автору. Здається декілька разів Model Context Protocol був названий Model Control Protocol (можливо це щось інше — а не те що викотив Anthropolc)?
Також цікаво було би побачити порівняння мейнстрім IDP реалізацій (особливо з точки зору трудозатратності кожного для команди devops) — e.g. Backstage+ Himanitec vs Port+ (що там на бекенді повинно бути), там ще якийсь від Attlassian є.

Дякую, Fixed! звичайно «Context» (помилка автоматичного перекладу, адже оригінал робив англійською). Щодо IDP, дякую, є можливість порівняти Port та Backstage, адже останній інтегрують колеги і там, на справді, все виглядає не так «весело» як з Port, з яким експериментую я але є нюанси. Дякую за ідею, подумаю що можна винести в паблік. З Himanitec добре і персонально знайомі але досвіду впровадження не маємо поки.

А чому не використовували Zapier або n8n?
Обидва інструменти добре підходять для автоматизації нотифікацій (через Slack, email тощо) на основі подій, які можуть бути ініційовані кастомним контролером (наприклад, через webhook).
Інтеграція з чат-ботами для Zapier та n8n мають інтеграції з платформами обміну повідомленнями (Slack, Discord, Teams), які можна використовувати для створення інтерфейсів для взаємодії з реліз-системою, хоча і не на рівні прямого MCP-агента.
Запуск дій (actions) в Platform Engineering інструментах (Port) Zapier та n8n можуть використовувати API Port для запуску автоматизацій на основі подій в Kubernetes (знову ж таки, ймовірно, через webhook).

два платних продукти замість innersource? щодо нотифікацій це одна ліба насправді і наприклад opsgenie як універсальний проксі.

Вот моя реализация mas-agent-orchestrator-jim.lovable.app что скажите? Интересно узнать мнение специалистов и практиков, я студент, поэтому разумная критика приветствуется

Не вистачає about або Readme для повного розуміння

Дійсно, MAS пропонує більш гнучкий, масштабований та незалежний спосіб інтеграції AI-функціональності в Kubernetes-екосистему, що полегшує управління AI-моделями, їхнє перевикористання та оновлення. Підхід автора, що був описан у статті робить акцент на більш тісній інтеграції AI з логікою управління Kubernetes, що може бути вигідним у певних специфічних сценаріях.

Денис, чудова стаття. Є над чим подумати. Дякую!

дякую за відгук, ще напрацьовуємо досвід з agentgateway (www.solo.io/...​and-introduces-agent-mesh) і буду ділитися згодом.

Підписатись на коментарі