Ця стаття була опублікована більше року тому. Старіші статті можуть містити застарілу інформацію. Перевірте, чи інформація на цій сторінці не втратила актуальності з моменту її публікації.
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
Для своєї роботи Cluster API використовує концепцію провайдерів, які є окремими контролерами, що відповідають за конкретні компоненти створюваного кластера. В межах Cluster API існує кілька типів провайдерів. Основні з них:
- Провайдер інфраструктури, який відповідає за надання обчислювальної інфраструктури, такої як віртуальні машини або фізичні сервери.
- Провайдер панелі управління, який надає панель управління Kubernetes, а саме компоненти kube-apiserver, kube-scheduler та kube-controller-manager.
- Провайдер Bootstrap, який використовується для створення конфігурацій cloud-init для віртуальних машин та серверів, що створюються.
Щоб почати, вам потрібно буде встановити сам Cluster API та одного провайдера кожного типу. Повний список підтримуваних провайдерів можна знайти в документації проєкту Cluster API.
Для встановлення можна використовувати утиліту clusterctl або Cluster API Operator як більш декларативний метод.
Вибір провайдерів
Провайдер інфраструктури
Для запуску кластерів Kubernetes за допомогою KubeVirt, необхідно встановити провайдер інфраструктури KubeVirt. Він дозволяє розгортання віртуальних машин для робочих вузлів у тому ж кластері керування, де працює Cluster API.
Провайдер панелі управління
Проєкт Kamaji пропонує готове рішення для запуску панелі управління Kubernetes для кластерів орендарів як контейнерів у кластері керування. Цей підхід має кілька суттєвих переваг:
- Економічність: Запуск панелі управління в контейнерах запобігає використанню окремих вузлів панелі управління для кожного кластеру, що суттєво знижує витрати на інфраструктуру.
- Стабільність: Спрощення архітектури шляхом усунення складних багатошарових схем розгортання. Замість послідовного запуску віртуальної машини, а потім встановлення компонентів etcd та Kubernetes всередині неї, є проста панель управління, яка розгортається і працює як звичайний застосунок всередині Kubernetes та керується оператором.
- Безпека: Панель керування кластера прихована від кінцевого користувача, що знижує можливість компрометації її компонентів, а також усуває доступ користувачів до сховища сертифікатів кластера. Такий підхід до організації панелі управління, невидимої для користувача, часто використовують постачальники хмарних послуг.
Провайдер Bootstrap
Kubeadm як Bootstrap 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 API також існує ресурс з назвою MachineDeployment, який описує групу вузлів, хоч то фізичні сервери, хоч віртуальні машини. Цей ресурс функціонує подібно до стандартних ресурсів Kubernetes, таких як Deployment, ReplicaSet та Pod, надаючи механізм для декларативного опису групи вузлів і автоматичного масштабування.
Іншими словами, ресурс MachineDeployment дозволяє вам декларативно описати вузли для вашого кластера, автоматизуючи їх створення, видалення та оновлення відповідно до заданих параметрів і запитуваної кількості реплік.
Діаграма, що показує взаємозвʼязок ресурсу MachineDeployment та його дочірніх ресурсів в Cluster API
Для створення машин MachineDeployment посилається на шаблон для генерації самої машини та шаблон для генерації її конфігурації cloud-init:
Діаграма, що показує взаємозвʼязок ресурсу 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 орендарів
Які компоненти обговорюються тут? Загалом набір включає такі:
Втулок CNI
Щоб забезпечити комунікацію між Podʼами в кластері Kubernetes орендаря, необхідно розгорнути втулок CNI. Цей втулок створює віртуальну мережу, яка дозволяє Podʼам взаємодіяти один з одним і традиційно розгортається як Daemonset на робочих вузлах кластера. Ви можете вибрати та встановити будь-який втулок CNI, який вважаєте відповідним.
Діаграма, що показує втулок CNI, встановлений всередині кластера Kubernetes орендаря на схемі вкладених кластерів Kubernetes
Cloud Controller Manager
Основне завдання Cloud Controller Manager (CCM) — інтеграція Kubernetes з середовищем провайдера хмари (в вашому випадку це кластер керування Kubernetes, в якому створюються всі робочі вузли Kubernetes орендаря). Ось деякі з його завдань:
- Коли створюється Service типу LoadBalancer, CCM ініціює процес створення хмарного балансувальника навантаження, який направляє трафік до вашого кластера Kubernetes.
- Якщо вузол видаляється з хмарної інфраструктури, CCM забезпечує його видалення з вашого кластера також, підтримуючи поточний стан кластера.
- При використанні CCM вузли додаються до кластера з особливим taint,
node.cloudprovider.kubernetes.io/uninitialized, який дозволяє обробку додаткової бізнес-логіки, якщо це необхідно. Після успішної ініціалізації цей taint видаляється з вузла.
Залежно від постачальника хмари, CCM може працювати як всередині, так і зовні кластера орендаря.
Провайдер хмари KubeVirt розроблений для установки у зовнішньому батьківському кластері керування. Таким чином, створення Service типу LoadBalancer у кластері орендаря ініціює створення Service типу LoadBalancer у батьківському кластері, які направляють трафік в кластер орендаря.
Діаграма, що показує 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
Автоматичний масштабувальник кластера
Cluster Autoscaler є універсальним компонентом, який може працювати з різними API хмари, а його інтеграція з Cluster-API є лише однією з доступних можливостей. Для правильного налаштування він потребує доступу до двох кластерів: кластера орендаря, щоб відстежувати Podʼи та визначати необхідність додавання нових вузлів, і кластера керування Kubernetes (management kubernetes cluster), де він взаємодіє з ресурсом MachineDeployment та регулює кількість реплік.
Хоча Cluster Autoscaler зазвичай працює всередині кластера Kubernetes орендаря, у цьому випадку рекомендується встановити його зовні з тих же причин, що і раніше. Цей підхід простіший в обслуговуванні та більш безпечний, оскільки запобігає доступу користувачів кластерів орендарів до API керування кластера керування.
Діаграма, що показує Cluster Autoscaler, встановлений зовні кластера Kubernetes орендаря на схемі вкладених кластерів Kubernetes
Konnectivity
Є ще один додатковий компонент, про який я хотів би згадати — Konnectivity. Ймовірно, він вам знадобиться пізніше, щоб налаштувати вебхуки та шар агрегації API в вашому кластері Kubernetes орендаря. Це питання детально висвітлене в одній з моїх попередніх статей.
На відміну від наведених вище компонентів, Kamaji дозволяє легко увімкнути Konnectivity та керувати ним як одним з основних компонентів вашого кластера орендаря, поряд з kube-proxy і CoreDNS.
Висновок
Тепер у вас є повністю функціональний кластер Kubernetes з можливістю динамічного масштабування, автоматичного надання томів та балансувальників навантаження.
Далі ви можете розглянути збір метрик і логів з ваших кластерів орендарів, але це вже виходить за межі цієї статті.
Звичайно, всі компоненти, необхідні для розгортання кластера Kubernetes, можна упакувати в один чарт Helm і розгорнути як єдиний застосунок. Саме так ми організовуємо розгортання керованих кластерів Kubernetes одним натисканням кнопки на нашій відкритій платформі PaaS, Cozystack, де ви можете безкоштовно випробувати всі технології, описані в статті.