Что если я скажу, что в вашей системе уже есть встроенный инструмент для контейнеризации, который работает быстрее Docker и тесно интегрирован с операционной системой? Знакомьтесь с systemd-nspawn
- мощный, но часто недооценённый инструмент, который давно встроен в systemd. Разработчики, привыкшие к Docker, часто упускают из виду эту альтернативу, а зря.
Почему systemd-nspawn, а не Docker?
Экосистема контейнеризации сегодня монополизирована Docker и containerd, но systemd-nspawn предлагает идеологически другой подход. Вместо сложного стека демонов, API и клиентов мы имеем единую команду и глубокую интеграцию с системой. Отличия принципиальные:
- Минимальные зависимости: Только glibc и systemd (почти всегда уже установлены)
- Нет центрального демона: Контейнеры запускаются напрямую через systemd
- Полная интеграция с cgroups v2: Изоляция ресурсов без дополнительных настроек
- Прямой доступ к системным инструментам:
journalctl
,machinectl
,systemd-resolve
работают с контейнерами "из коробки" - Мгновенное развёртывание: Запуск готовых образов Arch, Debian или Fedora за секунды
Практический пример: при разработке системного ПО мне часто нужна изолированная среда для тестирования взаимодействия сервисов. С nspawn я создаю временный контейнер, запускаю в нём кастомный сервис и через journalctl сразу вижу все логи без дополнительной настройки.
Установка и настройка в Arch Linux
Хотя systemd-nspawn входит в базовую установку systemd, нам понадобятся дополнительные утилиты для удобной работы:
sudo pacman -S arch-install-scripts debootstrap
Первая команда установит инструменты для развёртывания Arch Linux, вторая - для Debian/Ubuntu. Для других дистрибутивов выберите соответствующие пакеты (dnf-install
для Fedora и т.д.).
Критический шаг настройки: активируем службу systemd-networkd для управления сетевыми интерфейсами контейнеров. Редактируем файл /etc/systemd/network/80-container-host0.network
:
[Match]
Name=host0
[Network]
DHCP=yes
IPForward=yes
Активируем службу:
sudo systemctl enable --now systemd-networkd
Создаём первый контейнер
Пошаговый пример для создания контейнера Arch Linux:
# Создаём корневую файловую систему
sudo mkdir -p /var/lib/machines/arch-base
# Инициализируем базовую систему Arch
sudo pacstrap -c /var/lib/machines/arch-base base base-devel
# Копируем резо́лвер для доступа к сети
sudo cp /etc/resolv.conf /var/lib/machines/arch-base/etc/
Запускаем контейнер в интерактивном режиме:
sudo systemd-nspawn -D /var/lib/machines/arch-base
Внутри контейнера устанавливаем базовые компоненты:
pacman -Syu
passwd # устанавливаем пароль root
exit
Теперь у нас есть рабочий контейнер! Запускаем его как службу:
sudo systemd-run --service-type=notify -p DynamicUser=no \
--unit=arch-container systemd-nspawn \
-D /var/lib/machines/arch-base --boot --network-veth
Проверяем статус:
machinectl list
Управление через machinectl
Интерфейс machinectl
- ваш основной инструмент работы с контейнерами:
# Просмотр запущенных контейнеров
machinectl list
# Вход в контейнер
machinectl login arch-container
# Запуск команд без входа
machinectl shell arch-container /usr/bin/ls /
# Просмотр логов контейнера
journalctl -M arch-container -f
# Остановка контейнера
machinectl poweroff arch-container
Для постоянной регистрации контейнера создадим файл /etc/systemd/nspawn/arch-container.nspawn
:
[Exec]
Boot=on
[Network]
VirtualEthernet=yes
Теперь при запуске системы контейнер будет регистрироваться автоматически.
Монтирование томов и работа с сетью
Динамическое монтирование позволяет безопасно предоставлять контейнерам доступ к ресурсам хоста. Пример монтирования каталога проекта:
sudo systemd-nspawn -D /var/lib/machines/arch-container \
--bind=/home/user/projects:/projects
Более безопасный способ - использовать readonly-монтирование:
--bind-ro=/mnt/backups:/backups
Настройка сети - одно из главных преимуществ nspawn. Помимо простого --network-veth
, доступны сложные сценарии:
# Связка двух контейнеров в изолированную сеть
sudo systemd-nspawn -D /var/lib/machines/frontend \
--network-bridge=br0 --network-macvlan=eth0 -n
sudo systemd-nspawn -D /var/lib/machines/backend \
--network-bridge=br0 --network-macvlan=eth0 -n
Для проброса портов используем:
machinectl bind arch-container 8080:80
Продвинутые сценарии
Автоматизация сборки
Создадим служебный контейнер для сборки проектов. Файл /etc/systemd/system/build-container.service
:
[Unit]
Description=Build Container
After=network.target
[Service]
ExecStartPre=/usr/bin/mkdir -p /var/lib/machines/build
ExecStart=/usr/bin/systemd-nspawn --keep-unit \
-D /var/lib/machines/build \
--bind=/home/user/src:/src \
--bind=/home/user/build:/build \
/usr/bin/make -C /src
Restart=on-failure
Type=simple
[Install]
WantedBy=multi-user.target
Юниты для управления контейнерами
Создаём container-arch.service
в /etc/systemd/system/
:
[Unit]
Description=Arch Linux Container
[Service]
ExecStart=/usr/bin/systemd-nspawn --keep-unit -bD /var/lib/machines/arch-container
ExecStop=/usr/bin/machinectl poweroff arch-container
KillMode=mixed
Type=notify
RestartForceExitStatus=133
SuccessExitStatus=133
Синхронизация времени
Для контейнеров, критичных к точному времени:
systemd-nspawn --setenv=SYSTEMD_TIME_SYNC_ON_NETWORK=true -D /path/to/container
Производительность и отладка
Проведите простой тест развёртывания:
time sudo systemd-nspawn -D /var/lib/machines/arch-container --ephemeral
Сравните с Docker:
time docker run --rm archlinux echo "test"
В моих тестах nspawn запускается на 40% быстрее благодаря отсутствию демона и прямой интеграции.
Чтобы посмотреть текущие cgroup/ressource ограничения контейнера:
systemd-cgls -M arch-container
Для комплексной проверки изоляции используйте:
systemd-analyze security arch-container
Философия и границы применения
Система nspawn следует философии Unix: одна программа делает одну вещь хорошо. Она не пытается заменить Docker во всём. Основные сценарии применения:
- Локальные среды разработки и тестирования
- Изолированные билд-агенты
- Песочницы для потенциально опасного ПО
- Легковесные службы в embedded-системах
- Быстрое создание прототипов микросервисов
Когда Docker всё же предпочтительнее:
- Необходимость использовать Docker Compose
- Совместная работа в команде, где Docker - стандарт
- Использование Docker Hub и готовых образов
- Требуется Kubernetes
Заключение: начните наблюдать за процессами по-новому
Глубина интеграции nspawn с Linux позволяет видеть контейнеры как естественное расширение системы, а не как чужеродные сущности. При следующей отладке сложной проблемы попробуйте запустить проблемный сервис в изолированном контейнере с помощью nspawn. Не удивляйтесь, если обнаружите, что логи контейнера стали частью вашего основного journalctl - это не ошибка, а фича, которая однажды сэкономит вам часы работы.
То, что начинается как эксперимент, часто становится основным инструментом. У меня nspawn заменила Vagrant для 80% задач локального тестирования. Попробуйте создать свой первый контейнер прямо сейчас:
sudo mkdir /var/lib/machines/test-container
sudo pacstrap -c /var/lib/machines/test-container base
sudo systemd-nspawn -D /var/lib/machines/test-container
Когда выйдете из контейнера, сотрите его:
sudo rm -rf /var/lib/machines/test-container
Разве не проще, чем пляски с Dockerfile?