Введение в Kubernetes: оркестрация контейнеров для новичков
Допустим, вы запустили своё первое приложение в контейнере. Всё работает, вы довольны. Потом приложение начинает расти: появляется отдельный сервис для авторизации, отдельный для базы данных, ещё один для отправки уведомлений. Контейнеров становится десять, потом двадцать. И вот вы уже вручную следите за тем, какой из них упал, перезапускаете их в правильном порядке, вручную переносите нагрузку с перегруженного сервера на свободный.
Это не масштабирование. Это ручной труд, который рано или поздно даёт сбой — обычно ночью в пятницу.
Kubernetes решает именно эту проблему. Не "как запустить контейнер", а "как управлять сотнями контейнеров так, чтобы не сойти с ума".
Что такое Kubernetes и откуда он взялся
K8s — сокращение от Kubernetes: между "K" и "s" ровно восемь букв. Это open-source платформа для оркестрации контейнеров: она автоматически развёртывает приложения, следит за их работой, перезапускает упавшие сервисы и распределяет нагрузку между серверами.
Платформу создал Google на основе внутреннего опыта с системой Borg, которая управляла их собственной инфраструктурой. В 2014 году Google открыл код и передал проект в Cloud Native Computing Foundation. Сегодня K8s — стандарт де-факто для запуска контейнеризованных приложений в production.
Чтобы понять, зачем он нужен, полезно разобраться, что вообще такое контейнер и почему одного Docker для серьёзной работы не хватает.
Docker и Kubernetes: в чём разница
Контейнер — это изолированная упаковка для приложения. Внутри лежит сам код, все его зависимости и конфигурация. Контейнер запускается одинаково на любом сервере, где установлен Docker, — без сюрпризов в духе "а у меня локально работало".
Docker — это инструмент для создания и запуска контейнеров. Он отлично справляется на одной машине. Но представьте, что ваше приложение разбито на двадцать сервисов, и они должны работать на нескольких серверах одновременно. Кто решает, какой сервис запустить на каком сервере? Кто перезапускает упавший контейнер? Кто добавляет новые копии сервиса, когда нагрузка растёт?
Docker на эти вопросы не отвечает. Kubernetes — отвечает.
| Что умеет | Docker | Kubernetes |
|---|---|---|
| Запускать контейнеры | ✓ | ✓ |
| Управлять одним сервером | ✓ | ✓ |
| Управлять кластером серверов | — | ✓ |
| Перезапускать упавшие сервисы | Частично | ✓ |
| Масштабировать под нагрузку | — | ✓ |
| Распределять трафик | — | ✓ |
Если провести аналогию: Docker — это грузовик, Kubernetes — это диспетчерская служба, которая знает, куда какой грузовик отправить, следит за маршрутами и вызывает замену, если один из грузовиков сломался.
Как устроен кластер
Kubernetes работает с группой серверов — это называется кластер. Внутри кластера есть два типа узлов с принципиально разными ролями.
Control plane — управляющий уровень. Это мозг кластера: он принимает решения о том, где и что запускать, следит за состоянием всей системы и реагирует на изменения. Именно сюда вы отправляете команды, когда говорите Kubernetes "запусти три копии этого сервиса".
Worker nodes — рабочие узлы. Здесь непосредственно работают контейнеры с вашими приложениями. От того, какое железо стоит в основе каждого узла, зависит производительность кластера — о том, как выбрать сервер для офисных задач, мы рассказывали отдельно. Узлов может быть три, может быть триста — Kubernetes управляет ими одинаково.
┌─────────────────────┐
│ Control Plane │ ← принимает решения
│ (мозг кластера) │
└──────────┬──────────┘
│
┌───────────┼───────────┐
▼ ▼ ▼
┌─────────┐ ┌─────────┐ ┌─────────┐
│ Worker │ │ Worker │ │ Worker │ ← здесь работают
│ Node │ │ Node │ │ Node │ контейнеры
└─────────┘ └─────────┘ └─────────┘
Внутри control plane живут несколько компонентов. API Server — единая точка входа: все команды идут через него. Scheduler — планировщик, который решает, на каком узле запустить новый контейнер, учитывая свободные ресурсы. Controller Manager — следит за тем, чтобы реальное состояние кластера совпадало с желаемым: если контейнер упал, он создаёт новый. etcd — база данных, где хранится всё состояние кластера. Если etcd недоступен, кластер теряет управление — поэтому его бэкапят отдельно и тщательно.
На каждом рабочем узле есть kubelet — агент, который общается с control plane и следит за контейнерами на своём сервере.
Основные понятия: Pod, Deployment, Service
Три термина, без которых невозможно понять K8s.
Pod — минимальная единица в Kubernetes. Это один или несколько контейнеров, которые всегда работают вместе на одном узле и делят общий сетевой адрес. Обычно в поде живёт один контейнер — с вашим приложением. Поды — временные: они создаются, умирают и пересоздаются. Kubernetes не "лечит" упавший под, он просто создаёт новый.
Deployment — описание того, как должно работать ваше приложение: какой образ использовать, сколько копий держать живыми, как обновлять при выходе новой версии. Вы говорите Deployment: "мне нужно три копии этого сервиса". Он создаёт три пода и следит, чтобы их всегда было именно три. Упал один — Deployment поднимает новый.
Service — стабильный сетевой адрес для доступа к группе подов. Поды пересоздаются и получают новые IP-адреса, Service при этом остаётся неизменным. Именно через Service другие части приложения обращаются к вашему сервису — они не знают и не должны знать, на каком узле и под каким IP он сейчас работает.
Вот как выглядит простой Deployment в виде конфигурационного файла:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
replicas: 3 # держать три копии
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-app
image: nginx:1.25
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
Блок resources — не опция для продвинутых. Без него один контейнер может съесть всю память узла и положить соседей. Kubernetes не угадывает, сколько ресурсов нужно вашему приложению — вы указываете это явно. Соответственно, ещё на этапе сборки сервера для офисной инфраструктуры важно закладывать запас по CPU и памяти с учётом будущих лимитов контейнеров.
Зачем это бизнесу
Для разработчика и администратора Kubernetes — это автоматизация рутины. Но у IT-руководителей свои вопросы: зачем платить за сложность, если и так всё работает?
Три конкретных аргумента.
Отказоустойчивость. Когда сервер падает, Kubernetes автоматически переносит поды на оставшиеся узлы. Приложение продолжает работать — пользователи могут ничего не заметить. Без оркестрации та же ситуация требует ручного вмешательства и означает простой.
Масштабирование без человека. HPA (Horizontal Pod Autoscaler) следит за нагрузкой и добавляет или убирает копии сервиса автоматически. Пришёл неожиданный трафик — K8s поднял дополнительные поды за 15–30 секунд. Нагрузка спала — лишние поды убраны. Платите за реально используемые ресурсы, а не за запас "на всякий случай". По данным, которые публикуют cloud-провайдеры, грамотно настроенный автоскейлинг снижает расходы на инфраструктуру в production на 30–50%.
Обновления без даунтайма. Rolling update — стандартный механизм в Kubernetes. Новая версия приложения разворачивается постепенно: поды со старой версией заменяются новыми по одному. Если что-то пошло не так, откат занимает одну команду.
Попробовать локально: с чего начать
Разворачивать production-кластер с нуля для знакомства с K8s — избыточно. Есть инструменты, которые поднимают кластер на вашем ноутбуке за несколько минут.
Minikube — самый популярный вариант для начала. Разворачивает однонодовый кластер поверх Docker или виртуальной машины. Достаточно для того, чтобы понять базовые концепции и попробовать первые команды:
kubectl get nodes
kind (Kubernetes IN Docker) — альтернатива, которая умеет имитировать несколько узлов на одной машине. Ближе к реальному кластеру, полезен когда хочется понять, как работает взаимодействие между узлами.
Оба инструмента бесплатны, оба работают на Linux, macOS и Windows. Для первого знакомства разницы почти нет — берите minikube.
Безопасность: не откладывайте
Две вещи, которые новички обычно настраивают в последнюю очередь и потом жалеют.
RBAC — разграничение прав доступа внутри кластера. После первоначальной настройки у вас есть полный admin-доступ везде. В production это неприемлемо: разные команды и сервисы должны иметь доступ только к тому, что им реально нужно. RBAC позволяет это настроить точно: этот сервис-аккаунт читает поды только в своём namespace, этот разработчик деплоит только в staging, но не в prod.
Secrets — хранение паролей, токенов и ключей. Kubernetes умеет хранить чувствительные данные отдельно от кода приложения. Базовая реализация сохраняет их в etcd в формате base64 — это не шифрование, а просто кодирование. Для серьёзного использования настраивают шифрование at rest или интеграцию с внешними хранилищами вроде HashiCorp Vault.
Обе темы выглядят как "разберёмся потом". На практике "потом" наступает вместе с инцидентом.
Что дальше
Kubernetes — это не продукт, который ставится один раз и забывается. Это экосистема, которая продолжает развиваться.
После базового знакомства открываются следующие уровни. Helm — менеджер пакетов для K8s: вместо того чтобы писать десятки YAML-файлов вручную, вы используете готовые чарты для PostgreSQL, Redis, Prometheus и сотен других инструментов. Operators — механизм для автоматизации сложной логики управления приложениями: резервное копирование базы данных, failover, обновления со специфической бизнес-логикой. Service Mesh (Istio, Linkerd) — дополнительный уровень контроля над сетевым трафиком между сервисами: шифрование, детальные метрики, канареечные деплои.
Managed-кластеры от облачных провайдеров — EKS у Amazon, GKE у Google, AKS у Microsoft — снимают с команды задачу обслуживания control plane. Провайдер берёт на себя обновления, высокую доступность и резервное копирование etcd. Это разумный выбор для команд, которые хотят использовать K8s, но не хотят тратить ресурсы на его поддержку. Если же кластер разворачивается на собственном оборудовании, стоит заранее определиться с платформой виртуализации — какой гипервизор выбрать, мы разбирали в отдельном материале.
Порог входа у Kubernetes действительно высокий. Первые несколько дней всё кажется избыточно сложным. Потом начинаешь понимать логику — и она оказывается довольно стройной. Каждая абстракция решает конкретную проблему, которая неизбежно возникает при работе с контейнерами в масштабе.
Хорошая новость: minikube на ноутбуке, официальная документация kubernetes.io и пара часов экспериментов дают достаточно контекста, чтобы перестать бояться этого слова и начать разбираться всерьёз.


