
Docker и Kubernetes: как они работают вместе и в чём разница

Docker и Kubernetes — в чём разница между ними? Этот вопрос регулярно возникает у разработчиков, которые уже научились собирать контейнеры, но столкнулись с задачей запустить их в продакшне надёжно и масштабируемо. Docker и Kubernetes решают разные задачи и не конкурируют, а дополняют друг друга: Docker упаковывает приложение в контейнер, а Kubernetes управляет сотнями таких контейнеров в кластере, следит за их состоянием, распределяет нагрузку и восстанавливает упавшие. Разобравшись в этой связке, вы делаете следующий шаг — от локального запуска к работе в проде.
Docker и Kubernetes — не конкуренты
Путаница возникает потому, что оба инструмента связаны с контейнерами. Однако они обитают на разных уровнях стека, и заменить один другим не получится.
Docker отвечает за упаковку: вы описываете окружение приложения в Dockerfile, собираете образ и запускаете контейнер. Один контейнер, одна машина — всё предсказуемо. Kubernetes вступает в игру, когда контейнеров становится много, они разнесены по нескольким серверам, и всем этим нужно управлять как единым целым. Проще говоря, Docker упаковывает приложение, а Kubernetes его эксплуатирует.
| Критерий | Docker | Kubernetes |
| Задача | Упаковка и локальный запуск приложения | Оркестрация контейнеров в кластере |
| Что делает | Собирает образы, запускает контейнеры | Планирует, масштабирует, восстанавливает поды |
| Ключевой объект | Контейнер (image + runtime) | Pod (один или несколько контейнеров) |
| Когда использовать | Разработка, сборка CI/CD, локальное тестирование | Продакшн, горизонтальное масштабирование, высокая доступность |
| Чего не умеет без другого | Балансировать нагрузку между несколькими хостами, перезапускать упавшие контейнеры | Собирать образы — берёт готовые из реестра |
То есть Docker создаёт артефакт, Kubernetes его эксплуатирует.
Что делает Docker
Docker появился в 2013 году и решил давнюю боль разработчиков: приложение работает на машине одного человека и падает у другого. До контейнеров приложения деплоили прямо на сервер со всеми зависимостями, и несовпадение версий библиотек оборачивалось трудноуловимыми багами. Контейнер изолирует приложение вместе с рантаймом, библиотеками и конфигами, поэтому на любом хосте с Docker оно запускается одинаково. Подробнее о том, как устроена контейнеризация, — в статье «Что такое контейнеризация приложений».
Образы и контейнеры
Образ (image) — неизменяемый слепок файловой системы с приложением, хранится в реестре. Контейнер — запущенный экземпляр образа, изолированный от хоста через namespace и cgroups ядра Linux. Dockerfile — текстовый файл с инструкциями по сборке образа.
Пример минимального Dockerfile для Python-приложения: text
# Базовый образ FROM python:3.12-slim # Рабочая директория внутри контейнера WORKDIR /app # Копируем зависимости и устанавливаем их отдельным слоем (кэш Docker) COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt # Копируем исходный код COPY . . # Порт, который слушает приложение EXPOSE 8000 # Команда запуска CMD ["python", "main.py"]
Сборка и запуск: text
docker build -t my-app:1.0 . docker run -p 8000:8000 my-app:1.0
Слои образа и кэш сборки
Образ собирается послойно: каждая инструкция Dockerfile (FROM, COPY, RUN) создаёт отдельный слой — неизменяемый набор изменений файловой системы. Слои складываются друг на друга и переиспользуются между образами, поэтому если два образа начинаются с одного FROM python:3.12-slim, базовый слой на диске хранится один раз.
На этом устроен кэш сборки. При повторном docker build Docker сравнивает каждую инструкцию с кэшем и пересобирает слой только тогда, когда инструкция или её входные данные изменились. Именно поэтому в примере выше COPY requirements.txt идёт до COPY . . — пока список зависимостей не поменялся, слой с pip install берётся из кэша, а пересобирается только слой с исходным кодом. В обратном порядке кэш ломался бы при любой правке кода, и установка зависимостей запускалась бы заново каждый раз.
Multi-stage build и теги
Multi-stage build помогает не тащить в финальный образ инструменты сборки. Dockerfile описывает несколько стадий (FROM ... AS builder), а в итоговый образ через COPY --from=builder копируется только результат, например скомпилированный бинарник без компилятора и заголовочных файлов. Так образ на Go или C++ ужимается с сотен мегабайт до десятков, а чем меньше содержимого, тем меньше поверхность атаки.
Каждый образ адресуется тегом вида my-app:1.0. Тег — это метка версии, а не сам образ: под одним именем latest в реестре может лежать разное содержимое в разное время. Для продакшна теги фиксируют явно (1.4.2, хэш коммита), чтобы кластер поднимал именно ту версию, которую тестировали, а не случайный latest.
Главное ограничение Docker в том, что он отлично справляется с одним контейнером на одном хосте. Как только нужно запустить 50 контейнеров на 10 серверах с автомасштабированием, Docker Engine с этим не справляется. Здесь начинается зона Kubernetes.
Что делает Kubernetes
Kubernetes (сокращённо K8s) — система оркестрации контейнеров с открытым исходным кодом, которую Google выпустил в 2014 году на основе своего внутреннего инструмента Borg. Kubernetes отвечает за то, что происходит с контейнерами после того, как они собраны: где их запустить, сколько копий держать, что делать при падении.
Оркестрация контейнеров
Kubernetes решает четыре основные задачи.
- Планирование (scheduling): Kubernetes смотрит на доступные ноды кластера, оценивает их ресурсы и решает, на какой ноде запустить каждый под — конкретный сервер не указывается, планировщик делает это автоматически на основе заявленных лимитов CPU и памяти.
- Масштабирование: Horizontal Pod Autoscaler следит за нагрузкой и добавляет или убирает поды автоматически, а Cluster Autoscaler добавляет ноды в кластер, если подам не хватает места — при пиковой нагрузке кластер растёт, в ночное время сжимается.
- Сеть: каждый под получает IP-адрес, Service обеспечивает стабильную точку входа и балансирует запросы между подами, а Ingress управляет внешним HTTP-трафиком — всё это Kubernetes настраивает автоматически.
- Самовосстановление: если под упал, Kubernetes перезапустит его, а если вышла из строя нода — поды переедут на здоровые. Это называется Self-Healing: система постоянно сравнивает желаемое состояние кластера с реальным и устраняет расхождение.
Как они работают вместе
На практике Docker и Kubernetes — последовательные звенья одного пайплайна. Разработчик пишет код и Dockerfile, CI/CD-система собирает образ и пушит его в реестр, Kubernetes берёт образ из реестра и запускает поды.
От образа к поду
Полный путь контейнера от кода до продакшна выглядит так.
- Разработка: вы пишете Dockerfile и тестируете контейнер локально через docker build и docker run.
- CI/CD: пайплайн, например GitLab CI, автоматически собирает образ при коммите и публикует его в Container Registry с тегом версии.
- Развёртывание в K8s: вы описываете желаемое состояние в YAML-манифесте (объекты Deployment, Service) и применяете его командой kubectl apply, а Kubernetes читает манифест и начинает работу.
- Запуск подов: Kubernetes отправляет на каждую ноду задание запустить под, container runtime на ноде скачивает образ из реестра и запускает контейнер.
- Эксплуатация: Kubernetes следит за подами, масштабирует их при необходимости и восстанавливает упавшие.
Что Kubernetes добавляет поверх контейнера
Сам по себе контейнер — изолированный процесс: Docker знает, что он запущен, но не знает, готов ли он принимать трафик и жив ли на самом деле. Kubernetes достраивает над контейнером слой управления, которого у Docker нет, и складывается он из нескольких элементов.
Проверки состояния (probes). Kubernetes периодически опрашивает контейнер по двум независимым пробам. Liveness probe проверяет, жив ли процесс на самом деле: если проверка не проходит, Kubernetes считает контейнер зависшим и перезапускает его. Readiness probe проверяет, готов ли контейнер принимать запросы: пока приложение прогревается или подгружает кэш, под исключается из балансировки Service, и трафик на него не идёт. Разделение важно, потому что контейнер может быть жив, но ещё не готов принимать запросы.
ConfigMap и Secret. Конфигурацию и код держат раздельно. ConfigMap хранит несекретные параметры — адреса сервисов, флаги, значения по умолчанию, а Secret хранит чувствительные данные: пароли к базе, ключи API, токены. Оба подаются в под как переменные окружения или файлы, а не зашиваются в образ. Благодаря этому один и тот же образ проходит путь dev → staging → prod без пересборки, меняется только подключённый ConfigMap или Secret.
Декларативная модель. Docker выполняет императивные команды — запусти этот контейнер, и всё. Kubernetes работает от желаемого состояния: в манифесте вы объявляете, что нужно три реплики этого образа, а контроллеры сами приводят кластер к этому состоянию и удерживают его — доводят число подов до трёх при падении, выкатывают новую версию по одному поду без простоя (rolling update) и откатывают её при сбое.
Образы, реестры и container runtime
Чтобы понять совместную работу Docker и K8s, важно разобраться в трёх понятиях: образ, реестр и container runtime.
Образ — неизменяемый артефакт, который содержит всё необходимое для запуска приложения: код, рантайм, библиотеки, переменные окружения. Образы хранятся в реестрах — Docker Hub, GitHub Container Registry, GitLab Registry или собственном приватном реестре.
Реестр — это репозиторий для образов, и Kubernetes не собирает образы сам, а скачивает готовые из реестра. Именно поэтому CI/CD-пайплайн должен сначала собрать образ и запушить его, а потом уже Kubernetes может его использовать.
Публичные реестры вроде Docker Hub подходят для открытых образов, но продуктовый код обычно хранят в приватном реестре, чтобы образы не были доступны кому попало. Приватный реестр требует аутентификации, и Kubernetes получает доступ к нему через отдельный Secret типа docker-registry, на который под ссылается полем imagePullSecrets. Без него docker pull из закрытого реестра завершится ошибкой авторизации, и под не поднимется.
Container runtime — компонент, который фактически запускает контейнер на ноде. Docker исторически был стандартным runtime для Kubernetes, но в версии 1.24 поддержку dockershim удалили. Сегодня стандартный runtime в K8s — containerd или CRI-O, который реализует интерфейс CRI (Container Runtime Interface).
На практике это означает, что Docker как инструмент для сборки образов остаётся актуальным и никуда не исчезает. Образы, собранные через docker build, полностью совместимы с containerd — оба работают со стандартом OCI (Open Container Initiative). Просто в самом кластере Kubernetes для запуска контейнеров Docker Engine больше не нужен.
Для разработчика ничего не меняется: пишете Dockerfile, собираете образ, пушите в реестр, а Kubernetes подберёт образ оттуда и запустит через containerd без каких-либо модификаций.
От Docker к Kubernetes в VK Cloud
Когда вы готовы перенести контейнеризованное приложение в продакшн, Managed Kubernetes в VK Cloud позволяет сделать это без настройки инфраструктуры с нуля.
Стандартные Docker-образы запускаются в Managed Kubernetes VK Cloud без переделки: достаточно указать в манифесте имя образа из реестра, остальное K8s сделает сам.
Кластер поднимается за 10 минут, а мастер-ноды (Control Plane) предоставляются бесплатно — вы платите только за рабочие ноды. Платформа поддерживает версии K8s 1.25–1.32, что позволяет выбрать нужную версию под существующий стек или плавно обновляться. Кластер выдерживает до 55 000 подов, а Cluster Autoscaler автоматически добавляет и убирает ноды в зависимости от нагрузки. При падении ноды платформа восстанавливает её за 3–5 минут без вашего участия (Self-Healing).
Надёжность обеспечивают SLA 99,95%, мультизональное размещение на три ЦОД в одном регионе и изолированный Control Plane по схеме K8s-in-K8s, а собственная сеть SDN Sprut даёт прирост скорости на 34% по сравнению с классическим overlay. Посекундная тарификация и режим stop/start позволяют платить только за реально использованное время — удобно для тестовых и непостоянных нагрузок. В маркетплейсе аддонов доступны GitLab, Istio, Prometheus и другие инструменты, которые подключаются в несколько кликов из консоли: GitLab-интеграция позволяет выстроить полный CI/CD-пайплайн — сборка образа в GitLab CI, пуш в Container Registry, автодеплой в кластер.
Если вы уже работаете с Docker и хотите сделать следующий шаг, попробуйте Managed Kubernetes в VK Cloud: кластер поднимается за 10 минут, мастер-ноды бесплатны, а бонус до 12 000 ₽ позволяет протестировать платформу без вложений. Оставить заявку →
FAQ
Docker и Kubernetes — это одно и то же?
Нет. Docker — инструмент для упаковки приложений в контейнеры, а Kubernetes — система для управления контейнерами в кластере. Они решают разные задачи и используются вместе: Docker создаёт образ, Kubernetes его запускает и эксплуатирует.
Нужен ли Docker, если есть Kubernetes?
Docker как инструмент разработки и сборки образов нужен — именно через docker build разработчик собирает образ локально и проверяет его перед деплоем. Docker Engine как runtime внутри кластера не нужен, его заменил containerd, но сами образы, собранные Docker, полностью совместимы с K8s.
Что такое container runtime?
Container runtime — компонент, который физически запускает контейнер на ноде: изолирует процессы, монтирует файловую систему, выделяет сеть. В современных кластерах Kubernetes стандартный runtime — containerd: он реализует интерфейс CRI и работает с образами формата OCI, которые собирает Docker.
Можно ли запускать Docker-образы в K8s?
Да, без каких-либо модификаций. Kubernetes скачивает образ из реестра и запускает через containerd — любой образ, собранный через docker build, совместим с K8s, поскольку оба инструмента работают со стандартом OCI.
С чего начать — с Docker или K8s?
С Docker. Сначала научитесь писать Dockerfile, собирать образы и запускать контейнеры локально. Когда приложение стабильно работает в контейнере и вы понимаете, как управлять зависимостями и конфигурацией через переменные окружения, переходите к Kubernetes — попытка изучить K8s, не понимая контейнеров, только усложнит процесс.
Docker отвечает за упаковку и локальную разработку, Kubernetes — за надёжную эксплуатацию в продакшне: масштабирование, самовосстановление, балансировку, обновления. Вместе они образуют стандартный стек современной разработки.
Оставьте заявку, чтобы получить консультацию
Оставьте заявку или напишите на почту digital.tech@corp.mail.ru, чтобы узнать больше о сервисах VK и получить коммерческое предложение.

Почитать по теме


Контейнеризация приложений: что это такое и когда стоит использовать
