Kubernetes Operators Vocabulary: CRDs, Controllers, and Operator Patterns (англійською)
Нетипові визначення ресурсів, контролери, оператор SDK, цикл узгодження і словник операторів Kubernetes для інженерів платформи.
Якщо ви працюєте над інженерією платформи, надійністю сайту або DevOps у компанії, що використовує Kubernetes, ви майже напевно чули, як хтось каже: « нам слід написати оператора для цього ». Але словниковий запас навколо операторів Kubernetes дуже щільний — CRD, цикли примирення, фіналізатори, webhooks — і якщо ви не є носієм англійської мови, розрив між розумінням технології і швидким обговоренням архітектури може здатися великим. Ця стаття містить основну термінологію, яка вам потрібна для впевненого участі у таких розмовах.
Основні твори: «Блоки»
** Операторний шаблон ** - метод розширення Kubernetes за допомогою кодування операційних знань людського експерта (оператора «другого дня») в програмне забезпечення. Оператор стежить за кластером на предмет певного типу ресурсів і діє так, щоб утримувати його у бажаному стані, так само, як це робив би людина.
“Ми продовжуємо робити ті ж самі вручну кроки кожен раз, коли ми оновлюємо базу даних. Давайте закодуємо цю логіку в оператор, щоб кластер міг обробляти її автоматично»
«Операторний шаблон насправді є просто «контролерами плюс знаннями про домен» — як тільки ви побачите це таким чином, це клацає»
Custom Resource Definition (CRD) — розширення API Kubernetes, яке дозволяє визначати власні типи ресурсів. CRD повідомляє Kubernetes, що «тепер існує новий тип об’єкта під назвою PostgresCluster» (або що завгодно, що ви виберете). Ви створюєте його один раз, і з цього моменту сервер API приймає об’ єкти цього типу.
«Ми повинні зареєструвати CRD перш ніж хтось може створити
BackupPolicyоб’єкт — API сервер не буде знати, що робити з ним інакше»
“CRD є схемою; нетиповий ресурс є фактичним екземпляром. Не змішуйте їх в документації по дизайну»
** Нетиповий ресурс (CR) ** — екземпляр CRD. Після того, як ви визначите PostgresCluster CRD, кожен окремий кластер, який ви створите — з власною назвою, простором імен і специфікацією — буде нетиповим ресурсом.
«В даний час в виробництві розгорнуті три нетипових ресурси, кожен з яких представляє окремий екземпляр Postgres, яким керує оператор»
Controller — компонент рівня керування, який стежить за об’ єктами Kubernetes і працює над тим, щоб узгодити поточний стан кластера з бажаним станом. Кожна вбудована функція Kubernetes (розгортання, служби тощо) підтримується контролером, а оператори додають свої власні контролери зверху.
«Контролер працює в петлі аварій — він не може з’єднатися з сервером API, тому жоден з нестандартних ресурсів не прирівнюється»
«Ми написали нетиповий контролер, який стежить за
CertificateRequestоб’єктами і автоматично викликає наш внутрішній CA.»
** Реконциліювати петлю ** — основна функція всередині контролера. Kubernetes викликає цю функцію неодноразово (або коли щось змінюється) і передає їй поточний стан. Робота контролера полягає в тому, щоб порівняти цей стан з бажаним станом і зробити будь-яку дію, необхідну для заповнення прогалини.
«Ваш цикл примирення повинен бути ідемпотентним — якщо він запускається десять разів на тому ж об’єкті, він повинен давати той же результат кожен раз»
«Ми додали рядок журналу на початку циклу примирення, щоб ми могли побачити, як часто він запускається.»
** Бажання стану проти спостереження стану ** — « бажання стану » — це те, що ви оголосили (спеціфікація у вашому YAML); « спостереження стану » — це те, що фактично виконується у кластері (стан). Вся модель Kubernetes побудована на постійному керуванні спостережуваного стану до бажаного стану.
«Спостережуваний стан показує три репліки, але бажаний стан — п’ять — контролер повинен масштабуватися, давайте перевіримо, чому це не так»
«Kubernetes є декларативним саме тому, що ви виражаєте бажаний стан і дозволяєте контролерам управляти тим, як до нього дістатися»
Схеми та інструменти
kubebuilder — офіційний проект Kubernetes SIG, який надає скелет, генерацію коду і шаблони найкращих практик для операторів будівництва в Go. Запуск kubebuilder init і kubebuilder create api створює контролер boilerplate, CRD- маніфести і тестовий набір для вас.
«Використовуйте kubebuilder, якщо ви пишете оператор в Go — він обробляє всі леса і зберігає ваш проект у відповідності з конвенціями початкового коду.»
Книга kubebuilder є щільною, але це канонічна посилання; перегляньте її перед вашим першим оператором спринту
Operator SDK — фреймворк від Red Hat (частина проекту Operator Framework), який підтримує запис операторів у Go, Ansible або Helm. Він обгортає kubebuilder для операторів Go і додає інструменти для пакування і розповсюдження операторів через OLM.
«Operator SDK дає вам абстракцію вищого рівня, ніж raw kubebuilder — корисно, якщо ваша команда більше впевнена в Ansible, ніж в Go.»
«Ми використовували режим оператора Helm оператора Operator SDK, щоб обгорнути нашу існуючу діаграму Helm, щоб вона поводилася як правильний оператор»
** controller- runtime ** — бібліотека Go, яка є основою як для kubebuilder, так і для пакета SDK оператора. Він забезпечує Manager, інтерфейси порівняння, фільтри подій і кеши клієнтів, від яких залежить більшість операторів Go. Ви рідко викликаєте його безпосередньо, але він завжди знаходиться у дереві залежностей.
«Ця помилка є в ешелоні кешування контролера-запуску — це не кешування оновлення стану підресурсів, тому наш порівнювач діє на застарілих даних»
Manager — об’ єкт верхнього рівня у режимі виконання контролера, який є власником кешу, клієнта API і життєвого циклу всіх контролерів, що виконуються у двовимірному файлі одного оператора. Зазвичай, ви створюєте один менеджер для кожного оператора і реєструєте контролери за допомогою цього менеджера.
Менеджер відповідає за вибори лідерів — тільки один під буде активно примирюватися в один момент, що уникає проблем з розділенням мозку
«Ми реєструємо всі три контролери з одним менеджером, тому вони діляться одним кешом інформатора і зменшують навантаження на сервер API»
Розподіл і поведінка під час виконання
** Оператор Lifecycle Manager (OLM) ** - компонент Kubernetes, який керує встановленням, оновленням і життєвим циклом самих операторів. Він вводить такі поняття, як ClusterServiceVersion, Subscription, і InstallPlan, щоб оператори могли бути встановлені і оновлені в контрольований, аудиторний спосіб.
«OLM обробляє оновлення оператора — замість
kubectl apply-ing нового розгортання вручну, ви оновлюєте підписку і OLM координує розгортання.»
Якщо OLM не встановлено в кластері, ви не можете використовувати OperatorHub — вам потрібно буде встановити операторів вручну
operatorhub.io — публічний каталог спільноти та сертифікованих операторів, який підтримується Red Hat і більшою спільнотою Kubernetes. Це еквівалент реєстру пакунків, але для операторів.
«Перед тим, як ми збудуємо один з нуля, давайте перевіримо operatorhub.io — там, ймовірно, вже є підтримуваний оператор для Kafka.»
** Тригер, заснований на рівні, проти тригера, заснованого на краї ** — два підходи до вирішення, коли контролер повинен діяти. Термін « заснований на межах » означає « діяти, коли щось змінюється »; « заснований на рівнях » означає « діяти за поточною ситуацією, незалежно від того, як ви до неї дійшли ». Kubernetes наголошує на рекомендації використання методу заснованого на рівнях, оскільки він надає більше можливостей для запобігання пропущеним подіям.
“Не пишіть контролер на основі краю - якщо оператор перезавантажиться, він пропустить події і ніколи не відновиться. Завжди використовуйте логіку на основі рівнів у вашому порівнювачі»
«Засноване на рівні, тому ваша функція примирення повинна перечитувати стан з сервера API, а не покладатися на вантаж події.»
Finalizer — рядок, розміщений в полі metadata.finalizers об’єкта, який запобігає Kubernetes від вилучення об’єкта до тих пір, поки не буде вилучено названий фіналізатор. Контролери використовують фіналізатори для виконання логіки очищення (вилучення хмарних ресурсів, анульування сертифікатів) перед тим, як об’ єкт зникне.
«Ми додали фіналізатор, щоб коли хтось вилучає
DatabaseClusterCR, оператор має шанс зробити остаточне резервне копіювання перед тим, як хмарний екземпляр буде завершений»
«Ніколи не забувайте видаляти ваш фіналізатор у шляху вилучення циклу примирення — інакше ваші нетипові ресурси застрягнуть у стані
Terminatingназавжди»
Webhook (прийняття / зміна / перевірка) — зворотні виклики HTTP, які Kubernetes викликає під час циклу життя запитів API. * webhook * може модифікувати вхідні об’єкти (наприклад, ввести sidecar). * webhook для перевірки прийняття * може відкидати об’ єкти, які не відповідають правилам. Оператори часто надсилають webhooks разом зі своїми контролерами.
«Мутуючий webhook встановлює типові значення на CR перед тим, як його зберігати, тому контролер не повинен обробляти відсутні поля.»
«Наш перевіряючий webhook відкидає будь-який
BackupPolicy, який не вказує період зберігання — ми намагаємося це зробити в час прийому, а не дозволяємо поганим конфігураціям досягати контролера»
Як використовувати ці терміни в розмові
Після того, як ви вмітимете цей словник, вам доведеться використовувати його природно під час обговорень команди, переглядів коду і зустрічей з архітекторами. Декілька шаблонів, які регулярно з’ являються:
- При запропонуванні автоматизації: * “Замість написання цього в конвеєрі, ми могли б моделювати його як CRD і написати контролер - таким чином бажаний стан живе в кластері і цикл примирення обробляє дрейф.” *
- При перегляді коду оператора: “Цей контролер базується на рівні? Я хочу переконатися, що він відновлюється правильно, якщо оператор під перезапускається в середині примирення. ”
- Під час зневадження застряглого ресурсу: “Check
kubectl get <resource> -o yaml— якщо в метаданих є фіналізатор і встановлено часовий штамп вилучення, шлях очищення контролера не завершується.” - При обговоренні розповсюдження: “Чи ми відправляємо це через OLM або просто сирі манифести? Якщо в клієнтських кластерах встановлено OLM, пакування operatorhub.io варте зусиль.”
Краткий справочник
| Term | One-line definition |
|---|---|
| Operator pattern | Encoding human operational knowledge into a Kubernetes controller |
| CRD | Schema that registers a new resource type in the Kubernetes API |
| Custom resource (CR) | An instance of a CRD — your actual workload object |
| Reconcile loop | The idempotent function a controller calls to drive observed → desired state |
| Finalizer | A guard that blocks object deletion until clean-up is confirmed |
| Mutating webhook | Admission hook that can modify objects before they are persisted |
| Validating webhook | Admission hook that can reject non-compliant objects |
| OLM | Operator Lifecycle Manager — installs and upgrades operators themselves |
| kubebuilder / Operator SDK | Scaffolding frameworks for writing Go operators |
| Level-based trigger | Controller acts on current state, not just change events — resilient to restarts |