DIY: Створіть власну хмару з Kubernetes (Частина 3)

Наближаючись до найцікавішої фази, ця стаття розглядає запуск Kubernetes всередині Kubernetes. Висвітлюються такі технології, як Kamaji та Cluster API, а також їх інтеграція з KubeVirt.

Попередні обговорення охоплювали підготовку Kubernetes на "голому" обладнанні та як перетворити Kubernetes на систему управління віртуальними машинами. Ця стаття завершує серію, пояснюючи, як, використовуючи все вищезазначене, ви можете створити повноцінний керований Kubernetes і запускати віртуальні кластери Kubernetes одним дотиком.

Почнемо з Cluster API.

Cluster API

Cluster API — це розширення для Kubernetes, яке дозволяє керувати кластерами Kubernetes як власними ресурсами користувача всередині іншого кластеру Kubernetes.

Основна мета Cluster API — забезпечити єдиний інтерфейс для опису основних сутностей кластера Kubernetes і управління їх життєвим циклом. Це дозволяє автоматизувати процеси створення, оновлення та видалення кластерів, спрощуючи масштабування та управління інфраструктурою.

У контексті Cluster API є два терміни: кластер управління та кластери користувачів.

  • Кластер управління — це кластер Kubernetes, що використовується для розгортання та управління іншими кластерами. Цей кластер містить всі необхідні компоненти Cluster API та відповідає за опис, створення та оновлення кластерів користувачів. Він часто використовується тільки для цієї мети.
  • Кластери користувачів — це кластери користувачів або кластери, що розгортаються за допомогою Cluster API. Вони створюються шляхом опису відповідних ресурсів у кластері управління. Вони використовуються для розгортання застосунків та сервісів кінцевими користувачами.

Важливо розуміти, що фізично кластери користувачів не обовʼязково повинні працювати на тій же інфраструктурі, що і кластер управління; частіше за все вони розгортаються в іншому місці.

Діаграма, що показує взаємодію кластеру управління Kubernetes та кластерів користувачів Kubernetes за допомогою Cluster API

Діаграма, що показує взаємодію кластеру управління Kubernetes та кластерів користувачів Kubernetes за допомогою Cluster API

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

  • Провайдер інфраструктури, який відповідає за надання обчислювальної інфраструктури, такої як віртуальні машини або фізичні сервери.
  • Провайдер панелі управління, який надає панель управління Kubernetes, а саме компоненти kube-apiserver, kube-scheduler та kube-controller-manager.
  • Провайдер Bootstrapping, який використовується для створення конфігурацій cloud-init для віртуальних машин та серверів, що створюються.

Щоб почати, вам потрібно буде встановити сам Cluster API та одного провайдера кожного типу. Повний список підтримуваних провайдерів можна знайти в документації проєкту Cluster API.

Для встановлення можна використовувати утиліту clusterctl або Cluster API Operator як більш декларативний метод.

Вибір провайдерів

Провайдер інфраструктури

Для запуску кластерів Kubernetes за допомогою KubeVirt, необхідно встановити Infrastructure Provider KubeVirt. Він дозволяє розгортання віртуальних машин для робочих вузлів у тому ж кластері управління, де працює Cluster API.

Провайдер панелі управління

Проєкт Kamaji пропонує готове рішення для запуску панелі управління Kubernetes для кластерів користувачів як контейнерів у кластері управління. Цей підхід має кілька суттєвих переваг:

  • Економічність: Запуск панелі управління в контейнерах запобігає використанню окремих вузлів панелі управління для кожного кластеру, що суттєво знижує витрати на інфраструктуру.
  • Стабільність: Спрощення архітектури шляхом усунення складних багатошарових схем розгортання. Замість послідовного запуску віртуальної машини, а потім встановлення компонентів etcd та Kubernetes всередині неї, є проста панель управління, яка розгортається і працює як звичайний застосунок всередині Kubernetes та управляється оператором.
  • Безпека: Панель управління кластера прихована від кінцевого користувача, що знижує можливість компрометації її компонентів, а також усуває доступ користувачів до сховища сертифікатів кластера. Такий підхід до організації панелі управління, невидимої для користувача, часто використовують постачальники хмарних послуг.

Провайдер Bootstrapping

Kubeadm як Bootstrapping Provider — стандартний метод підготовки кластерів у Cluster API. Цей провайдер розроблений як частина самого Cluster API. Він вимагає лише підготовленого системного образу з встановленими kubelet і kubeadm і дозволяє генерувати конфігурації у форматах cloud-init та ignition.

Слід зазначити, що Talos Linux також підтримує виділення ресурсів через Cluster API та має провайдерів для цього. Хоча попередні статті обговорювали використання Talos Linux для налаштування кластера управління на вузлах bare-metal, для створення клієнтських кластерів підхід Kamaji+Kubeadm має більше переваг. Він полегшує розгортання панелей управління Kubernetes у контейнерах, усуваючи необхідність окремих віртуальних машин для екземплярів панелі управління. Це спрощує управління та знижує витрати.

