🐳 Раздел 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 можно развернуть на двух серверах для экономии» — при падении одной ноды оставшаяся не наберёт кворум, кластер умрёт.

Связанные вопросы