Skip to content

Архітектура Kubernetes

Kubernetes базується на клієнт-серверній архітектурі з головними і робочими вузлами. Ключовим елементом у цій архітектурі є кластер. Що ж це таке?

Уяви виробничий комплекс з великою кількістю будівель та приміщень. Одна з будівель — адміністративна (headquarters). У ній працюють менеджери, які планують, координують і контролюють всі процеси виробництва. Вони приймають важливі рішення, наприклад, де і коли почати нове виробництво або як розподілити ресурси. Інші будівлі комплексу є виробничими (factory 1, 2, …) і залучені для виготовлення продукції.

Кластер — це комплекс серверів або віртуальних машин, який можна порівняти з виробничим комплексом з великою кількістю будівель та приміщень (серверів або віртуальних машин). Кластер складається з вузлів (nodes), кожен з яких виконує певну функцію і впливає на загальну продуктивність.

На схемі нижче ти можеш бачити робочі вузли (worker nodes) — Node 1та Node 2. Робочі вузли (комп’ютери або віртуальні машини) відповідають за запуск і виконання додатків. На цих нодах працюють робочі контейнери з програмами, які виконують конкретні задачі, від обробки даних до обслуговування вебзапитів.

Панель керування (його ще називають Control Plane, Master Nodes, майстер-вузли) відповідає за планування, розподіл роботи, моніторинг стану виробництва та розв’язання проблем (подібно до адміністративної будівлі ). Це мозок Kubernetes, який керує всім кластером. Тут відбувається прийняття рішень (наприклад, де розмістити додатки), відстеження стану кластера та реагування на зміни. Control plane включає важливі компоненти:

  • API-server, який також називають kube-api-server;
  • scheduler;
  • Controller Manager;
  • сховище даних ключів-значень, яке називається etcd.

💡Втрата Control Plane може призвести до значних перебоїв. Пізніше ти дізнаєшся як цього уникнути.

Компоненти Control Plane можуть бути запущені на будь-якому комп'ютері в кластері. Зазвичай ці компоненти запускаються як мінімум на одному окремому комп'ютері. Це допомагає уникнути затримок у комунікації та спрощує координацію між компонентами при управлінні кластером.

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

Компоненти контрольної панелі

Тепер трохи детальніше розглянемо компоненти майстер-вузлів.

kube-api-server (API Server)

Перший компонент — це kube-api-server, який також називають API Server.

API Server — це «головні ворота» для всіх операцій у кластері. По своїй суті ці ворота подібні до REST API server, який виконує роль центрального інтерфейсу для управління кластером і забезпечує приймання та обробку всіх запитів від користувачів, адміністраторів, розробників та зовнішніх агентів. Також API Server валідує запити та забезпечує безпеку через автентифікацію, авторизацію та контроль доступу.

У разі стрімкого збільшення кількості запитів API Server може створювати «клони» чи «репліки», щоб впоратися з навантаженням. Горизонтальне масштабування — одна із ключових властивостей API Server. Як і більшість компонентів Kubernetes, API Server запущений у контейнері.

💡API Server — це єдиний компонент, який безпосередньо взаємодіє з etcd, діючи як проміжний інтерфейс для всіх інших агентів панелі керування.

etcd

Другий компонент — це etcd, який являється розподіленим (distributed) та надійним (strongly consistent) сховищем типу «ключ-значеня» (key-value). Дане сховище зберігає всю критично важливу інформацію про стан кластера.

💡etcd можна порівняти з сейфом, у якому зберігається конфігурація та стан усіх ресурсів кластера. Усе, що відбувається в кластері, має бути записано та збережено! Цю функцію і виконує etcd.

Усі нові дані записуються до сховища даних шляхом додавання, при цьому застарілі дані регулярно стискаються для оптимізації обсягу зберігання. Прямий доступ до etcd має лише API server. Така конфігурація забезпечує централізоване управління та контроль.

Для керування etcd використовують etcdctl, який виконує різні функції. Однією з найважливіших функцій etcdctl є здатність створювати «знімки» (snapshots) стану кластера. Ці знімки, наче фотографії, фіксують стан сховища в певний момент часу. Їх можна використовувати для відновлення стану кластера після якихось збоїв або проблем, зменшуючи ризик втрати важливих даних.

Зазвичай у кластері є 3 і більше майстер-ноди (кількість майстер-нод повинна бути непарною).

По своїй суті etcd теж є кластером. Наприклад, є 3 ноди etcd, одна з яких є лідером, а інші — підопічними (фоловерами). При старті кластер самостійно визначає, хто і яку роль буде виконувати. У цьому випадку 3 ноди потрібні для стабільності і цілісності даних про операції і стани в середині кластера.

Коли на etcd приходить запит на запис, цей запис автоматично перенаправляється на лідера кластера. Лідер робить помітку про зміну, але ще не записує її.

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

kube-scheduler

Наступний компонент — це kube-scheduler або просто scheduler. Можливо, по назві ти вже здогадався(-лась), за що саме відповідає цей компонент: kube-scheduler відповідає за планування ресурсів, які потрібні для виконання роботи. Під роботою мається на увазі запуск контейнерів, який потребує наступних ресурсів:

  • CPU;
  • RAM;
  • Disk Space.

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

💡При виборі вузла планувальник враховує різні фактори, включаючи фізичні ресурси та різні обмеження, які ти можеш налаштовувати.

kube-controller-manager

kube-controller-manager відповідає за підтримку нормального (бажаного) стану кластера. Він уважно відстежує роботу кластера і, якщо щось пішло не так, запускає контролери та оператори, щоб виправити ситуацію.

