Pull to refresh
11.07

DIY: Ваше собственное облако на базе Kubernetes (часть 3)

Reading time8 min
Views5.8K

Вот мы и подобрались к самому интересному - запуску Kubernetes в Kubernetes. В этой статье мы поговорим о таких технологиях как Kamaji и Cluster API, а так же о том как интегрировать их с KubeVirt.

В прошлых статьях мы уже рассказывали как мы готовим Kubernetes на bare metal, и о том как превратить Kubernetes в средство запуска виртуальных машин. Эта статья завершает серию, объясняя как используя всё вышеперечисленное можно построить полноценный managed Kubernetes и запуск виртуальных Kubernetes-кластеров по клику.

И начнём мы, пожалуй с Cluster API.

Cluster API

Cluster API является расширением для Kubernetes, которое дает возможность управлять Kubernetes-кластерами как custom resources внутри другого Kubernetes-кластера.

Основная задача Cluster API — предоставить унифицированный интерфейс для описания основных сущностей Kubernetes-кластера и управлять их жизненным циклом. Это позволяет автоматизировать процессы создания, обновления, и удаления кластеров, упрощая масштабирование и управление инфраструктурой.

В контексте Cluster API есть два типа понятия: management кластер и tenant кластер.

  • Management кластер представляет собой Kubernetes кластер, который используется для развертывания и управления другими кластерами. Этот кластер содержит все необходимые компоненты Cluster API и отвечает за описание, создание, и обновление tenant кластеров и зачастую используется только для этого.

  • Tenant кластеры - это пользовательские кластеры или кластеры, развернутые с помощью Cluster API. Их создание происходит путем описания соответствующих ресурсов в management кластере. Уже они используются для развертывания приложений и сервисов конечными пользователями.

Важно понимать, что физически tenant кластера не обязательно должны запускаться на инфраструктуре management-кластера, а чаще запускаются как раз наоборот где-то в другом месте.

Для своей работы Cluster API использует концепцию "провайдеров", под которыми понимаются отдельные контроллеры, отвечающие за конкретные компоненты создаваемого кластера. В рамках Cluster API существует множество типов провайдеров. Основные из них это:

  • Infrastructure Provider, который отвечает за предоставление вычислительной инфраструктуры, такой как виртуальные машины или физические сервера.

  • Control Plane Provider, который предоставляет Kubernetes control plane, а именно компоненты kube-apiserver, kube-scheduler и kube-controller-manager.

  • Bootstrap Provider, который используется для генерации cloud-init конфигов для создаваемых виртуальных машин и серверов.

Для начала, вам потребуется установить сам Cluster API и по одному провайдеру каждого типа. Полный список поддерживаемых провайдеров вы можете найти в документации проекта.

Для установки можно использовать утилиту clusterctl, или более декларативный метод с помощью  Cluster API Operator.

Выбор провайдеров

Infrastructure Provider

Мы выбрали KubeVirt в качестве Infrastructure Provider - потому что для организации виртуальной среды мы используем KubeVirt и хотим запускать виртуальные машины для воркеров прямо внутри нашего management-кластера.

Control Plane Provider

Проект Kamaji предлагает готовое решение для запуска control-plane Kubernetes для tenant-кластеров в виде контейнеров внутри management-кластера. Этот подход имеет ряд весомых преимуществ:

  • Экономичность: Запуск control-plane в контейнерах позволяет избежать использования отдельных control-plane нод для каждого кластера, тем самым существенно уменьшая затраты на инфраструктуру.

  • Стабильность: Упрощение архитектуры за счет исключения сложной многоуровневой схемы развертывания. Вместо последовательного запуска виртуальной машины и последующей установкой etcd и компонентов Kubernetes внутри неё, у вас есть простой control-plane, который разворачивается и запускается как обычное приложение внутри Kubernetes и управляется оператором.

  • Безопасность: control-plane кластера скрыт от конечного пользователя что уменьшает возможность вывода из строя его компонентов, а также исключает доступ пользователя к хранилищу сертификатов кластера. Такой подход организации невидимого пользователю control-plane часто применяется облачными провайдерами.

Bootstrap Provider

Kubeadm в качестве Bootstrap Provider - как стандартный способ подготовки кластеров в Cluster API. Этот провайдер развивается как часть самого Cluster API. Для своей работы он требует только наличие подготовленного образа системы с установленным kubelet и kubeadm и позволяет генерировать конфиги в формате cloud-init и ignition.

