Docker или LXD: две системы контейнеров для разных задач
Docker и LXD не конкурируют за одну и ту же роль. Первая система упаковывает одно приложение в неизменяемый контейнер и оптимизирована для микросервисов и CI/CD. Вторая предоставляет полноценную операционную систему в контейнере и подходит для legacy-нагрузок, мультитенантных окружений и задач, где…
Что выбрать: Docker или LXD — две системы контейнеров для разных задач
Docker и LXD не конкурируют за одну и ту же роль. Первая система упаковывает одно приложение в неизменяемый контейнер и оптимизирована для микросервисов и CI/CD. Вторая предоставляет полноценную операционную систему в контейнере и подходит для legacy-нагрузок, мультитенантных окружений и задач, где нужна полная совместимость с системными сервисами. Ошибка в выборе оборачивается либо неделями переписывания кода под Docker, либо неоправданными затратами ресурсов на LXD там, где хватило бы лёгкого контейнера.
В 2015 году Docker перешёл с LXC на собственный рантайм runc, создав иллюзию, будто две технологии теперь конкурируют. На деле LXC/LXD и Docker сосуществуют и часто дополняют друг друга. Например, в облачных провайдерах LXD используют для изолированных окружений разработчиков, а внутри этих окружений запускают Docker-контейнеры с микросервисами. Такой подход снижает накладные расходы на виртуализацию и упрощает управление инфраструктурой.
Docker: когда приложение важнее системы
Docker упаковывает одно приложение в неизменяемый контейнер. Образ строится слоями: каждая инструкция в Dockerfile — новый слой, который кешируется. Это ускоряет сборку и экономит дисковое пространство, так как одни и те же базовые слои (например, Ubuntu 22.04) делят между собой сотни контейнеров.
Запуск контейнера — миллисекунды. Потребление ресурсов минимально: 2–3% CPU и 10–20 МБ RAM на контейнер. Это делает Docker идеальным для микросервисов, CI/CD и облачных рабочих нагрузок. В экосистеме Docker Hub тысячи готовых образов, а инструменты вроде Docker Compose, Swarm и Kubernetes решают задачи оркестрации, мониторинга и безопасности.
Но неизменяемость — двусторонний нож. Если нужно изменить что-то в работающем приложении, контейнер останавливают, образ пересобирают и деплойют снова. Для системных задач, где требуется долгоживущее состояние (например, база данных или файловое хранилище), это не всегда удобно. В таких случаях Docker либо усложняет архитектуру, либо заставляет изобретать костыли вроде томов и sidecar-контейнеров.
LXD: системные контейнеры, которые ведут себя как лёгкие ВМ
LXC/LXD — это системные контейнеры. Они позволяют запускать полноценные ОС с systemd, cron, SSH и другими системными сервисами. LXC — низкоуровневый инструмент, LXD — надстройка для удобного управления: REST API, кластеризация, живая миграция, снимки состояния.
Создание контейнера:
lxc-create -t download -n mycontainer -- -d ubuntu -r focal -a amd64
Запуск:
lxc-start -n mycontainer -d
Подключение:
lxc-attach -n mycontainer
LXD поддерживает кластеризацию, что удобно для высокой доступности. Можно мигрировать работающий контейнер между хостами без остановки. Для безопасности LXD позволяет запускать непривилегированные контейнеры: даже если внутри контейнера root, на хосте у него не будет прав root.
Но за удобства приходится платить. LXD-контейнеры стартуют за секунды (из-за запуска init-системы), потребляют не менее 50–100 МБ RAM и требуют больше дискового пространства. Производительность диска и сети почти как у хоста, но скорость запуска и масштабирование уступают Docker.
Где Docker проваливается: системные задачи, которые не решить слоями
Возьмём legacy-приложение на Java с init-скриптами, cron-задачами и зависимостями от конкретной версии ОС. Попытка завернуть его в Docker потребует переписывания архитектуры:
- Разделение на несколько контейнеров: один для приложения, другой для cron, третий для базы данных.
- Адаптация init-скриптов под systemd или supervisord.
- Настройка томов для долгоживущего состояния.
Время адаптации — дни или недели. Результат: сложная архитектура, которую тяжело поддерживать, и лишние слои абстракции.
Другая проблема — безопасность. Docker изолирует приложения на уровне процессов, но контейнеры делят одно ядро. Если контейнер скомпрометирован, атака может распространиться на хост. LXD предлагает более глубокую изоляцию (например, непривилегированные контейнеры), но требует более тщательной настройки профилей безопасности.
Где LXD проваливается: скорость и масштабирование
Docker выигрывает в скорости запуска и масштабировании однотипных контейнеров. В CI/CD это критично: тысячи контейнеров запускаются и останавливаются в минуту. LXC/LXD для таких задач не подходит: старт занимает секунды, а потребление ресурсов выше.
Экосистема Docker тоже богаче. Docker Hub, Kubernetes, Swarm, Compose, мониторинг, безопасность через Docker Scout — всё это уже настроено и работает из коробки. У LXD нет аналога Docker Hub, а интеграция с Kubernetes требует ручной настройки. Для DevOps-команд это означает дополнительные усилия по оркестрации и поддержке.
Пять минут на развёртывание против недель адаптации
Реальный кейс: команда пытается быстро развернуть микросервис на Go. Docker-образ собирается за минуты, контейнер запускается за миллисекунды, а Kubernetes автоматически масштабирует нагрузку. Всё работает с первого раза.
Та же команда пытается развернуть legacy-приложение на Java с cron-задачами. В Docker приходится переписывать init-скрипты, адаптировать конфигурацию под supervisor, настраивать тома для базы данных. В LXD контейнер создаётся за минуты, init-система работает как на хосте, cron и системные сервисы поднимаются автоматически. Задача решается за пару часов без изменений в коде.
Когда обе системы нужны вместе
Docker не заменит LXD для системных задач, и наоборот. Но есть сценарий, где обе системы используются вместе: LXD управляет изолированными окружениями (например, для разработчиков), а внутри этих окружений запускаются Docker-контейнеры с микросервисами. Такой подход снижает накладные расходы на виртуализацию и упрощает управление.
Если проект требует гибридного подхода, комбинация LXD + Docker внутри контейнеров — это рабочий вариант. Если проект — облачное приложение с микросервисами, Docker подойдёт лучше. Если проект — legacy-система или нужна полноценная ОС, выбирайте LXD.
Выбирайте по задаче, а не по моде
Docker и LXD не конкурируют за одну и ту же роль. Первая система оптимизирована для приложений и микросервисов, вторая — для системных окружений и legacy-нагрузок. Ошибка в выборе оборачивается либо неделями переписывания кода, либо неоправданными затратами ресурсов.
Не нужно считать Docker универсальным инструментом только потому, что он популярен в DevOps. Не нужно отказываться от LXD ради скорости запуска, если задача требует полноценной ОС. Инженеры, которые понимают разницу между этими системами, экономят время, ресурсы и нервы.