Архитектурная разница между гипервизором и контейнеризацией
Классическая виртуальная машина работает под управлением гипервизора, такого как KVM, VMware ESXi или VirtualBox. Гипервизор полностью эмулирует физическое железо сервера: виртуальные процессоры, сетевые контроллеры, дисковые накопители и оперативную память. Каждая виртуальная машина вынуждена нести в себе полноценный образ гостевой операционной системы со своим ядром, демонами инициализации, системными библиотеками и драйверами. Запуск такой машины означает прохождение полного цикла загрузки ядра и служб, что занимает от десятков секунд до нескольких минут.
Docker решает задачу изоляции на совершенно ином уровне архитектуры. Вместо аппаратной эмуляции контейнер использует средства изоляции ядра Linux, появившиеся задолго до создания самого Docker. Запущенный контейнер остается обычным изолированным процессом основной операционной системы. Все контейнеры на сервере обращаются напрямую к системным вызовам одного общего ядра хоста, минуя прослойку эмуляции оборудования.
Механизмы ядра Linux внутри Docker
Платформа Docker стала популярной в 2013 году благодаря тому, что объединила разрозненные низкоуровневые инструменты ядра Linux в удобный интерфейс. В основе работы любого Linux-контейнера лежат три базовые технологии.
- Пространства имен (namespaces) создают для процесса иллюзию владения собственной операционной системой. Пространство PID изолирует дерево идентификаторов процессов, пространство NET выделяет собственный стек сетевых интерфейсов и портов, пространство MNT дает отдельную таблицу точек монтирования файловой системы, а IPC и UTS обособляют межпроцессное взаимодействие и имя хоста.
- Контрольные группы (cgroups) отвечают за жесткий учет и лимитирование физических ресурсов сервера. С их помощью ядро ограничивает лимиты выделения процессорного времени, физической оперативной памяти, сетевой пропускной способности и дискового ввода-вывода для конкретного контейнера.
- Многослойные файловые системы с объединением (OverlayFS) позволяют собирать образ контейнера из неизменяемых слоев только для чтения. При запуске поверх этих слоев накладывается тонкий временный слой для записи, благодаря чему десятки контейнеров могут одновременно читать одни и те же системные файлы с диска без их дублирования.
Сравнение потребления ресурсов и накладных расходов
Поскольку виртуальной машине требуется собственная ОС, базовый образ Windows Server или Ubuntu Server «из коробки» занимает от 2 до 15 гигабайт дискового пространства и сразу резервирует от 500 мегабайт до пары гигабайт оперативной памяти под служебные нужды. Контейнер базового дистрибутива Alpine Linux весит около 5 мегабайт, а готовый образ с микросервисом на языке Go укладывается в 20-30 мегабайт. При этом контейнер потребляет ровно столько оперативной памяти, сколько нужно самому приложению.
Проблема «у меня на компьютере все работало» и DevOps
До массового внедрения контейнеров перенос готового кода из среды разработки на боевой сервер регулярно ломал приложение. Программист писал сервис на локальной машине с Python версии 3.10 и определенной версией библиотеки OpenSSL, а на производственном сервере системный администратор держал Python 3.8 и другие системные пакеты. Несовпадение путей к файлам, переменных окружения и библиотек требовало долгой ручной синхронизации и написания громоздких сценариев развертывания.
Docker превратил приложение и всю его рабочую среду в единый неизменяемый артефакт сборки, описываемый текстовым файлом Dockerfile. Образ собирается на этапе непрерывной интеграции (CI), проходит тестирование и в абсолютно идентичном виде запускается на серверах тестирования (Staging) и в продакшене. Разработчик получает гарантию, что код будет выполняться в точно таком же бинарном окружении, в котором его отлаживали.
Когда выбирать Docker, а когда виртуальную машину
Выбор архитектурного решения зависит от требований к изоляции, используемых операционных систем и специфики рабочей нагрузки.
- Docker выбирают для микросервисной архитектуры, веб-серверов, очередей сообщений и сценариев горизонтального масштабирования, когда за секунды нужно поднять десять новых копий приложения под наплыв трафика.
- Docker незаменим при организации пайплайнов непрерывной доставки кода (CI/CD), где агенты сборки должны быстро запускать чистые среды для тестов и удалять их сразу после завершения работы.
- Виртуальные машины выбирают при необходимости запускать совершенно разные ядра ОС на одном физическом сервере, например гостевую Windows поверх гипервизора на Linux.
- Виртуализация обязательна для задач со строгими требованиями информационной безопасности, когда на одном сервере работают сервисы разных недоверенных заказчиков или организаций.
- Виртуальные машины применяют для монолитных legacy-систем, баз данных с экстремальными требованиями к прямой работе с контроллерами дисков или приложений, требующих тонких низкоуровневых настроек параметров ядра.
Частые вопросы
Можно ли запустить Docker-контейнер с Windows внутри Linux-сервера?
Напрямую нельзя. Контейнеры Windows требуют общего ядра Windows NT, а Linux-контейнеры используют системные вызовы ядра Linux. Запустить Windows-приложение на Linux-сервере можно только внутри полноценной виртуальной машины с установленной Windows.
Как Docker работает на macOS и Windows, если у них нет ядра Linux?
При установке Docker Desktop операционная система разворачивает скрытую легковесную виртуальную машину Linux через встроенные гипервизоры Hyper-V, WSL 2 или Hypervisor.framework. Все создаваемые контейнеры запускаются внутри этой служебной виртуальной машины.
Теряются ли данные внутри контейнера при его перезапуске?
Временный слой записи удаляется вместе с контейнером. Для сохранения постоянных данных баз данных и файлов пользователей используют тома (Docker Volumes) или монтирование каталогов с хоста (Bind Mounts), которые сохраняют информацию независимо от жизненного цикла контейнера.
Чем Docker отличается от Kubernetes?
Docker создает контейнеры и управляет их запуском на одном сервере. Kubernetes — это инструмент оркестрации более высокого уровня, который координирует работу сотен контейнеров на десятках серверов, балансирует сетевой трафик, перезапускает упавшие контейнеры и управляет автоматическим масштабированием.