Як це працює

Основний обʼєкт у Cluster API — це ресурс Cluster, який виступає як батьківський для всіх інших. Зазвичай цей ресурс посилається на два інші: ресурс, що описує панель управління, та ресурс, що описує інфраструктуру, кожен з яких управляється окремим провайдером.

На відміну від Cluster, ці два ресурси не є стандартизованими, і їх тип залежить від конкретного провайдера, якого ви використовуєте:

Діаграма, що показує взаємозвʼязок ресурсу Cluster та ресурсів, до яких він посилається в Cluster API

Діаграма, що показує взаємозвʼязок ресурсу Cluster та ресурсів, до яких він посилається в Cluster API

У межах Cluster API також існує ресурс з назвою MachineDeployment, який описує групу вузлів, хоч то фізичні сервери, хоч віртуальні машини. Цей ресурс функціонує подібно до стандартних ресурсів Kubernetes, таких як Deployment, ReplicaSet та Pod, надаючи механізм для декларативного опису групи вузлів і автоматичного масштабування.

Іншими словами, ресурс MachineDeployment дозволяє вам декларативно описати вузли для вашого кластера, автоматизуючи їх створення, видалення та оновлення відповідно до заданих параметрів і запитуваної кількості реплік.

Діаграма, що показує взаємозвʼязок ресурсу MachineDeployment та його дочірніх ресурсів в Cluster API

Діаграма, що показує взаємозвʼязок ресурсу MachineDeployment та його дочірніх ресурсів в Cluster API

Для створення машин MachineDeployment посилається на шаблон для генерації самої машини та шаблон для генерації її конфігурації cloud-init:

Діаграма, що показує взаємозвʼязок ресурсу MachineDeployment та ресурсів, до яких він посилається в Cluster API

Діаграма, що показує взаємозвʼязок ресурсу MachineDeployment та ресурсів, до яких він посилається в Cluster API

Щоб розгорнути новий кластер Kubernetes за допомогою Cluster API, вам потрібно буде підготувати наступний набір ресурсів:

  • Загальний ресурс Cluster
  • Ресурс KamajiControlPlane, відповідальний за панель управління, що управляється Kamaji
  • Ресурс KubevirtCluster, що описує конфігурацію кластера в KubeVirt
  • Ресурс KubevirtMachineTemplate, відповідальний за шаблон віртуальної машини
  • Ресурс KubeadmConfigTemplate, відповідальний за генерацію токенів і cloud-init
  • Щонайменше один MachineDeployment для створення деяких робочих ресурсів (workers)

Шліфування кластера

У більшості випадків цього достатньо, але залежно від використаних провайдерів, вам можуть знадобитися й інші ресурси. Ви можете знайти приклади ресурсів, створених для кожного типу провайдера, в документації проєкту Kamaji.

На цьому етапі ви вже маєте готовий клієнтський кластер Kubernetes, але наразі він містить лише API-робітників і кілька основних втулків, що стандартно включені в установку будь-якого кластера Kubernetes: kube-proxy та CoreDNS. Для повної інтеграції вам потрібно буде встановити ще кілька компонентів:

Щоб встановити додаткові компоненти, ви можете використовувати окремий Cluster API Add-on Provider для Helm, або той же FluxCD, про який згадувалося в попередніх статтях.

При створенні ресурсів у FluxCD, можна вказати цільовий кластер, звертаючись до kubeconfig, згенерованого Cluster API. Тоді установка буде виконана безпосередньо в нього. Таким чином, FluxCD стає універсальним інструментом для управління ресурсами як у кластері управління, так і в клієнтських кластерах.

Діаграма, що показує схему взаємодії fluxcd, який може встановлювати компоненти як у кластері управління, так і в орендарських кластерах Kubernetes

Діаграма, що показує схему взаємодії fluxcd, який може встановлювати компоненти як у кластері управління, так і в орендарських кластерах Kubernetes

Які компоненти обговорюються тут? Загалом, набір включає наступні:

Втулок CNI

Щоб забезпечити комунікацію між podʼами в клієнтському кластері Kubernetes, необхідно розгорнути втулок CNI. Цей втулок створює віртуальну мережу, яка дозволяє podʼам взаємодіяти один з одним і традиційно розгортається як Daemonset на робочих вузлах кластера. Ви можете вибрати та встановити будь-який втулок CNI, який вважаєте відповідним.

Діаграма, що показує втулок CNI, встановлений всередині клієнтського кластера Kubernetes на схемі вкладених кластерів Kubernetes

Діаграма, що показує втулок CNI, встановлений всередині клієнтського кластера Kubernetes на схемі вкладених кластерів Kubernetes

Cloud Controller Manager

