LXC против виртуальной машины: разница на практике
Когда в Proxmox или другой панели нужно создать новое окружение, первый вопрос — LXC-контейнер или полноценная виртуальная машина. Разница не в названии и не в галочке при создании: это два принципиально разных способа делить одно физическое железо, и от выбора зависит и производительность, и то, что именно вы сможете внутри запустить, и насколько вы защищены от соседей. Разберём это без абстракций — на конкретных командах и конкретных последствиях.
Содержание
Что физически происходит внутри
Полная виртуальная машина (KVM, в терминах Proxmox — «qemu») — это эмуляция отдельного компьютера. Гипервизор создаёт виртуальное железо: виртуальный процессор, виртуальную память, виртуальный диск, виртуальную сетевую карту. Поверх этого железа грузится собственное ядро — то же самое ядро Linux, Windows или BSD, какое загрузилось бы на реальном сервере. VM ничего не знает о хосте, кроме того, что ей выдал гипервизор через эмулированные устройства.
LXC-контейнер устроен иначе. Ядра у него своего нет — контейнер запускает пользовательское пространство (userspace) поверх ядра хоста, разделяя его с самим хостом и со всеми остальными контейнерами на этой машине. Изоляция достигается не отдельным ядром, а средствами самого ядра: namespaces (контейнер видит свой набор процессов, свою сеть, свою файловую систему, но это иллюзия, создаваемая ядром хоста) и cgroups (ограничение CPU, памяти, I/O). Разницу с изнутри можно проверить одной командой:
# внутри LXC-контейнера
uname -r
# внутри VM на том же хосте
uname -r
В контейнере версия ядра будет идентична версии на хосте — потому что это буквально одно и то же ядро. В VM версия ядра может отличаться сколько угодно: хост на одном ядре, гостевая система — на совершенно другом дистрибутиве с другим ядром. Это не деталь реализации, а корень всех практических различий ниже.
Здесь же стоит держать в голове важную оговорку: LXC — это не Docker, хотя механизм похож. Docker контейнеризует одно приложение (один процесс с зависимостями), LXC — «системный контейнер», который ведёт себя как целая Linux-машина: со своим init, своим SSH, своими systemd-юнитами, возможностью поставить несколько сервисов внутри. Если вы привыкли думать в терминах Docker, ближайшая аналогия LXC — «лёгкая VPS внутри VPS», а не «контейнер для одного сервиса».
Производительность и накладные расходы
Раз LXC-контейнер использует ядро хоста напрямую, системные вызовы выполняются нативно — без слоя эмуляции между гостем и железом. Практических накладных расходов на виртуализацию как таковую здесь нет: то, что видит контейнер (кроме ограничений cgroups), выполняется так же быстро, как если бы процесс работал прямо на хосте.
Полная VM устроена иначе: каждое обращение к диску, сети или памяти в общем случае проходит через слой эмуляции железа (у современных гипервизоров — паравиртуализированные драйверы virtio, которые сильно сокращают этот путь, но не убирают его целиком). Оверхед у современного KVM с virtio небольшой, и для подавляющего большинства нагрузок он незаметен на глаз — но он не нулевой, в отличие от LXC. Точные цифры сильно зависят от типа нагрузки (диск, сеть, CPU-bound вычисления, частые системные вызовы), конкретного железа и настроек гипервизора, поэтому дать честное «на X% медленнее» без замера на своей задаче нельзя — не доверяйте цифрам, которые не сопровождаются описанием конкретного теста.
Что можно сказать надёжно: если задача — это множество однотипных Linux-сервисов и важна именно суммарная производительность на весь парк, LXC даёт больше полезной работы с того же железа, потому что часть ресурсов VM тратится не на вашу нагрузку, а на поддержание иллюзии отдельного компьютера.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверИзоляция: где VM ощутимо сильнее
Это обратная сторона того же самого общего ядра. У VM изоляция подкреплена и аппаратными механизмами виртуализации (Intel VT-x/AMD-V), и отдельным ядром: даже если гостевая система полностью скомпрометирована, атакующему ещё нужно пробить гипервизор, чтобы добраться до хоста или до соседних VM. Такие побеги (VM escape) случаются, но это редкие и дорогие в эксплуатации уязвимости.
У LXC граница слабее по конструкции, а не из-за недоработки: раз ядро общее, уязвимость в самом ядре (в подсистеме namespaces, в cgroups, в любом syscall) потенциально даёт доступ не только к своему контейнеру, но и к хосту и соседним контейнерам сразу. Мы разбирали этот нюанс подробнее в статье про миф «контейнер — это песочница»: контейнерная изоляция — это не герметичная граница, а набор ограничений поверх общего ресурса, и относиться к ней стоит соответственно. Механику того, как именно ядро создаёт для контейнера иллюзию отдельной системы, мы показывали в статье про namespaces.
Практический вывод простой: для мультитенантной инфраструктуры, где на одном хосте соседствуют клиенты, которым вы не доверяете (или доверяете не до конца), VM — более безопасный выбор по умолчанию. LXC подходит там, где все контейнеры на хосте контролируете вы сами и они не защищаются друг от друга как от потенциального противника.
Гибкость операционной системы
Здесь ограничение LXC жёсткое и не обходится настройками: контейнер обязан использовать ядро хоста, а значит — ту же архитектуру ядра, что и хост. На Linux-хосте в LXC можно запускать только Linux (разные дистрибутивы, разные версии userspace — это нормально, но ядро одно на всех). Запустить Windows, FreeBSD или любую другую ОС с иным ядром в LXC-контейнере невозможно в принципе, это не вопрос конфигурации.
Полная VM в этом смысле не знает ограничений хоста: гипервизор эмулирует железо, а какую ОС на это железо ставить — решает пользователь. На одном и том же гипервизоре KVM спокойно уживаются VM с Windows Server, VM с FreeBSD и несколько VM с разными дистрибутивами Linux на разных версиях ядра — каждая независима от остальных и от хоста.
# создание LXC-контейнера в Proxmox — доступны только Linux-шаблоны
pct create 201 local:vztmpl/debian-12-standard_12.7-1_amd64.tar.zst \
--hostname web-lxc --memory 2048 --cores 2 \
--rootfs local-lvm:16 --net0 name=eth0,bridge=vmbr0,ip=dhcp
# создание полной VM в Proxmox — можно указать любой ISO, включая не-Linux
qm create 301 --name win-vm --memory 4096 --cores 2 \
--net0 virtio,bridge=vmbr0 \
--cdrom local:iso/windows-server-2022.iso \
--scsihw virtio-scsi-pci --scsi0 local-lvm:32
Если задача заранее предполагает не-Linux гостя, или неизвестно заранее, что там будет стоять через год — VM снимает этот вопрос полностью, а LXC его даже не рассматривает как опцию.
Плотность на одном сервере
Отсутствие накладных расходов на эмуляцию железа напрямую превращается в более высокую плотность. Контейнеру не нужно резервировать память под виртуальное железо и под собственное ядро — типичный «пустой» Linux-контейнер занимает единицы-десятки мегабайт памяти на старте, тогда как «пустая» VM тратит память ещё до запуска пользовательских процессов — на загрузку своего ядра и системные сервисы гостевой ОС.
На практике это значит, что на одном и том же физическом сервере с одним и тем же объёмом CPU/RAM обычно помещается заметно больше LXC-контейнеров, чем полных VM — конкретное число зависит от того, сколько ресурсов вы фактически выделяете каждому окружению, поэтому говорить о универсальном коэффициенте («в N раз больше») смысла нет, ориентируйтесь на свой профиль нагрузки. Именно поэтому LXC-тарифы у хостеров обычно дешевле сопоставимых по ресурсам KVM-тарифов — провайдер физически размещает больше клиентов на том же железе.
Обратная сторона той же плотности — переподписка (overcommit). Если хост-провайдер выделяет ресурсы контейнерам агрессивно рассчитывая, что не все используют их одновременно, «шумный сосед» на LXC потенциально ощутимее сказывается на соседях, чем на VM с более строгим резервированием. Это ещё один аргумент в пользу VM для нагрузок, чувствительных к стабильности производительности во времени, а не только к средней скорости.
Как выбрать: практические критерии
Единого правильного ответа нет — выбор зависит от конкретной задачи. Ниже — сравнение по всем разобранным осям и типичные сценарии для каждого варианта.
| Критерий | LXC | Полная VM (KVM) |
|---|---|---|
| Ядро | Общее с хостом | Собственное, независимое |
| Оверхед виртуализации | Практически нулевой | Небольшой, но не нулевой |
| Изоляция | Слабее (общее ядро — общий риск) | Сильнее (отдельное ядро + эмуляция железа) |
| Гостевая ОС | Только Linux, версия ядра хоста | Любая, независимо от хоста |
| Плотность на хосте | Выше | Ниже |
| Типичная цена у хостера | Ниже | Выше |
| Вложенная виртуализация, модули ядра | Обычно нет или сильно ограничено | Возможна |
Практические сценарии, где LXC — разумный выбор:
- Несколько изолированных, но доверенных друг другу Linux-сервисов на одном хосте (например, внутренние инструменты компании), где плотность и цена важнее строгой границы между ними.
- Разработческие и тестовые окружения, где скорость поднятия контейнера и низкий расход ресурсов важнее максимальной изоляции.
- Сервисы, которым не требуется своё ядро, вложенная виртуализация или не-Linux гостевая ОС.
Сценарии, где нужна именно полная VM:
- Мультитенантная инфраструктура с недоверенными или потенциально враждебными пользователями — например, если вы сами перепродаёте виртуальные машины конечным клиентам.
- Любая задача, где гостевая ОС не Linux, или неизвестно заранее, что там будет запущено.
- Нужна вложенная виртуализация, собственные модули ядра, нестандартные параметры sysctl или файловые системы, которые LXC не даёт менять.
- Compliance-требования или внутренняя политика безопасности, где формально требуется «отдельное ядро» как граница изоляции.
Если решение неочевидно и хочется более широкой матрицы сравнения (включая ситуации, где обсуждается конкретно Docker как альтернатива LXC), у нас есть отдельный разбор что выбрать для сервера — KVM или LXC, а первый практический запуск виртуалки в Proxmox описан в статье про первую виртуалку в Proxmox VE с нуля.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверНужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.
Частые вопросы
Можно ли поставить Docker внутри LXC-контейнера?
Технически возможно при включённой поддержке вложенных namespaces (в Proxmox — опция nesting в конфигурации контейнера), но часть возможностей Docker (некоторые сетевые драйверы, определённые файловые системы, работа с cgroups v1/v2) может работать нестабильно или требовать привилегированного режима контейнера, что снижает изоляцию ещё сильнее. Если Docker — основной сценарий использования, часто проще и надёжнее взять полную VM и ставить Docker уже внутри неё на правах обычного Linux-хоста.
LXC — это то же самое, что Docker?
Нет. Docker (и вообще OCI-контейнеры) проектировался для контейнеризации одного приложения с его зависимостями — обычно один процесс на контейнер. LXC — «системный» контейнер: полноценное Linux-окружение со своим init, сервисами, пользователями, будто отдельная машина. Механизм изоляции у обоих (namespaces, cgroups) один и тот же, но назначение и типичный образ использования разные.
Что произойдёт, если в ядре хоста найдут критическую уязвимость?
Для LXC-контейнеров на этом хосте это прямой риск — уязвимость в общем ядре потенциально затрагивает все контейнеры сразу, и защититься на уровне контейнера нельзя, только обновлением ядра хоста. Для полных VM риск ниже: чтобы добраться до других VM или хоста, атакующему нужна отдельная уязвимость непосредственно в гипервизоре, а не в ядре гостя.
Можно ли на лету «превратить» LXC в VM или наоборот?
Нет, это разные технологии виртуализации с разным форматом хранения диска и разной моделью загрузки, прямой конвертации «в одну кнопку» не существует. Практически проще развернуть новое окружение нужного типа и перенести туда данные и конфигурацию сервиса.
Правда ли, что LXC всегда быстрее VM?
Только в смысле отсутствия накладных расходов на эмуляцию железа — это структурное преимущество LXC. Но реальная скорость конкретного приложения зависит от того, сколько ресурсов ему выделено, от диска, от сети и от самой нагрузки; на лёгких задачах разница может быть незаметна на глаз даже без замера.
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →