🐳 Розділ 14 · Питання #8

Що таке Kubernetes і навіщо він потрібен

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


🟢 Junior Level

30-секундна відповідь

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

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

  • Декларативне керування: ви описуєте в YAML-маніфесті бажаний стан системи (Desired State), наприклад: «Сервіс платежів повинен завжди мати 5 працюючих реплік».
  • Самовідновлення (Self-Healing): якщо контейнер зависає або фізичний сервер виходить з ладу, Kubernetes автоматично перезапускає аварійний контейнер або миттєво підіймає його копію на іншому здоровому сервері.

Наочна аналогія з життя

  • Docker-контейнер — це один музикант: він уміє бездоганно грати свою партію на скрипці.
  • Kubernetes — це диригент симфонічного оркестру (саме слово Kubernetes у перекладі з грецької означає «керманич», «рульовий»):
    • Диригент розсаджує музикантів по місцях (Scheduling).
    • Якщо скрипаль раптово захворів прямо під час концерту, диригент миттєво викликає дублера (Self-healing).
    • Якщо зала заповнилася слухачами вщерть, диригент підключає додаткову групу духових інструментів (Auto-scaling).

5 головних задач, які вирішує Kubernetes

  1. Service Discovery та балансування навантаження: кожному поду виділяється унікальна IP-адреса та єдине DNS-ім’я, а трафік рівномірно балансується між репліками.
  2. Автоматичне масштабування (Autoscaling): динамічне збільшення кількості подів у разі зростання навантаження на CPU/RAM (HPA) та додавання нових серверів у кластер (Cluster Autoscaler).
  3. Оновлення без простою (Zero-Downtime Rolling Updates): почергова заміна старих контейнерів на нові з миттєвим автоматичним відкатом (Rollback) у разі виникнення помилок.
  4. Керування конфігураціями та секретами: впровадження паролів БД, API-ключів та параметрів середовища без необхідності перезбирати образи контейнерів.
  5. Оркестрація сховищ (Storage Orchestration): автоматичне монтування локальних або хмарних дисків (AWS EBS, GCP Persistent Disk, NFS, Ceph).

🟡 Middle Level

Архітектура кластера: Control Plane vs Worker Nodes

Кластер Kubernetes складається з двох основних фізичних контурів:

+-------------------------------------------------------------------------------+
|                       CONTROL PLANE (Керуючий контур)                         |
|                                                                               |
|  [ kube-apiserver ] <---> [ etcd (Raft DB) ]                                  |
|        ^       ^                                                              |
|        |       +-------- [ kube-scheduler ]                                   |
|        v                                                                      |
|  [ kube-controller-manager ] <---> [ cloud-controller-manager ]               |
+-------------------------------------------------------------------------------+
       | (HTTPS / gRPC)
       v
+-------------------------------------------------------------------------------+
|                       WORKER NODES (Робочі сервери)                           |
|                                                                               |
|  [ Node 1 ]                          [ Node 2 ]                               |
|  ├─ kubelet                          ├─ kubelet                               |
|  ├─ kube-proxy                       ├─ kube-proxy                            |
|  ├─ Container Runtime (containerd)   ├─ Container Runtime (containerd)        |
|  └─ Pod A | Pod B                    └─ Pod C | Pod D                         |
+-------------------------------------------------------------------------------+

1. Компоненти Control Plane (Мозок кластера)

  • kube-apiserver: центральний REST API-сервер кластера. Єдиний компонент, який безпосередньо взаємодіє з базою даних etcd. Усі інші сервіси (і CLI kubectl) спілкуються виключно через нього.
  • etcd: високонадійне розподілене key-value сховище на базі алгоритму консенсусу Raft. Зберігає повний стан кластера.
  • kube-scheduler: аналізує новостворені поди та обирає найбільш підходящий Worker Node з урахуванням доступних ресурсів CPU/RAM, Taints, Tolerations та Affinity.
  • kube-controller-manager: безперервно виконує цикл узгодження (Reconciliation Loop), відстежуючи відповідність поточного стану кластера бажаному (Node Controller, Deployment Controller, Endpoint Controller).

2. Компоненти Worker Nodes (Виконавці)

  • kubelet: системний агент, що працює на кожному сервері. Приймає від API-сервера специфікації подів (PodSpecs) та віддає команди Container Runtime на запуск, зупинку та моніторинг контейнерів.
  • kube-proxy: мережевий проксі, що підтримує мережеві правила хоста (iptables або IPVS) для маршрутизації трафіку до подів через абстракцію Service.
  • Container Runtime: низькорівневе середовище запуску контейнерів, що реалізує інтерфейс CRI (containerd, CRI-O).