В целом мы довольно много колебались между выбором Talos Linux и Kamaji+Kubeadm для запуска кластеров в Cluster API, но всё-таки решили сделать в пользу второго решения. Преимущественно из-за возможности запуска control-plane в контейнерах, а не отдельных виртуальных машинах.

Как с этим работать

Основным объектом в Cluster API является ресурс Cluster, который является родительским для всех остальных. Как правило этот ресурс ссылается на два других: ресурс описывающий control plane и ресурс описывающий infrastructure, каждый из них управляется отдельным провайдером.

В отличие от Cluster эти два ресурса не стандартизированы и их kind зависит от конкретного используемого вами провайдера:

В рамках Cluster API существует также ресурс под названием MachineDeployment, который описывает группу узлов (нод), будь то физические сервера или виртуальные машины. Этот ресурс работает аналогично стандартным Kubernetes ресурсам, таким как Deployment, ReplicaSet и Pod, предоставляя механизм для декларативного описания группы узлов и автоматического масштабирования.

Другими словами ресурс MachineDeployment позволяет вам декларативно описывать ноды для вашего кластера, автоматизируя их создание, удаление и обновление в соответствии с заданными параметрами и запрошенным числом реплик.

Для создания машин, MachineDeployment ссылается на шаблон для генерации самой машины и шаблон для генерации её cloud-init конфига:

Таким образом чтобы развернуть новый Kubernetes-кластер с помощью Cluster API, вам потребуется подготовить следующий набор ресурсов:

  • Общий ресурс Cluster

  • Ресурс KamajiControlPlane, отвечающий за control-plane запускаемый Kamaji

  • Ресурс KubevirtCluster, описывающий конфигурацию кластера в KubeVirt

  • Ресурс KubevirtMachineTemplate, отвечающий за темплейт виртуалки

  • Ресурс KubeadmConfigTemplate, отвечающий за генерацию токенов и cloud-init

  • Как минимум один MachineDeployment для создания хоть каких-то воркеров

В большинстве случаев этого достаточно, но в зависимости от используемых провайдеров, вам могут понадобиться и другие ресурсы. Примеры создаваемых ресурсов для провайдеров каждого типа вы можете найти в документации проекта Kamaji

Доводим кластер до ума

На этом этапе у вас уже есть готовый tenant Kubernetes кластер, но пока что в нём нет ещё ничего кроме API воркеров и нескольких core-плагинов, которые стандартно включены при установке любого Kubernetes-кластера: это kube-proxy и coredns. Для полноценной интеграции вам потребуется установить в него ещё несколько компонентов:

Для установки дополнительных компонентов вы можете воспользоваться отдельным Cluster API Add-on Provider for Helm, или всё тем же FluxCD.

При создании ресурсов в FluxCD есть возможность указать целевой кластер сославшись на kubeconfig сгенерированный Cluster API. Тогда установка будет выполняться непосредственно в него. Таким образом, FluxCD становится универсальным инструментом для управления ресурсами как в management-кластере, так и в пользовательских tenant-кластерах.

О каких компонентах идёт речь? В общем случае их набор следующий:

CNI Plugin

Чтобы обеспечить связь между подами в tenant-Kubernetes кластере, необходимо развернуть CNI-плагин. Этот плагин формирует виртуальную сеть, позволяющую подам взаимодействовать друг с другом, и традиционно разворачивается как Daemonset на рабочих узлах кластера. Вы можете выбрать и установить любой CNI-плагин, который сочтете подходящим.

Cloud Controller Manager

Основная задача Cloud Controller Manager (CCM) - это интеграция Kubernetes с облачной инфраструктурой провайдера (в нашем случае - её роль выполняет родительский Kubernetes-кластер в котором запускаются все виртуальные машины дочернего Kubernetes-кластера), вот несколько задач которые он выполняет:

  1. Когда создается сервис с типом LoadBalancer, CCM инициирует процесс создания облачного балансировщика нагрузки, который направляет трафик на ваш Kubernetes-кластер.

  2. Если из облачной инфраструктуры удаляется нода, CCM обеспечивает её удаление и из вашего кластера, поддерживая актуальное состояние кластера.

  3. При использовании CCM, ноды добавляются в кластер со специальныи таинтом node.cloudprovider.kubernetes.io/uninitialized что позволяет обрабатывать дополнительную бизнес-логику при необоходимости. После успешной инициализации с ноды этот таинт снимается.

