четверг, 21 мая 2015 г.

systemd-nspawn для разработчика

На данный момент я работаю в проекте который в качестве целевой платформы установки использует Debian 7 при этом хочется переехать на Debain 8, а сам я сижу на Arch Linux. В результате часто требуется быстренько оказаться в правильном окружении и пособирать свои последние правки. Чаще всего для этого я использовал VirtualBox как наиболее просто конфигурируемое решение, но всегда хотелось побаловаться с лёгкими контейнерами. Правда, всегда отпугивала скорость разворачивания таких решений. Я экспериментировал с LXC и systemd-nspawn, но в первом случае разворачивание виртуалки занимает больше времени чем хочется, а во втором случае всё гладко только если гостевая система использует systemd.

Но вот, свершилось, Debain 8 использует systemd по умолчанию и его можно быстренько разворачивать. Правда, кто-то успел немного подгадить с другой стороны. Теперь в арче сервис systemd-nspawn@ по умолчанию предлагает иметь противоестественные сношения с настройкой идеологически правильного разделения сети между контейнерами добавив ключ --network-veth. Раньше этот сервис позволял запустить контейнер так, что он просто видел хостовый интерфейс и им пользовался, что совершенно не подходит для облачных решений (для которых есть отличные и мощные проекты, такие как OpenVZ и LXC), но очень удобно для нужд разработчиков (а именно для этих целей и позиционировалась разработка systemd-nspawn). Дабы раз и навсегда искоренить этот печальный недостаток, копируем этот сервис из /usr/lib/systemd/system в /etc/systemd/system и уничтожаем использование ненужной "идеологической правильности".

Итак создаём гостевуху:

yaourt -S debootstrap # Если ещё не установлен
sudo debootstrap jessie /var/lib/container/debian8 http://mirror.yandex.ru/debian
sudo systemd-nspawn -D /var/lib/container/debian8
Мы оказались в сверх-минималистичном дебиане с целью задать пароль пользователю root и установить пакет dbus (без него утилита machinectl не сможет подключиться к запущенному контейнеру). Выполнив эти две нехитрые операции нажимаем Ctrl+D чтобы вернуться в основное окружение и честно загрузив контейнер входим в него через парадное крыльцо для дальнейшей настройки:
sudo systemctl start systemd-nspawn@debian8
sudo machinectl login debian8

Вот готово почти всё. Точнее для одноразового использования готово вообще всё. А вот если контейнер планируется использовать для тестов регулярно, то имеет смысл поставить туда ssh и научить systemd автоматически запускать виртуалку при попытке в неё зайти по этому самому ssh. Для этого пишем файл на хосте
/etc/systemd/system/systemd-nspawn@debian8.socket:

[Unit]
Description=The SSH socket of debian8-nspawn container

[Socket]
ListenStream=4022

[Install]
WantedBy=sockets.target
А в гостевой ситеме надо отключить безусловный автозапуск SSH и настроить его активацию через сокет добавив два файла:
/etc/systemd/system/sshd.socket:
[Unit]
Description=SSH Socket for Per-Connection Servers

[Socket]
ListenStream=4022
Accept=yes

[Install]
WantedBy=sockets.target
и /etc/systemd/system/sshd@.service:
[Unit]
Description=SSH Per-Connection Server for %I

[Service]
ExecStart=-/usr/sbin/sshd -i
StandardInput=socket

[Install]
WantedBy=multi-user.target
Alias=sshd.service
После чего в контейнере переключаем SSH на активацию через сокет:
sudo systemctl disable sshd.service
sudo systemctl enable sshd.socket
И на хосте активируем сокет запуска машины:
sudo systemctl enable systemd-nspawn@debian8.socket

Ну вот теперь можно настроить профиль в Konsole и быстренько заходить в виртуалку в два клика. Запуск контейнера до состояния принятия ssh соединения у меня занимает около 2х секунд, что несравнимо меньше времени ожидания старта VirtualBox виртуалки, а сборка кода с помощью ninja эффективно параллелиться по всем процессорам демонстрируя великолепную производительность.

Комментариев нет: