
Kubernetes полюбился разработчикам своим удобством: описал развертывание, в любой момент изменил параметры — и все работает. Но вот раскатка самих кластеров долгое время оставалась лоскутным одеялом: Terraform, Ansible, десятки плейбуков и пайплайнов. Потерял стейт — и начинается квест.
Cluster API (CAPI) закрыл этот разрыв и за последние годы стал едва ли не стандартом для управления Kubernetes-кластерами. Он превратил развертывание и сопровождение инфраструктуры в такой же декларативный процесс, как деплой приложения.
В нашей платформе «Штурвал» мы уже давно используем Cluster API в продакшене. И довольно быстро стало понятно: это не просто удобный способ развернуть Kubernetes, а смена парадигмы эксплуатации. Но вместе с предсказуемостью приходят новые сложности — от обновлений управляющей плоскости до нетривиальных сценариев отказа. В этой статье разберемся, чем хорош Cluster API, а в чем его подводные камни, о которых обычно узнают уже в ходе эксплуатации.
Cluster API — начало
Идею декларативного управления кластерами Kubernetes предложили инженеры из Heptio в 2017 году. Так появился Cluster API — фреймворк, который расширяет API Kubernetes и вводит новые кастомные ресурсы и контроллеры для описания и управления кластерами.
Он обеспечивает:
декларативную конфигурацию прямо в Kubernetes;
автомасштабирование;
самовосстановление.
Сейчас вокруг Cluster API выросло активное сообщество. На конференциях все чаще звучат доклады про этот фреймворк и его «обвязку», которая позволяет легко создавать кластеры в разных инфраструктурах. Он интегрируется с различными провайдерами вроде AWS и vSphere, востребованными облачными платформами. Сегодня с помощью Cluster API можно без труда развернуть идентичные кластеры, например, в Yandex Cloud и VK Cloud, и управлять ими одинаковым образом.
Как он работает

Фреймворк устроен по тем же принципам, что и Kubernetes: есть ядро, а функционал расширяется за счет провайдеров. В Cluster API выделяют три их типа:
Control Plane — отвечает за жизненный цикл управляющих компонентов кластера (например, добавление или удаление узлов etcd).
Bootstrap — разворачивает конфигурацию control plane и приводит ее к нужному формату через набор контрактов.
Infrastructure — взаимодействует с облаком или «железом»: создает виртуальные машины, балансировщики нагрузки и другие ресурсы.
Каждый провайдер реализует собственную логику и правила, но все они опираются на единый контракт — набор требований к API, ресурсам и их полям.


Как все связано
Базовая схема взаимодействия выглядит так: слева — Control Plane, справа — машины. Корневая точка — кластер (CAPI-кластер). Он же описывает сущность, с которой мы работаем, но одного его недостаточно — нужны дополнительные ресурсы.

