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, и управлять ими одинаковым образом. 

Как он работает  

Архитектура: https://cluster-api.sigs.k8s.io/user/concepts 

Фреймворк устроен по тем же принципам, что и Kubernetes: есть ядро, а функционал расширяется за счет провайдеров. В Cluster API выделяют три их типа:

  • Control Plane — отвечает за жизненный цикл управляющих компонентов кластера (например, добавление или удаление узлов etcd).

  • Bootstrap — разворачивает конфигурацию control plane и приводит ее к нужному формату через набор контрактов.

  • Infrastructure — взаимодействует с облаком или «железом»: создает виртуальные машины, балансировщики нагрузки и другие ресурсы.

Каждый провайдер реализует собственную логику и правила, но все они опираются на единый контракт — набор требований к API, ресурсам и их полям.

Пример требований: https://cluster-api.sigs.k8s.io/developer/providers/contracts/overview

Как все связано 

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

Базовая схема, как все взаимодействует: https://cluster-api.sigs.k8s.io/developer/providers/contracts/overview
Базовая схема, как все взаимодействует: https://cluster-api.sigs.k8s.io/developer/providers/contracts/overview
  • 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

Control Plane

Список инфраструктурных провайдеров еще длиннее. Однако в официальной документации опубликованы далеко не все: например, там нет Yandex Cloud, хотя он доступен на GitHub. Ниже я выделил наиболее полезные варианты и описал, в каких случаях их можно использовать. 

Infrastructure

В чем подвох

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 требует внимания и понимания.

Полезные материалы: 

Александр Краснов

СТО платформы «Штурвал»