Основне завдання Cloud Controller Manager (CCM) — інтеграція Kubernetes з середовищем провайдера хмари (в вашому випадку це кластер управління Kubernetes, в якому створюються всі робітники клієнтського Kubernetes). Ось деякі з його завдань:

  1. Коли створюється сервіс типу LoadBalancer, CCM ініціює процес створення хмарного балансувальника навантаження, який направляє трафік до вашого кластера Kubernetes.
  2. Якщо вузол видаляється з хмарної інфраструктури, CCM забезпечує його видалення з вашого кластера також, підтримуючи поточний стан кластера.
  3. При використанні CCM вузли додаються до кластера з особливим taint, node.cloudprovider.kubernetes.io/uninitialized, який дозволяє обробку додаткової бізнес-логіки, якщо це необхідно. Після успішної ініціалізації цей taint видаляється з вузла.

Залежно від постачальника хмари, CCM може працювати як всередині, так і зовні клієнтського кластера.

Провайдер хмари KubeVirt розроблений для установки у зовнішньому батьківському кластері управління. Таким чином, створення сервісів типу LoadBalancer в клієнтському кластері ініціює створення сервісів LoadBalancer у батьківському кластері, які направляють трафік в клієнтський кластер.

Діаграма, що показує Cloud Controller Manager, встановлений зовні клієнтського кластера Kubernetes на схемі вкладених кластерів Kubernetes та відображення сервісів, якими він управляє з батьківського кластера в дочірньому кластері Kubernetes

Діаграма, що показує Cloud Controller Manager, встановлений зовні клієнтського кластера Kubernetes на схемі вкладених кластерів Kubernetes та відображення сервісів, якими він управляє з батьківського кластера в дочірньому кластері Kubernetes

Драйвер CSI

Container Storage Interface (CSI) розділений на дві основні частини для взаємодії зі зберіганням у Kubernetes:

  • csi-controller: Цей компонент відповідає за взаємодію з API постачальника хмари для створення, видалення, підключення, відключення та зміни розміру томів.
  • csi-node: Цей компонент працює на кожному вузлі та полегшує монтування томів до podʼів на запит kubelet.

У контексті використання CSI драйвера KubeVirt виникає унікальна можливість. Оскільки віртуальні машини в KubeVirt працюють всередині кластеру управління Kubernetes, де доступне повноцінний API Kubernetes, це відкриває шлях для запуску csi-controller ззовні клієнтського кластера. Цей підхід є популярним у спільноті KubeVirt і має кілька ключових переваг:

  • Безпека: Цей метод приховує внутрішнє API хмари від кінцевого користувача, надаючи доступ до ресурсів виключно через інтерфейс Kubernetes. Таким чином, зменшується ризик прямого доступу до кластера управління з клієнтських кластерів.
  • Простота і зручність: Користувачам не потрібно управляти додатковими контролерами у своїх кластерах, спрощуючи архітектуру і зменшуючи навантаження управління.

Однак, csi-node обовʼязково повинен працювати всередині клієнтського кластера, оскільки він безпосередньо взаємодіє з kubelet на кожному вузлі. Цей компонент відповідає за монтування та демонтування томів у podʼах, вимагаючи тісної інтеграції з процесами, що відбуваються безпосередньо на вузлах кластера.

CSI-драйвер KubeVirt діє як проксі для замовлення томів. Коли PVC створюється всередині клієнтського кластера, PVC створюється в кластері управління, а потім створений PV підключається до віртуальної машини.

Діаграма, що показує компоненти плагіна CSI, встановлені як всередині, так і ззовні клієнтського кластера Kubernetes на схемі вкладених кластерів Kubernetes та відображення постійних томів, якими він управляє з батьківського до дочірнього кластера Kubernetes

Діаграма, що показує компоненти плагіна CSI, встановлені як всередині, так і ззовні клієнтського кластера Kubernetes на схемі вкладених кластерів Kubernetes та відображення постійних томів, якими він управляє з батьківського до дочірнього кластера Kubernetes

Автоматичний масштабувальник кластера

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

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

Діаграма, що показує Cluster Autoscaler, встановлений зовні клієнтського кластера Kubernetes на схемі вкладених кластерів Kubernetes

Діаграма, що показує Cluster Autoscaler, встановлений зовні клієнтського кластера Kubernetes на схемі вкладених кластерів Kubernetes

Konnectivity

Є ще один додатковий компонент, про який я хотів би згадати — Konnectivity. Ймовірно, він вам знадобиться пізніше, щоб налаштувати вебхуки та шар агрегації API в вашому клієнтському кластері Kubernetes. Це питання детально висвітлене в одній з моїх попередніх статей.

На відміну від наведених вище компонентів, Kamaji дозволяє легко увімкнути Konnectivity та управляти ним як одним з основних компонентів вашого клієнтського кластера, поряд з kube-proxy і CoreDNS.

Висновок

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

Далі ви можете розглянути збір метрик і логів з ваших клієнтських кластерів, але це вже виходить за межі цієї статті.

Звичайно, всі компоненти, необхідні для розгортання кластера Kubernetes, можна упакувати в один Helm chart і розгорнути як єдиний застосунок. Саме так ми організовуємо розгортання керованих кластерів Kubernetes одним натисканням кнопки на нашій відкритій платформі PaaS, Cozystack, де ви можете безкоштовно випробувати всі технології, описані в статті.