Control Plane — в Cluster API используется провайдер kubeadm Control Plane (дефолтный для Bootstrap и Control Plane). Он напоминает StatefulSet, так как необходимы учет кворума и специальный алгоритм работы с возможными нюансами. Например, при добавлении узла он регистрирует его участником etcd, а при удалении — корректно выводит из состава участников.
Машины — управляются через Machine Deployment, Machine Set и Machine. Работают как Deployment с шаблонами и спецификациями и проще управляются. Спецификации зависят от конкретного инфраструктурного провайдера и вынесены в отдельный ресурс <Infrastructure>MachineTemplate. Например, в VK Cloud указываются размеры машин, а в Yandex Cloud — поколение процессоров, число ядер, память и прочее. Для настройки kubelet и дополнительных параметров используется <Bootstrap>ConfigTemplate.
Список провайдеров постоянно расширяется, на момент написания статьи поддерживаются:
Bootstrap
K3s — подходит для кластера с двумя мастерами, так как не имеет в основе etcd.
Talos — вся работа выстраивается через API, формат конфигурации отличается от остальных.
Control Plane
Nested — control plane в подах кластера управления.
Список инфраструктурных провайдеров еще длиннее. Однако в официальной документации опубликованы далеко не все: например, там нет Yandex Cloud, хотя он доступен на GitHub. Ниже я выделил наиболее полезные варианты и описал, в каких случаях их можно использовать.
Infrastructure
Bring Your Own Host (BYOH) и k0smotron RemoteMachine (SSH) — когда нет прямого доступа к виртуализации или используется платформа со «специфическим» API.
KubeVirt — «матрешка», позволяет разворачивать Kubernetes-кластеры поверх в виртуальных машинах внутри Kubernetes.
Metal3 — специфический провайдер, который я ценю за реализацию не только PXE, но и Redfish: он дает возможность работать с физическими серверами через BMC и «бутстрапить» их напрямую.
Nested — позволяет поднимать кластер внутри Kubernetes с помощью контейнеров.
OpenStack — подходит тем, кто хочет написать собственного инфраструктурного провайдера. Примечание от автора: а еще его документация читается почти как приключенческий роман.
vcluster — дает разработчикам виртуальные кластеры так, что они почти не замечают, что работают внутри другого.
vSphere — один из первых провайдеров, поэтому внутри немало legacy, но в плане использования остается стабильным.
В чем подвох
Cluster API не про сервисы. Он может создать «голый» кластер: пять бинарей Kubernetes, правильные версии kubelet, API-сервера и все. Сетку, мониторинг, логирование, CNI нужно ставить отдельно. Есть вспомогательные инструменты ClusterResourceSet и Helm Addon Operator, но они работают только при запуске кластера, а полноценного lifecycle-менеджмента нет, все приходится делать вручную. Мы написали свой оператор, который управляет профилями и конфигурациями кластеров на всех этапах жизненного цикла кластера.
Ненадежное управление сетью. Предполагается, что инфраструктура предоставляет DHCP в сети узлов. Если его нет — нужны костыли вроде IP Address Management (IPAM), которые позволяют выдавать диапазон внутри. Получается уже не так декларативно, как хотелось бы.
Штатное обновление через пересоздание узлов. В спецификации задается версия Kubernetes, ее обновления будут постоянно триггерить rollout. Не все бывают к этому готовы. Первый шаг к обходу этого нюанса сделан в Cluster API 1.12, но инфраструктурным провайдерам еще предстоит реализовать хуки обновления. В «Штурвале» мы сделали несколько вспомогательных операторов. Один из них может обновить кластер, даже если кластера управления больше нет. Второй синхронизирует версии и статусы в кластере управления с фактическим состоянием кластера.
Отказ Cluster API != отказ кластера. У нас есть единая точка, из которой мы всем управляем — кластер, в котором запущен Cluster API. Запустить его можно даже на minikube. Архитектура самого по себе Cluster API во всех реализациях (кроме Rancher) не является единой точкой отказа (SPOF): minikube можно выключить, при этом инфраструктурные кластеры продолжат работать. С GitOps-подходом манифесты хранятся в git, что позволяет легко воссоздать конфигурацию кластера. Это реально удобно — наши заказчики так и делают: нужно воспроизвести окружение один в один — просто берем из git, и все работает.
Делать бэкапы мало. События последних месяцев снова показали: недостаточно просто делать резервные копии — нужно регулярно проверять, что восстановление из них действительно работает. Например, мы реализуем Disaster Recovery (DR) с помощью Velero (подробности описаны в доке). У нас есть два кластера — так называемые менеджменты — в каждом из которых есть Cluster API. С помощью backup restore можно реплицировать ресурсы между ними. Таким образом, в случае катастрофы управление сохраняется и продолжает работать, как и прежде.
Не всегда готовые провайдеры. Провайдеров много, но качество у них разное. Иногда приходится дорабатывать самому. Однако сами провайдеры писать несложно, если у инфраструктуры есть нормальное API и Go SDK, то базовый провайдер можно собрать за пару дней. Например, в «Штурвале» есть кастомные провайдеры под vSphere, oVirt (и подобные платформы виртуализации: РЕД Виртуализация, zVirt, HOSTVM, ROSA Virtualization), Basis Dynamix, OpenStack, VK Cloud, Yandex Cloud, vCloud Director и другие.
Выводы
Cluster API позволяет управлять кластерами так же, как мы управляем подами. Фреймворк помогает сделать плавный переход с западных облаков на отечественные платформы виртуализации. Все процессы, которые строились в одной инфраструктуре, легко переносятся в другую — если есть провайдер, всё заработает без боли.
Но это не «волшебная кнопка». Он решает задачу управления инфраструктурой Kubernetes-кластеров, но не сервисов внутри. Всё это остается вашей заботой. И именно там обычно скрывается основная сложность эксплуатации: кластер поднялся за 15 минут, а привести его к рабочему состоянию всё ещё занимает часы. Поэтому важно думать, как мы управляем системными сервисами — что у нас будет происходить с конфигурацией кластера.
Блеск Cluster API — в унификации и автоматизации. Нищета — в том, что до production-ready-состояния всегда придется допиливать что-то свое, в особенности в части сервисов кластера.
Когда Cluster API — находка:
Если у вас десятки кластеров и несколько облаков / ЦОДов.
Если строите GitOps-процессы.
Если хотите уйти от «зоопарка» решений: Terraform + Ansible + скрипты.
Когда может быть лишним:
Для одного кластера. Управлять кластером изнутри тоже можно, но нужно разобраться.
Когда нет возможности разобраться. Cluster API требует внимания и понимания.
Полезные материалы:
Александр Краснов
СТО платформы «Штурвал»
