Анатомия «Штурвала»: как устроена магия управления кластерами изнутри
Почему одного Cluster API мало для жизненного цикла кластера и какую роль играют Cluster Manager, Init Job и связка cert-manager ↔ вебхуки ↔ CNI.
-
- Введение: состояние NotReady и скелет без нервной системы
- Cluster Manager и Init Job: как обойти лимиты метаданных
- Почему Cert-manager — это «голова», или смертельный deadlock
- CCM и Provider ID: связываем виртуальные сущности с реальностью
- ClusterInfo и ClusterProfile: контроль и глубокая кастомизация
- Искусство разрушения: как не оставить «призраков» в облаке
- Заключение: репликаторы и светлое будущее
На этой странице
-
- Введение: состояние NotReady и скелет без нервной системы
- Cluster Manager и Init Job: как обойти лимиты метаданных
- Почему Cert-manager — это «голова», или смертельный deadlock
- CCM и Provider ID: связываем виртуальные сущности с реальностью
- ClusterInfo и ClusterProfile: контроль и глубокая кастомизация
- Искусство разрушения: как не оставить «призраков» в облаке
- Заключение: репликаторы и светлое будущее
Приветствую, коллеги. Продолжаем наш технический сериал. В прошлый раз в материале «Как Штурвал управляет облаками» мы разобрали, как Cluster API (CAPI) и его инфраструктурные провайдеры «дергают» виртуализацию, чтобы создать виртуалки и превратить их в узлы. Сегодня перейдем ко второму акту нашего марлезонского балета — тому, что происходит «под капотом» платформы «Штурвал», когда облако уже выдало нам ресурсы.
Разберемся, почему стандартного CAPI недостаточно для жизни и почему без правильной последовательности инициализации ваш кластер так и останется бесполезной грудой запущенных бинарников.
Введение: состояние NotReady и скелет без нервной системы
Представьте: CAPI отработал, виртуалки созданы, на них закрутились пять стандартных бинарников (kubelet, apiserver, controller-manager, etcd и scheduler). Если вы сделаете kubectl get nodes, вы увидите заветную мастер-ноду, но в статусе NotReady.
Проблема в том, что в кластере нет сети. Мы намеренно не ставим CNI через прокси на этапе базового развертывания. CAPI дает нам только «скелет». Роль «доводчика», который натягивает на этот скелет мышцы и нервную систему, берет на себя «Штурвал». И главным дирижером здесь выступает Cluster Manager.
Cluster Manager и Init Job: как обойти лимиты метаданных
Как только базовый куб оживает в минимальном виде, в управляющем кластере (Management Cluster) просыпается Cluster Manager. Его задача — инициировать первую волну деплоя через ресурс ClusterConfig.
Для этого используется механизм Init Job.
- Что это: это под в новом кластере с образом, содержащим Helm и
kubectl. - Зачем: почему мы не запихиваем всё в Cloud-init? Потому что Cloud-init не резиновый. У провайдеров вроде Basis или vDirector есть жесткие лимиты на объем метаданных (иногда это жалкие 10 КБ). Попытка пропихнуть туда тяжелые манифесты чартов мониторинга или CRD, которые весят мегабайты, приведет к «метадатному голоданию» — тачка просто не прожует такой конфиг.
Init Job — это наш способ избежать этого ограничения и раскатать базу в цикле. На этом этапе ставятся:
- Cert-manager (критически важен для выживания);
- CNI (чтобы ноды наконец ожили);
- SSC (Shturval Service Config) и NCI (Node Config Interface);
- SSP (Shturval Service Patch) — для последующей доконфигурации, если параметры изменятся.
Почему Cert-manager — это «голова», или смертельный deadlock
Часто спрашивают: «Зачем нам Cert-manager в первые секунды?». Без него вы попадете в классический архитектурный тупик (deadlock).
Современный Kubernetes завязан на вебхуки (Validating и Mutating). Например, когда вы создаете Ingress или AcmeConfig, API-сервер должен спросить у оператора: «А это вообще валидный конфиг?». Чтобы никто не подменил ответ и не влез в середину процесса (защита от «левых» сервисов, правящих спеки подов на лету), Kubernetes требует строгого TLS-соединения для вебхуков.
Цепочка зависимостей выглядит так:
- Нет Cert-manager — нет валидных сертификатов для вебхуков.
- Нет TLS — API-сервер отказывается общаться с мутирующими вебхуками.
- Без вебхуков ресурсы операторов (включая CNI) будут просто отбиваться как некорректные.
Итог: CNI не поднимется, ноды останутся в NotReady, кластер — «тыква».
CCM и Provider ID: связываем виртуальные сущности с реальностью
Чтобы магия CAPI работала, управляющий кластер должен четко понимать, какая CAPI Machine в его манифестах соответствует реальной Node в клиентском кластере. Связь идет через Provider ID.
Здесь мы идем «ортодоксальным» путем через CCM (Cloud Controller Manager).
- Безопасность прежде всего: мы запускаем CCM в управляющем кластере (Management Cluster). Почему? Чтобы не хранить облачные креды (пароли от виртуализации) на клиентских нодах. Если злоумышленник «уведет» одну ноду, он не получит доступ к управлению всем вашим облаком.
- Маппинг: CCM вытаскивает ID из облака и проставляет его в статус ноды. Если этот маппинг ломается или провайдер не выдает ID, CAPI впадает в депрессию и не понимает, жива ли машина.
ClusterInfo и ClusterProfile: контроль и глубокая кастомизация
Чтобы не тонуть в «финализерном аду» и не гадать, что происходит, у нас есть ClusterInfo. Это «единое окно» в потроха: здесь собраны статусы инсталляции, ключи, количество CPU на воркерах и состояние всех системных сервисов. Именно из этого ресурса фронтенд «Штурвала» рисует свои графики.
Для стандартизации парка кластеров используется ClusterProfile. Это наш механизм дефолтов (Defaulting Webhook). Самая мощная фишка здесь — возможность привязать к профилю секреты, содержащие произвольные манифесты.
Используя Match Expressions и лейблы, вы можете сказать: «Для всех кластеров в зоне RU-CENTRAL примени вот эти патчи через SSP и докинь эти секреты». Это позволяет кастомизировать инфраструктуру, не трогая основной код оператора.
Искусство разрушения: как не оставить «призраков» в облаке
Удаление кластера — процесс более тонкий, чем создание. Если просто «грохнуть» Namespace, вы получите ворох бесхозных ресурсов в облаке, за которые продолжите платить.
Алгоритм удаления в «Штурвале» построен на защите от дурака:
- SSC в manual: останавливаем попытки контроллеров «починить» то, что мы удаляем.
- Зачистка LoadBalancer: первым делом сносим сервисы с внешними IP, чтобы облако освободило адреса.
- Игнорирование PV: мы осознанно не трогаем Persistent Volumes. Безопасность данных важнее чистоты. Мы лучше заставим админа удалить диск руками, чем наш скрипт из-за опечатки в политике Retain уничтожит три года продакшена.
- Триггер удаления CAPI Cluster: только после этого дается команда на снос виртуалок.
- Garbage Collector и секреты: в Namespace лежат облачные секреты и SSH-ключи, нужные для удаления ресурсов. Если Namespace удалится первым — всё, вы потеряли ключи от квартиры, где лежат деньги (и виртуалки). Наш GC ждет лейбла
garbage-collectи финалайзеров CAPI, и только когда облако подтвердит «чисто», он сносит Namespace под ноль.
Заключение: репликаторы и светлое будущее
Платформа растет. В версии 2.14 мы перешли от простого «перекладывания» ресурсов к мультинаправленной репликации. Теперь два менеджмент-кластера могут обмениваться данными встречно, а автоматика через «захват» (capture) сама решает, какой из них сейчас является мастером для конкретного набора клиентских кластеров.
В ближайших планах — окончательно похоронить Init Job ради еще более элегантного процесса запуска. А пока — не стесняйтесь заглядывать в статусы ClusterConfig руками, там много интересного о жизни ваших нод!