В зависимости от облачного провайдера CCM может работать как внутри, так и вне tenant-кластера. 

KubeVirt Cloud Provider спроектирован так, чтобы устанавливается во внешнем родительском management-кластере. Таким образом создание сервисов типа LoadBalancer в tenant-кластере инициирует создание сервисов типа LoadBalancer в родительском кластере, которые направляют трафик внутрь tenant-кластера.

CSI-драйвер

Container Storage Interface (CSI) разделяется на две основные части для взаимодействия с хранилищем в Kubernetes:

  • csi-controller: Этот компонент отвечает за взаимодействие с API облачного провайдера для создания, удаления, подключения, отключения и изменения размера томов.

  • csi-node: Этот компонент запускается на каждой ноде и обеспечивает монтирование томов к подам по требованию kubelet.

В контексте использования KubeVirt CSI Driver, возникает уникальная возможность. Поскольку виртуальные машины (ВМ) в KubeVirt запускаются внутри management Kubernetes-кластера, где доступен полноценный Kubernetes API, это открывает путь для запуска csi-controller за пределами пользовательского tenant-кластера. Такой подход популярен в сообществе KubeVirt и предлагает несколько ключевых преимуществ:

  • Безопасность: Этот метод скрывает внутренний API облака от конечного пользователя, предоставляя доступ к ресурсам исключительно через интерфейс Kubernetes. Таким образом, уменьшается риск непосредственного доступа к управляющему кластеру из пользовательских кластеров.

  • Простота и удобство: Пользователям не нужно управлять дополнительными контроллерами в своих кластерах, что упрощает архитектуру и уменьшает нагрузку на управление.

При этом CSI-node обязательно должен запускаться внутри tenant-кластера, так как он напрямую взаимодействует с kubelet на каждой ноде. Этот компонент обеспечивает монтирование и демонтирование томов в поды, что требует тесной интеграции с процессами, происходящими непосредственно на нодах кластера.

KubeVirt CSI Driver выступает в роли прокси для заказа томов. При создании PVC внутри tenant-кластера, создаётся PVC в management-кластере, затем PV созданные подключается в виртуальную машину

Cluster Autoscaler

Cluster Autoscaler является универсальным компонентом, который может работать с разнообразными облачными API, и его интеграция с Cluster-API — лишь одна из доступных функций. Для корректной настройки ему требуется доступ к двум кластерам: к tenant-кластеру, для отслеживания подов и определения необходимости добавления новых нод, и к управляющему Kubernetes-кластеру (management kubernetes cluster), где он взаимодействует с ресурсом MachineDeployment и корректирует количество реплик.

Хотя обычно Cluster Autoscaler запускают внутри tenant Kubernetes кластера, в данной ситуации мы предлагаем устанавливать его снаружи. Это связано по тем же причинам что мы описывали и выше. Это проще и безопаснее, мы не хотим чтобы пользователи tenant кластеров имели какой-либо доступ к management API management-кластера.

Konnectivity

Есть ещё один дополнительный компонент о котором я хотел бы упомянуть - это Konnectivity. Он, скорее всего понадобится вам чуть позже, для того чтобы у вас заработали вебхуки и API aggregation layer в tenant Kubernetes кластере. Эта тема подробно рассмотрена в одной из моих предыдущих статей.

В отличие от вышепредставленных компонентов. Kamaji, позволяет легко включить Konnectivity и управлять им как одним из core компонентов вашего tenant-кластера, на ряду с kube-proxy и coredns.


Теперь у вас есть полноценный Kubernetes-кластер с возможностью динамического масштабирования, автоматического провижининга томов и балансировщиков нагрузки.

В дальнейшем вы можете рассмотреть вопросы сбора метрик и логов с ваших tenant-кластеров, но это уже выходит за рамки этой статьи.

Разумеется все перечисленные компоненты, необходимые для деплоя Kubernetes-кластера вы можете упаковать в единый Helm-чарт и деплоить как единое приложение. Именно так мы и организуем деплой manged Kubernetes-кластеров по кнопке в нашей свободной PaaS-платформе Cozystack, где вы можете попробовать все описанные в статье технологии совершенно бесплатно.

Tags:
Hubs:
Total votes 10: ↑10 and ↓0+10
Comments4

Articles

Information

Website
aenix.io
Registered
Employees
2–10 employees
Location
Чехия
Representative
Andrei Kvapil