Зачем Kubernetes
Жизнь без Kubernetes
Ты запустил своё первое приложение в Docker. Всё работает локально. Но что происходит в production?
Сценарий 1: Контейнер упал
Приложение падает из-за утечки памяти раз в 2 часа. Кто перезапустит его в 3 ночи? С Docker — никто, пока не проснётся человек.
Сценарий 2: Высокая нагрузка
Пришло 10x больше трафика. Нужно быстро запустить ещё 5 копий приложения. С Docker — это ручная работа: зайти на сервер, написать команды, настроить load balancer.
Сценарий 3: Обновление без простоя
Нужно обновить версию приложения без даунтайма. С Docker придётся вручную останавливать старые контейнеры и запускать новые, теряя запросы в процессе.
Сценарий 4: Несколько серверов
Приложение выросло, нужно 3 сервера. Как распределить контейнеры? Как следить за всеми? Что делать если один сервер упадёт?
Kubernetes решает все эти проблемы.
Что такое Kubernetes
Kubernetes (k8s) - это система управления контейнерными приложениями. Главная идея Kubernetes не в том, чтобы вручную выполнить много команд, а в том, чтобы описать: какое состояние мы хотим получить.
Например, мы хотим сказать системе:
- у приложения должно быть 3 копии;
- все копии должны использовать image
nginx:1.25; - если одна копия упала, нужно вернуть их снова к 3;
- у приложения должен быть стабильный сетевой адрес;
- настройки нужно передать отдельно от image.
То есть мы описываем не каждый ручной шаг, а итоговую картину: "в кластере должно быть вот так". Kubernetes дальше сам сравнивает желаемое состояние с фактическим и пытается привести кластер к тому, что мы описали.
Важная идея: Kubernetes работает не как список разовых команд, а как система поддержания желаемого состояния.
Ты описываешь, что должно быть: сколько копий, какой image, какие настройки, какой доступ. Kubernetes постоянно сравнивает это описание с реальностью и пытается исправить расхождение.
Если сейчас работает 2 копии, а мы описали 3, Kubernetes создаст ещё одну. Если одна копия умерла, Kubernetes создаст замену. Если мы поменяли версию image, Kubernetes постепенно обновит приложение.
Важно: Kubernetes не заменяет Docker image. Образ приложения всё ещё нужен. Kubernetes управляет тем, как эти образы запускать, обновлять, масштабировать и связывать между собой.
Императивный и декларативный подход
Чтобы понять Kubernetes, удобно различать два подхода: императивный и декларативный.
Императивный подход: ты говоришь, какое действие выполнить прямо сейчас.
Это похоже на обычную работу в терминале: "запусти", "создай", "удали", "покажи". Такой подход удобен для обучения, быстрых проверок и простых действий в лабораторной.
Декларативный подход: ты описываешь итоговое состояние в манифесте и применяешь его.
Здесь главное не команда сама по себе, а файл с описанием. Ты как бы говоришь: "Kubernetes, сделай так, чтобы в кластере было состояние из этого файла".
В Kubernetes мы используем именно декларативный подход - мы описываем желаемое состояние системы, а Kubernetes следит за тем чтобы реальное состояние совпадало с желаемым. И если надо сам добавляет, обновляет, удаляет приложения чтобы привести к желаемому состоянию.
В первых лабораторных мы иногда будем создавать объекты короткими командами kubectl, чтобы быстрее увидеть результат и не утонуть в YAML с самого начала. Но в реальной работе важнее именно манифесты: их хранят в Git, проверяют в code review, применяют через CI/CD и по ним видно, какое состояние кластера считается правильным.
Абстракции Kubernetes
Чтобы удобно описывать желаемое состояние, Kubernetes даёт готовые абстракции. Мы не описываем вручную каждый процесс, IP-адрес и правило балансировки. Вместо этого используем объекты Kubernetes.
Важная идея: объекты Kubernetes - это язык, на котором мы описываем разные части приложения и инфраструктуры.
Pod описывает запуск контейнера, Deployment - стабильную группу Pod'ов и обновления, Service - сетевой доступ, ConfigMap - настройки. Запомнить Kubernetes проще, если видеть не набор YAML, а набор абстракций под разные задачи.
| Объект | Что описывает |
|---|---|
| Pod | минимальную единицу запуска контейнера |
| Deployment | приложение, количество копий и способ обновления |
| ReplicaSet | технически поддерживает нужное число Pod'ов для Deployment |
| Service | стабильный сетевой адрес для группы Pod'ов |
| ConfigMap | обычные настройки приложения |
| Secret | чувствительные значения: пароли, токены, ключи |
| Namespace | логическое разделение ресурсов внутри кластера |
Эти объекты и есть язык, на котором мы объясняем Kubernetes желаемое состояние. Например: "мне нужен Deployment с 3 копиями", "мне нужен Service для доступа к этим Pod'ам", "мне нужна ConfigMap с настройками".
Первый курс не требует знать все ресурсы Kubernetes. Но перед каждой командой полезно спросить: "я сейчас описываю приложение, сетевой доступ, конфигурацию или просто смотрю текущее состояние?".
Что такое манифест
Манифест - это файл с описанием Kubernetes-объекта. Обычно это YAML-файл, который применяют командой kubectl apply -f.
Манифест - не скрипт и не список команд. В нём не написано "сначала сделай раз, потом сделай два". В нём написано: "в кластере должен существовать вот такой объект".
Почти каждый манифест содержит несколько базовых частей:
| Поле | Что означает |
|---|---|
apiVersion |
версия Kubernetes API для этого типа объекта |
kind |
тип объекта: Pod, Deployment, Service и так далее |
metadata |
имя, labels, namespace и другие служебные данные |
spec |
желаемое состояние объекта |
Есть ещё status, но обычно его не пишут руками в манифесте. status заполняет сам Kubernetes: сколько Pod'ов запущено, готов ли объект, какие ошибки возникли.
Как выглядит манифест
Например, вот описание: "я хочу 3 копии nginx версии 1.25".
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
replicas: 3 # всегда держи 3 копии
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.25
После применения этого манифеста Kubernetes:
- Создаст 3 Pod'а с nginx
- Будет следить, что их всегда 3 (если один упадёт — создаст новый)
- При обновлении образа — заменит Pod'ы постепенно, без даунтайма
- Распределит их по разным серверам для надёжности
Ключевые возможности
Самовосстановление (Self-healing)
Если Pod упал → Kubernetes перезапустит его автоматически.
Если узел (Node) вышел из строя → Kubernetes перенесёт Pod'ы на другие узлы.
Автомасштабирование (Auto-scaling)
# HorizontalPodAutoscaler: масштабируй от 2 до 10 при нагрузке
spec:
minReplicas: 2
maxReplicas: 10
targetCPUUtilizationPercentage: 70
Rolling Updates (Обновления без простоя)
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1 # запустить +1 новый перед удалением старого
maxUnavailable: 0 # не допускать простоя
Service Discovery
Pod'ы получают DNS-имена. Сервисы находят Pod'ы автоматически.
Storage Orchestration
Kubernetes может автоматически создавать PersistentVolume в облаке по запросу.
Когда использовать Kubernetes
| Ситуация | Kubernetes нужен? |
|---|---|
| 1 приложение, 1 сервер | Обычно нет — Docker достаточно |
| Несколько сервисов, нужна надёжность | Да |
| Команда из 5+ разработчиков | Да |
| Нужен zero-downtime deploy | Да |
| ML workloads с GPU | Да |
| Стартап с MVP | Возможно нет — слишком сложно |
Kubernetes vs Docker Compose
| Аспект | Docker Compose | Kubernetes |
|---|---|---|
| Масштаб | Один хост | Множество хостов |
| Self-healing | Нет | Да |
| Auto-scaling | Нет | Да |
| Сложность | Низкая | Высокая |
| Цель | Разработка, малые проекты | Production |
Контроллеры и reconciliation loop
Kubernetes постоянно выполняет reconciliation: сравнивает желаемое состояние с фактическим. Это не разовая команда, а цикл.
Пример: Deployment описывает replicas: 3. Если один Pod удалён вручную, ReplicaSet Controller увидит, что фактически осталось 2, и создаст новый Pod. Поэтому в Kubernetes часто не “чинят Pod”, а меняют объект верхнего уровня: Deployment, StatefulSet, Job.
Kubernetes не гарантирует, что конкретный Pod будет жить вечно. Он гарантирует, что контроллер будет пытаться поддерживать нужное количество и состояние.
Поэтому в Kubernetes важно мыслить объектами верхнего уровня и проверками состояния, а не “сервером по имени”. Это главный переход от ручного Docker к оркестрации.
В следующей статье разберём как устроен кластер Kubernetes изнутри.