Головні абстракції Kubernetes

| Об’єкт | Призначення | | :— | :— | | Pod | Мінімальна одиниця розгортання (один або група тісно пов’язаних контейнерів). | | Deployment | Декларативне керування репліками stateless-застосунків та оновленнями. | | Service | Стабільна точка входу (віртуальний IP та DNS-ім’я) з L4-балансуванням до подів. | | Ingress | L7 HTTP/HTTPS маршрутизатор, термінація SSL/TLS та роутинг за доменами/шляхами. | | ConfigMap / Secret | Відокремлення конфігурації та чутливих даних (паролів) від коду. | | PersistentVolumeClaim | Запит на виділення постійного дискового сховища. | | Namespace | Віртуальний ізольований простір для мультитенантності всередині кластера. |


🔴 Senior Level

Цикл узгодження (Reconciliation Loop) та Event-Driven Architecture

Kubernetes побудований на принципах теорії автоматичного керування зі зворотним зв’язком: \(\text{Desired State (Бажаний стан)} \longleftrightarrow \text{Actual State (Фактичний стан)}\)

  1. Watch API & Informers: контролери не опитують API-сервер важкими polling-запитами. Вони встановлюють довгоживучі HTTP streaming-з’єднання (HTTP chunked watch) через Informer.
  2. Reflector & Delta FIFO Queue: у разі зміни об’єкта в etcd подія вмить передається контролеру в чергу WorkQueue.
  3. Reconcile(): метод контролера порівнює факти: «В etcd записано 5 реплік, а kubelet повідомляє лише про 4 працюючі». Контролер надсилає в API Server команду на створення 1 нового пода.

Життєвий цикл запиту до API Server (Admission Control Pipeline)

Коли інженер виконує kubectl apply -f deployment.yaml:

  1. Authentication (Аутентифікація): перевірка X.509 клієнтського сертифіката, Bearer-токена або OIDC/OAuth2 провайдера.
  2. Authorization (Авторизація): перевірка прав за моделлю RBAC (Role-Based Access Control) — чи має користувач право створювати поди в даному Namespace.
  3. Mutating Admission Webhooks: перехоплювачі можуть динамічно модифікувати маніфест (наприклад, Istio автоматично інжектує контейнер-сайдкар envoy, а Vault інжектує секрети).
  4. Schema Validation: сувора перевірка відповідності JSON/YAML схеми специфікації Kubernetes API.
  5. Validating Admission Webhooks: фінальна валідація політик безпеки (наприклад, OPA Gatekeeper або Kyverno блокують запуск подів із прапорцем privileged: true або runAsUser: root).
  6. ETCD Persistence: атомарний запис об’єкта в etcd з інкрементом глобального лічильника resourceVersion.

Сховище etcd: Кворум та надійність (Raft Consensus)

Senior-інженер зобов’язаний розуміти математичні обмеження etcd:

  • Для забезпечення кворуму потрібна суворо непарна кількість вузлів: $N = 2F + 1$, де $F$ — допустима кількість відмовлених нод.
  • Кластер із 3 нод: кворум дорівнює 2. Витримує відмову рівно 1 ноди.
  • Кластер із 5 нод: кворум дорівнює 3. Витримує відмову 2 нод.
  • Вимога до дискової затримки: etcd вкрай чутливий до затримки fsync операцій на диску. Якщо час запису на SSD перевищує 10–15 мс, передача лідерства в Raft починає збоїти, спричиняючи каскадну відмову API-сервера всього кластера.

4 Tricky Questions

1. Що станеться з працюючими застосунками, якщо всі майстер-ноди Control Plane (kube-apiserver та etcd) одночасно вийдуть з ладу?

Відповідь: Користувацький трафік і запущені поди продовжать працювати без збоїв! Control Plane відповідає за керування та зміну стану, але не бере участі в обробці користувацького трафіку:

  • На Worker-нодах процеси контейнерів продовжать виконуватися під керуванням containerd.
  • Мережеві правила маршрутизації (iptables / IPVS), уже записані kube-proxy, залишаться в ядрі операційної системи хоста, і сервіси продовжать балансувати трафік.
  • Що зламається: заблокується будь-яке керування: не можна буде застосувати нові деплої, не спрацює автоперезапуск аварійних подів, перестануть працювати autoscaling (HPA) та реєстрація нових нод до повного відновлення Control Plane.

2. Як алгоритм вибору ноди (kube-scheduler) розподіляє поди, і які дві головні фази він виконує?

