09 июля 2016

Как я с systemd-nspawn знакомился.



Systemd-nspawn - это такой механизм для запуска системы в изолированном пространстве (namespace). C помощью этого механизма можно запустить на одном ядре linux фактически несколько разных дистрибутивов. Очень похоже на chroot, но более ограничено во взаимодействии с системой.
У меня на домашнем сервере стоит Debian 8. Но истинному админу локалхоста всё время хочется что-то подкрутить и прикрутить. Вот тут такая система контейнеров и пригодится.

В результате очередного эксперимента всё упёрлось в версии пакетов в репозитории Debian Jessie. Я начал руками пересобирать пакеты из ветки sid, но в итоге цепочка зивисимостей вывела мена к версии gcc. Я плюнул на это дело, удалил весь мусор, который набрался при скачивании и сборке разных пакетов и поставил в систему "debootstrap", чтобы сделать в отдельно взятом каталоге свой Debian с пакетами и репозиториями.

По опыту общения с WD My Book Live я адаптировал скрипт запуска chroot-окружения. Всё запускалось и вроде как даже работало, но всё равно решение казалось очень костыльным. Тогда я попробовал натравить на развёрнутую систему "systemd-nspawn" такой командой:

sudo systemd-nspawn -D debian-testing -M debian-testing

Сразу же очутился в новой системе. В списке процессов практически пусто, но система работает и даже по сети с миром может общаться. Все необходимые виртальные файловые системы смонтированны, ничего руками и скриптами делать не надо. Но система пока не настоящая, потому что нужные сервисы всё равно надо запускать руками, пользователей фактический нет, если root не считать, да и выход из такого окружения тормозит систему в контейнере.

Вот тут сразу перепрыгну все свои пробы и ошибки и опишу процесс полноценного запуска окружения. Команды приводить не буду, просто опишу шаги.

Сначала я сменил пароль для root, чтобы можно было хоть как-то входить в систему. Потом поставил ssh-сервер "openssh-server", чтобы без лишних телодвижений попадать в нужную систему, и сразу перевёл его на другой порт, чтобы не конфликтовал с уже установленным в основной системе.

Теперь можно попробовать запустить контейнер с ключом "-b", чтобы система в нём действительно загрузилась.

Появится короткий лог загрузки и приглашение для ввода логина. После логина под root можно посмотреть список процессов и убедиться, что ssh-сервер работает и даже принимает соединения. Нажатие "Ctrl+]]]" всё равно убивает контейнер со всем содержимым.

Для запуска контейнера при загрузке системы достаточно сделать символическую ссылку на корневой каталог контейнера в "/var/lib/container/" и активировать сервис "systemd-nspawn@conteiner", где "container" - это имя символической ссылки.

Теперь контейнером можно управлять как обычным systemd-сервисом.

UPDATE: Символической ссылки теперь не достаточно. Systemd 232 при такой схеме портит права внутри каталога контейнера, фактически ломая его.