Виртуализация запускает на одном физическом сервере несколько независимых операционных систем со своим ядром у каждой. Контейнеризация запускает несколько изолированных процессов, которые делят одно ядро хостовой системы. Разница в устройстве изоляции определяет скорость запуска, плотность размещения и список задач, для которых подходит каждый подход.
Чем виртуальная машина отличается от контейнера
Виртуальная машина работает поверх гипервизора и получает в своё распоряжение виртуальный процессор, виртуальную память и виртуальный диск — для гостевой операционной системы это выглядит как отдельное железо. Контейнер не содержит собственного ядра: он использует ядро хостовой системы, а изоляция обеспечивается пространствами имён процессов, сети и файловой системы.
- виртуальная машина может работать под другой операционной системой, чем хост, контейнер — не может
- контейнер запускается за секунды, потому что не грузит отдельное ядро
- виртуальная машина изолирована сильнее, потому что не делит ядро ни с хостом, ни с соседними машинами
Разбор того же вопроса применительно к конкретной платформе виртуализации есть в статье LXC или виртуальная машина в Proxmox.
Сравнение по ключевым параметрам
На практике выбор между виртуальной машиной и контейнером сводится к нескольким измеримым различиям.
| Параметр | Виртуальная машина | Контейнер |
|---|---|---|
| Ядро | своё, отдельное от хоста | общее с хостом |
| Время запуска | десятки секунд на загрузку ОС | обычно доли секунды |
| Изоляция | полная, на уровне гипервизора | на уровне пространств имён ядра |
| Плотность на сервере | ниже из-за накладных расходов на гостевую ОС | выше, процессы легче виртуальных машин |
Запуск контейнеров на собственном сервере через Docker описан в статье настройка Docker на VDS.
Как это выглядит на практике
Контейнер обычно описывают образом, который включает только приложение и его зависимости, без полноценной операционной системы. Запуск веб-сервера в контейнере выглядит так.
docker run -d -p 80:80 nginx
Команда скачивает образ nginx, если его ещё нет локально, и запускает контейнер, пробрасывая порт 80 наружу. Для сравнения, запуск веб-сервера в виртуальной машине потребовал бы сначала установить и настроить целую операционную систему внутри неё.
Что ограничивает каждый из подходов
Контейнер не подходит, если приложению нужно другое ядро, другая операционная система целиком или доступ к низкоуровневым возможностям, которые изолированы пространствами имён. Виртуальная машина в такой ситуации остаётся единственным вариантом.
Виртуальная машина, в свою очередь, избыточна для простых одноразовых задач вроде запуска одного веб-сервиса — здесь контейнер экономит память и запускается быстрее. Контейнеризация внутри гипервизора Proxmox, когда нужны обе модели на одном сервере, разобрана в статье контейнер LXC в Proxmox.
Разница становится заметнее на серверах с ограниченным объёмом памяти: десяток контейнеров с одним и тем же базовым образом может занимать заметно меньше места на диске и в оперативной памяти, чем десяток полноценных виртуальных машин с отдельными копиями операционной системы внутри каждой.
Что делать при выборе модели изоляции
Решение проще принимать по порядку шагов.
- определите, нужна ли приложению отдельная операционная система или другое ядро
- оцените, сколько независимых сервисов должно работать на одном сервере одновременно
- проверьте требования к изоляции — есть ли задачи, которым нельзя доверять общее ядро
- для простых сервисов без особых требований к ядру выбирайте контейнер, для остального — виртуальную машину
Два подхода часто комбинируют: виртуальная машина служит границей изоляции между клиентами, а контейнеры внутри неё разделяют сервисы одного проекта.
Частые вопросы
Можно ли запускать контейнеры внутри виртуальной машины?
Да, это обычная практика: виртуальная машина обеспечивает изоляцию на уровне всего сервера, а контейнеры внутри неё разделяют отдельные сервисы одного проекта между собой.
Что безопаснее — виртуальная машина или контейнер?
Виртуальная машина изолирована сильнее, потому что не делит ядро ни с хостом, ни с соседями, поэтому для недоверенных или чувствительных нагрузок её выбирают чаще, чем контейнер.
Почему контейнеры запускаются быстрее виртуальных машин?
Потому что контейнер использует уже загруженное ядро хостовой системы и не проходит полную загрузку операционной системы, в отличие от виртуальной машины, которая стартует с нуля.