Відповідь: Планувальник виконує двофазний цикл:

  1. Фаза фільтрації (Filtering / Predicates): відсіює завідомо непідходящі вузли. Перевіряються:
    • Чи достатньо на ноді вільних ресурсів (CPU/RAM Requests).
    • Збіг міток nodeSelector та правил NodeAffinity.
    • Наявність міток відчуження Taints та відповідних Tolerations у пода.
    • Перевірка лімітів на монтування томів (MaxCSIVolumeCount).
  2. Фаза ранжування (Scoring / Priorities): залишеним придатним нодам виставляються бали від 0 до 100 на основі плагінів:
    • ImageLocality (чи є вже потрібний образ на ноді для прискорення старту).
    • LeastAllocated / BalancedResourceAllocation (рівномірний розподіл навантаження).
    • PodTopologySpread (розподіл подів по різних зонах доступності дата-центру для відмовостійкості). Нода з максимальним сумарним балом обирається для прив’язки (Binding).

3. Чому в маніфестах подів критично важливо вказувати і requests, і limits, і чим загрожує їхня відсутність?

Відповідь:

  • requests використовує kube-scheduler для пошуку ноди: нода резервує вказану кількість ресурсів. Якщо requests не вказані, планувальник вважає їх рівними 0 і може посадити 50 «важких» подів на одну ноду, спричинивши її миттєве перевантаження.
  • limits використовує ядро Linux (cgroups):
    • У разі перевищення CPU limit ядро вмикає тротлінг (CPU CFS Throttling), штучно уповільнюючи застосунок.
    • У разі перевищення Memory limit ядро негайно знищує процес сигналом SIGKILL із помилкою OOMKilled (Exit Code 137).
  • Якщо лімітів немає, один завислий або текучий по пам’яті Java-под (Memory Leak) може зжерти всю оперативну пам’ять фізичного сервера, змусивши Linux OOM Killer знищити критичні системні процеси ноди (включно з Docker та kubelet).

4. Що таке Split-Brain у кластері etcd, і чому кластер із 4 вузлів менш надійний, ніж кластер із 3 вузлів?

Відповідь:

  • Кластер із 3 вузлів вимагає кворуму $\lfloor 3/2 \rfloor + 1 = 2$ вузли. При падінні 1 вузла решта 2 продовжують роботу (допустима 1 відмова).
  • Кластер із 4 вузлів вимагає кворуму $\lfloor 4/2 \rfloor + 1 = 3$ вузли. При мережевому розділенні кластер розколеться на дві частини: 2 вузли та 2 вузли. Жодна з половин не зможе набрати кворум із 3 голосів, і весь кластер повністю припинить приймати будь-які операції запису!
  • Таким чином, кластер із 4 вузлів так само витримує відмову лише 1 ноди, але потребує більше мережевого трафіку на синхронізацію та підвищує ймовірність відмови кворуму під час мережевих збоїв.

🎯 Шпаргалка для інтерв’ю

Головне про Kubernetes

  • Призначення: автоматизація розгортання, масштабування та самовідновлення контейнерів у кластері.
  • Control Plane: kube-apiserver (API), etcd (база даних Raft), kube-scheduler (розміщення), kube-controller-manager (підтримання стану).
  • Worker Node: kubelet (агент пода), kube-proxy (мережеві правила), containerd (рантайм CRI).
  • Філософія: декларативний підхід (Desired State) через цикл узгодження (Reconciliation Loop).
  • Базові об’єкти: Pod $\to$ Deployment $\to$ Service $\to$ Ingress.

Managed K8s (EKS / GKE / AKS) vs Self-Hosted (Kubeadm)

| Параметр | Managed Kubernetes | Self-Hosted | | :— | :— | :— | | Control Plane | Обслуговується хмарним провайдером (SLA 99.95%) | Обслуговується власною командою інженерів | | Резервне копіювання etcd | Автоматично | Вручну скриптами та моніторингом | | Вартість входу | Оплата невеликої комісії або тільки за ноди | Потрібна виділена команда SRE (3–5 осіб) |

Червоні прапорці на співбесіді (Чого говорити не можна)

  • ❌ «Kubernetes потрібен узагалі кожному проєкту, навіть моноліту з одного сервісу» — це оверінжиніринг, що додає колосальні накладні витрати на експлуатацію.
  • ❌ «У разі падіння майстер-ноди Kubernetes усі контейнери застосунку відразу падають» — контейнери на worker-нодах продовжують працювати та обробляти мережевий трафік.
  • ❌ «etcd можна розгорнути на двох серверах для економії» — у разі падіння однієї ноди та, що залишилася, не набере кворум, кластер помре.

Пов’язані питання