Існують різні типи операторів та контролерів, кожний з яких відстежує певний аспект роботи кластера. Наприклад, node controller відповідає за те, щоб відстежувати та реагувати на перебої у роботі нод.

kube-controller-manager об'єднує всі контролери в один процес для забезпечення ефективного управління. Це дозволяє легко налаштовувати роботу різних контролерів для стабільної роботи кластера та дотримання встановлених вимог та правил.

Суть роботи контролерів зводиться до відтворення бажаного стану. Контролери запущені у вічному циклі, який постійно перевіряє, чи бажаний стан кластера співпадає з поточним станом. І якщо ці стани не співпадають, то відповідний контроллер запускає механізми синхронізації, щоб усунути цю проблему.

cloud-controller-manager

cloud-controller-manager схожий на kube-controller-manager, проте запускає саме специфічні контролери для хмарного провайдера. Якщо запускати Kubernetes на власному обладнанні, то у кластері не буде cloud-controller-manager.

Як і kube-controller-manager, cloud-controller-manager поєднує декілька контролерів, які запускаються як один процес. Щоб покращити продуктивність або витримати збої, можна запускати більше однієї копії таких процесів.

Робочі вузли (Worker Nodes)

Справжня магія Kubernetes твориться саме у робочих вузлах (worker nodes), де виконуються додатки у контейнерах. Щоб детальніше розібратись з робочими вузлами, потрібно ознайомитись з подами (pods).

Под (pod) — це колекція з одного або декількох контейнерів, запланованих (scheduled) разом. Цю колекцію можна одночасно запускати, зупиняти або переплановувати.

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

Тепер, коли ти знаєш, що таке под, настав час повертатись до Worker Node.

Для безперебійної роботи, кожен робочий вузол містить:

  • kubelet — це агент, який працює на кожному робочому вузлі та відстежує, щоб все працювало нормально.

Для моніторингу kubelet отримує від майстер-вузла інформацію щодо того, яка робота має бути виконана та які поди потрібно створити. Врахувавши отриману інформацію, kubelet запускає, зупиняє та управляє контейнерами. Також він здійснює постійний моніторинг стану подів та відправляє звіти на майстер-вузол.

  • kube-proxy — це агент, який відповідає за взаємодію з мережею. Він балансує навантаження, розподіляючи трафік між подами, а також відстежує дотримання мережевих правил. kube-proxy відповідає за комунікації всередині кластера.

Бажаний стан (Desired State)

Бажаний стан (Desired State) — це опис того, як повинна функціонувати система. У цьому описі визначено, скільки копій застосунку повинно бути запущено, які мережеві ресурси вони повинні використовувати, які об'ємні сховища вони мають підключати, та багато іншого.

Іншими словами, бажаний стан — це план, який описує як повинна працювати система.

За допомогою kube-controller-manager Kubernetes постійно перевіряє, чи все працює згідно з описаними вимогами. Коли щось ламається або працює некоректно, Kubernetes виправляє це відповідно до плану.

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

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

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

Стабільна мережа та сервіси

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

Агенти на ноді, такі як Kubelet (який управляє подами на ноді) або системні демони, мають можливість спілкуватися з усіма подами, які знаходяться на цій самій ноді. Це дозволяє ефективно управляти ресурсами та здійснювати моніторинг стану подів.

Усі контейнери всередині одного пода ділять між собою простір імен мережі пода. Тобто вони використовують IP- і MAC-адресу самого пода, а не власні. Щоб комунікувати між собою, контейнери всередині одного поду можуть використовувати localhost замість будь-якого IP.

Комунікація між подами

Kubernetes використовує віртуальну мережу для своїх компонентів і забезпечує кожному поду свою унікальну IP-адресу всередині цієї віртуальної мережі. Комунікація між подами відбувається за допомогою IP-адрес.

Уяви, що в першому поді — Python Server, який показує погоду через вебсторінку, а в другому поді — сервіс, який містить АРІ для генерації передбачень (як в «Сільпо»). Щоб показати погоду і передбачення, сервіс погоди робить запит на сервіс передбачень. І як IP сервісу передбачень просто використовує IP другого поду.

Ця схема може виглядати трохи заплутаною. На щастя, знати IP подів майже ніколи не потрібно. Для цього є мережеві об’єкти, які називаються сервіси (Services).

Сервіси (Services)

Kubernetes надає можливість легкого масштабування. У залежності від навантаження та потреб, кількість подів може збільшуватися або зменшуватися. У такі моменти IP-адреса пода може змінитись, або ж може додатись додатковий под з новим IP. Відстежувати всі ці зміни вручну дуже важко. Kubernetes розв’язує цю проблему за допомогою Service.

Service як мережевий об’єкт k8s має постійну адресу, яку можна використовувати для доступу до групи подів. Адреса буде коректна, навіть якщо окремі поди вимикаються або замінюються новими. Це гарантує, що додаток залишатиметься доступним під однією адресою, незалежно від внутрішніх змін у кластері. Найчастіше до сервісу звертаються не по його IP-адресі, а по його мережевій назві.

Service дозволяє використовувати різні типи доступу:

  • внутрішній доступ (ClusterIP);
  • зовнішній доступ (NodePort, LoadBalancer);
  • мапування на зовнішні ресурси (ExternalName).

Service забезпечує гнучкість у розгортанні та взаємодії з додатками, дозволяючи адаптуватися до різних потреб і сценаріїв використання. Завдяки Service ти можеш легко знайти та зв’язатися з сервісами в кластері, що полегшує управління мережею і підвищує ефективність взаємодії між сервісами.

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