С вами снова #linux_возможности.
Сегодня речь пойдёт о systemd-nspawn.
systemd-nspawn это часть systemd отвечающая за контейнеризацию. Сабж напоминает более простой в использовании (но при этом урезанный в возможностях) LXC, который тоже является системой контейнеризации.
В наше время когда говорят о контейнерах, то на ум в первую очередь приходит Docker. Перечисленные выше системы сильно от него отличаются, так как направлены скорее на запуск в контейнере целых дистрибутивов, а не конкретных процессов. В отличии от LXC, systemd-nspawn способен запускать лишь дистрибутивы которые работают под systemd. Лично я использую именно systemd-nspawn, т.к. для моих целей его вполне хватает, а целей у меня две: тестирование дистрибутивов и создание сборок.
В отличии от виртуализации, контейнеры не тратят ресурсы на эмуляцию, не теряют производительности и работают с теме же ресурсами с которыми работает и хостовая система (с определёнными ограничениями конечно же). По этим причинам, тестировать что-либо в контейнере куда удобнее чем на виртуалке или лайв образе. Данные во многих исошках можно легко распаковать и сделать контейнер прямо из них.
Контейнеры systemd-nspawn представляют из себя просто рут директорию дистрибутива. Утилиты deboostrap и pacstrap позволяют создать минимальные рут директории для Debian и Arch Linux соответственно. И это даёт большие возможности для лёгкого создания собственных сборок.
После создания контейнера с помощью нужной из перечисленных утилиты, мы можем его запустить, поставить нужный нам софт, подправить конфиги и в целом манипулировать контейнером как нам угодно. Так же можно редактировать его и извне, учитывая что все файлы просто лежат в папке. Можно даже запускать графические приложения из контейнера. Для этого всего лишь необходимо выполнить команду "xhost +local:" из под того графического сервера на хосте, под которым необходимо запустить приложение из контейнера а так же, при запуске из приложения, перед командой добавить "DISPLAY=:X". Вместо X должен быть номер графического сервера, под которым должно быть запущено приложение. Его можно узнать выполнив "echo $DISPLAY" находясь в нужном графическом сервере. Так же, можно из под контейнера выполнить "export DISPLAY=:X" и тогда все приложения запускаемые из контейнера будут запущены под указанным графическим сервером.
Раз можно запускать приложения, то собственно можно запустить и целое окружение рабочего стола. Для этого нужно всего лишь на свободном tty запустить пустой X сервер и сделать всё так, как описано выше, но запустить вместо приложения само DE. Тогда мы получаем хостовую машину на одном графическом сервере, а контейнер на другой и можем легко между ними переключаться.
В позапрошлой статье я писал о Xorg multiseat, который позволяет нескольким людям пользоваться одной машиной. Если вдруг вы с кем-то хотели это попробовать, но поругались на тему того какой дистрибутив будете использовать, то вот вам выход. Для одного из пользователей можно запустить контейнер с его любимым дистром.
Так же, естественно, нет смысла делать сборку в контейнере, если её потом нельзя раскатить на физическую машину. Школьники наверное уже догадались как это сделать, т.к. при установке Arch Linux приходится делать нечто подобное. Всё очень просто. Нужно загрузиться из под Live образа (желательно того дистрибутива, сборку которого будем раскатывать, т.к. chroot может ругаться на несоответствие), после чего разбить вручную (или скриптом) диск, примонтировать рут раздел в /mnt и все остальные разделы (если таковые есть) в соответствующие папки в /mnt. А дальше, нам надо залить в /mnt наш контейнер, что очень быстро можно сделать с помощью комбо из утилит ncat и tar, о которых я писал в предыдущей статье. После этого достаточно просто прибиндить несколько директорий в нашем новом руте (под арчем вроде бы это даже не нужно делать):
mount —bind /dev /mnt/dev
mount —bind /sys /mnt/sys
mount —bind /proc /mnt/proc