Kubernetes для малих проектів: практичний підхід

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

Сучасна інфраструктура веб-додатків пройшла довгий шлях розвитку від простої внутрішньої бази даних на одному сервері до використання безлічі різних сервісів, розподілених на декількох віртуальних машинах і серверах. Перехід до хмарних рішень з можливостями балансування навантаження та горизонтального масштабування був великим кроком, а потім ми дійшли до мікросервісів.

Але управління сучасною мікросервісною інфраструктурою, пов'язане з власним набором проблем через складну архітектуру та різноманітні компоненти, що її складають. Основними больовими точками є:

  1. Збір логів з усіх сервісів
  2. Збір метрик
  3. Моніторинг стану служб і їх перезапуск, у разі виникнення проблем
  4. Автоматичне виявлення нових служб по мірі їх додавання
  5. Автоматичне оновлення конфігурації при додаванні/видаленні компонентів сервісів
  6. Легке масштабування вгору і вниз
  7. Постійна інтеграція змін коду та безперешкодне розгортання нових версій
  8. Відсутність прив'язки до рішення конкретного постачальника, чи то хмарного провайдера, чи то "голих" серверів.

Kubernetes з'явився як спосіб задовольнити всі ці операційні потреби в одній комплексній системі.

Основи Kubernetes

Архітектура Kubernetes в цілому виглядає як майстер (їх може бути декілька) та декілька вузлів (до 5 000), на кожному з яких встановлено наступне:

  • Docker
  • Kubelet (керує Docker)
  • Kube-proxy (керує iptables)

Майстер містить:

  • API сервер
  • базу даних etcd
  • Планувальник (вирішує, на якому вузлі запускати контейнер)
  • Менеджер контролерів (відповідає за відмовостійкість)

На додаток до всього цього є утиліта управління kubectl та конфігурації, описані у форматі YAML (декларативний DSL).

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

  1. Контейнер — образ + команда, що виконується в ньому
  2. Pod (дослівно перекладається як "стручок") — набір контейнерів (може бути лише один) зі спільною мережею, однією IP-адресою та іншими спільними характеристиками (спільне сховище даних, мітки); примітка: саме pods (а не окремі контейнери) дозволяє запускати Kubernetes
  3. Мітка та селектор — набір довільних пар ключ-значення, що призначаються подів та інших примітивів Kubernetes
  4. ReplicaSet — набір подів, кількість яких автоматично підтримується (при зміні кількості подів у конфігурації, при виході з ладу будь-яких подів/вузлів), що робить масштабування дуже простим
  5. Розгортання — ReplicaSet + історія старих версій ReplicaSet + процес оновлення між версіями (використовується для завдань безперервної інтеграції та розгортання)
  6. Сервіс — DNS ім'я + віртуальний IP + селектор + балансувальник навантаження (для розподілу запитів між подів, що відповідають селектору)
  7. Job — завдання та логіка визначення його успішного виконання (використовується для міграцій)
  8. CronJob — завдання та розклад cron
  9. Volume — прив'язка сховища даних (до боду, ReplicaSet або Deployment) із зазначеним розміром, типом доступу (ReadWriteOnce, ReadOnlyMany, ReadWriteMany) і типом зберігання (підтримується 19 способів реалізації: фізичний, програмний, хмарний)
  10. StatefulSet — подібний до ReplicaSet набір подів, але зі строго визначеними іменами/хостами, щоб ці поди завжди могли взаємодіяти один з одним, використовуючи їх (для ReplicaSet імена щоразу генеруються випадковим чином) і мали окремі томи (а не один на всіх, як у випадку з ReplicaSet)
  11. Ingress — доступний для зовнішніх користувачів сервіс, який розподіляє всі запити до сервісів на основі правил (залежно від імені хоста та/або URL-адрес)

Приклади опису pod і ReplicaSet у форматі YAML:

POD:

Цей YAML визначає блок з назвою "my-nginx-pod" з єдиним контейнером з назвою "nginx". Контейнер використовує образ "nginx:latest" і відкриває порт 80.

ReplicaSet:

Цей YAML визначає ReplicaSet з ім'ям "my-nginx-replicaset", який підтримує 3 репліки визначеного вище пакета. Селектор гарантує, що ReplicaSet керує пакетами з міткою "app: nginx". Шаблон визначає конфігурацію подів, яка використовується для створення реплік.

Ці примітиви вирішують всі описані вище проблеми за кількома незначними винятками: в автоматизації оновлення конфігурації не вирішується проблема побудови образів Docker, замовлення нових серверів та встановлення на них вузлів, а в CI/CD залишається необхідність підготовчих робіт (встановлення CI, опис правил побудови образів Docker, розгортання YAML конфігурацій на Kubernetes).

Архітектура та CI/CD

Під невеликими проектами ми маємо на увазі малі (до 50 вузлів, до 1500 pods) та середні (до 500 вузлів, до 15000 pods) проекти.

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

Контролер Ingress встановлено на трьох віртуальних машинах (kube-front-X).

Замість Pacemaker, показаного на схемі, можна використовувати VRRP, ucarp або іншу технологію, в залежності від конкретного дата-центру.

Конвеєр безперервної доставки виглядає так:

Ми використовуємо GitLab для безперервної інтеграції.

  • У Kubernetes ми налаштовуємо середовища для кожного рівня (production, staging, testing тощо — кількість залежить від конкретного проекту). Різні яруси можуть обслуговуватися різними кластерами Kubernetes (на різному обладнанні та в різних хмарах), а розгортання на них налаштовується в GitLab.
  • Docker-файл (точніше, ми використовуємо для цього dapp) і каталог .kube з YAML-конфігураціями ми поміщаємо в Git.
  • На етапі комміту (збірки) ми створюємо Docker-образ, який проштовхуємо в Docker-регістр.
  • Далі (етап тестування) ми беремо цей Docker-образ і запускаємо на ньому тести.
  • На етапі релізу (release stage) YAML конфігурації з каталогу .kube передаються утиліті kubectl, яка надсилає їх до Kubernetes, після чого образи Docker завантажуються і запускаються в інфраструктурі, розгорнутій відповідно до YAML конфігурації. Раніше ми використовували для цього Helm, але зараз допрацьовуємо власний dapp-інструмент.
  • Таким чином, Kubernetes повністю відповідає за останній етап (operate).

Для невеликих проектів інфраструктура виглядає як контейнерна хмара (її реалізація вторинна — залежить від наявного обладнання та потреб) з налаштованим сховищем (Ceph, AWS, GCE...) та контролером Ingress, а також (на додаток до цієї хмари), можливо, додатковими віртуальними машинами для запуску сервісів, які ми не розгортаємо всередині Kubernetes.

Висновок

З нашої точки зору, Kubernetes є достатньо зрілою для використання в проектах будь-якого розміру. Більше того, ця система дає чудову можливість будувати проекти, які з самого початку є дуже простими, надійними, відмовостійкими та горизонтально масштабованими. Основною проблемою є людський фактор: для невеликої команди може бути складно знайти фахівця, який зможе впоратися з усіма необхідними завданнями (що вимагає широкої технологічної експертизи), або такий фахівець може коштувати занадто дорого (і йому може скоро стати нудно працювати над проектом).

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

604
Події
Спільнота
Відеотека
Про нас