Работа с systemd-nspawn в Linux

Обновлено и опубликовано Опубликовано:

Используемые термины: Docker, Podman, LXD, Linux.

В двух словах, systemd-nspawn — платформа контейнеризации на основе systemd. Ее очевидный плюс заключается в нативности (для любой системы на основе systemd требуется минимум установок и настроек). Из минусов отмечу более сложный процесс настройки и запуска контейнеров. Обо всем по порядку.

Установка

Для работы с systemd-nspawn нам нужно выполнить установку пакета systemd-container. В разных системах это делается, немного, по-разному.

а) На Linux Deb (Debian / Ubuntu / Astra Linux):

apt update

apt install systemd-container

б) На Linux RPM (Rocky Linux):

yum install systemd-container

Установка выполнена.

Подготовка образа

В отличие от других популярных аналогов (Docker, Podman, LXD) systemd-nspawn не имеет своего репозитория с образами, из которых мы можем легко получить контейнер. Поэтому нам необходимо создать свои собственные шаблоны.

Для systemd-nspawn образ — это система, установленная в каталог с помощью Debootstrap/Yumbootstrap. Рассмотрим процесс немного подробнее.

Инструменты Debootstrap и Yumbootstrap очень капризные. При работе с ними можно столкнуться с большим количеством разных ошибок. По возможности, я укажу решение некоторых из них.

Для минимизации проблем, мы можем выполнить установку системы в каталог на соответствующей платформе, например, если нам нужна Astra Linux, то запускаем debootstrap на Astra Linux. После готовый каталог копируем на машину, где хотим использовать systemd-nspawn.

Debootstrap (образы с deb-linux)

Для установки в каталог системы на основе Debian нам нужно использовать инструмент debootstrap. Его можно установить из базовых репозиториев. В зависимости от системы, на которой мы будем работать, наши действия будут отличаться.

а) Если работаем на Linux Deb (Debian / Ubuntu / Astra Linux):

apt install debootstrap

б) Если работаем на Linux RPM (Rocky Linux):

yum install epel-release

yum install debootstrap

После установки debootstrap можно приступать к установки системы.

Посмотрим содержимое каталога /usr/share/debootstrap/scripts:

ls /usr/share/debootstrap/scripts

В нем находится набор готовых скриптов для различных дистрибутивов Linux на основе Deb. Мы должны найти соответствующее название для системы, которую хотим установить в каталог.

Предположим, нам нужно работать с Ubuntu 22.04. Ее кодовое название Jammy. Проверяем, что такой скрипт есть:

ls /usr/share/debootstrap/scripts | grep jammy

Теперь выполним установку системы в каталог:

debootstrap jammy /var/lib/machines/image-ubuntu-jammy

* в нашем примере будет использоваться скрипт jammy для установки Ubuntu в каталог /var/lib/machines/image-ubuntu-jammy.

Мы можем получить ошибку Keyring file not available at /usr/share/keyrings/ubuntu-archive-keyring.gpg. Для решения проблемы нам нужно получить gpg-ключ и сохранить его в соответствующем каталоге. Выполняем команды:

mkdir -p /usr/share/keyrings

gpg --keyid-format long --keyserver hkp://keyserver.ubuntu.com --recv-keys 0x871920D1991BC93C

gpg --export 871920D1991BC93C > /usr/share/keyrings/ubuntu-archive-keyring.gpg

В итоге, мы должны увидеть:

...
I: Base system installed successfully.

Система установлена. При необходимости ее отредактировать, вводим:

chroot /var/lib/machines/image-ubuntu-jammy

Выполняем необходимые команды (например по инструкции С чего начать настройку любого UNIX сервера) и выходим из chroot:

exit

Готово — мы получили deb-образ, который может использоваться в качестве шаблона для контейнеров systemd-nspawn.

Yumbootstrap (образы с rpm-linux)

Утилита yumbootstrap позволит установить в каталог системы на базе RPM. Ее нет в репозиториях, но она идет в поставке с файлами для сборки установочных пакетов deb и rpm.

Перейдем в каталог для хранения исходников:

cd /usr/src

Скачаем yumbootstrap:

git clone https://github.com/dozzie/yumbootstrap.git

Если получим ошибку bash: git: command not found, выполним установку git:

apt install git

yum install git

* первая команда для систем deb, вторая — rpm.

Переходим в загруженный каталог yumbootstrap:

cd yumbootstrap

Далее команды для сборки и установки под разные типы дистрибутивов Linux будут отличаться.

а) Если работаем на Deb (Debian / Ubuntu / Astra Linux):

apt install devscripts debhelper python python-setuptools

dpkg-buildpackage -b -uc

dpkg -i ../yumbootstrap*.deb

б) Если работаем на RPM (Rocky Linux):

В процессе сборки мы можем столкнуться с рядом проблем. Рассмотрим все нюансы.

yum install rpm-build make python2 python2-setuptools

* обратите внимание, что мы устанавливаем именно  python версии 2. Для 3-й версии выскакивает ошибка синтаксиса при попытке собрать пакет.

make srpm

Если мы получим ошибку error: attempt to use unversioned python, define %__python to /usr/bin/python2 or /usr/bin/python3 explicitly, открываем файл:

vi redhat/yumbootstrap.spec

Самой первой строкой добавляем:

%define __python /usr/bin/python2
...

rpmbuild --rebuild yumbootstrap-*.src.rpm

Мы можем получить ошибку python-setuptools is needed by yumbootstrap. В некоторых дистрибутивах на основе RPM нет пакета python-setuptools — либо python2-setuptools, либо python3-setuptools. Но так как сборщик требует, именно, python-setuptools, внесем правки в spec-файл:

vi redhat/yumbootstrap.spec

Редактируем значение для директивы BuildRequires:

BuildRequires: python2-setuptools

* в нашем примере теперь будет требоваться уже установленный нами пакет python2-setuptools.

После снова собираем исходники:

make srpm

Также на данном этапе мы можем столкнуться с ошибкой ERROR: ambiguous python shebang in ...: #!/usr/bin/python. Change it to python3 (or python2) explicitly. Открываем файл:

vi /usr/lib/rpm/redhat/brp-mangle-shebangs

Находим строки:

# Replace ambiguous python with python2
  py_shebang=$(echo "$shebang" | sed -r -e 's@/usr/bin/python(\s|$)@/usr/bin/python2\1@')

И после них добавляем блок:

  if [ "$py_shebang" == "/usr/bin/python2" ]; then
    shebang="/usr/bin/python2"
  fi

* насколько я смог разобраться, в некоторых системах неправильно определяется оригинальный путь до  python2. В моем примере идет подмена неправильного /usr/bin/python на правильный /usr/bin/python2. Решение не самое изящное, но работает.

Наконец, можно устанавливать собранный пакет:

yum localinstall ~/rpmbuild/RPMS/noarch/yumbootstrap-*.rpm

После установки yumbootstrap можно установить систему в каталог.

Смотрим список дистрибутивов, для которых есть шаблоны yumbootstrap:

ls /etc/yumbootstrap/suites/

Предположим, будем работать с centos-7. Вводим команду:

yumbootstrap centos-7 /var/lib/machines/centos-7

* в нашем примере будет использоваться шаблон centos-7 для установки Ubuntu в каталог /var/lib/machines/centos-7.

Система установлена. При необходимости ее отредактировать, вводим:

chroot /var/lib/machines/centos-7

Выполняем необходимые команды (например по инструкции С чего начать настройку любого UNIX сервера) и выходим из chroot:

exit

Готово — мы получили rpm-образ, который может использоваться в качестве шаблона для контейнеров systemd-nspawn.

Создание контейнеров

Рассмотрим работу с контейнерами поэтапно:

  1. Сначала мы скопируем ранее созданный шаблон в папку контейнера.
  2. После запустим контейнер без init. В данном режиме мы сможем задать пароль учетной записи root.
  3. Полноценный запуск в интерактивном режиме. С целью убедиться, что контейнер работает.
  4. Настроим автозапуск контейнера.

Приступим.

Создание контейнера из образа

На самом деле, создать новый контейнер из образа, это скопировать ранее созданный шаблон в каталог /var/lib/machines.

Каталог не обязательно должен быть /var/lib/machines, но для systemd-nspawn предусмотрены шаблоны команд, которые удобнее использовать, если контейнеры находятся, именно, в этой папке.

Скопируем /var/lib/machines/image-ubuntu-jammy и создадим контейнер ubuntu-jammy:

cp -R /var/lib/machines/image-ubuntu-jammy /var/lib/machines/ubuntu-jammy

Идем дальше.

Запуск без init

Вводим команду типа:

systemd-nspawn -D <путь до папки контейнера>

Например:

systemd-nspawn -D /var/lib/machines/ubuntu-jammy

* в данном примере мы возьмем скопированную папку ubuntu-jammy и запустим из нее контейнер.

Введем команду:

passwd

И зададим новый пароль для пользователя root.

Выходим из контейнера, зажав Ctrl и нажав ]]] (три раза ]).

Запуск с init

Выполняем команду запуска контейнера с добавлением опции -b:

systemd-nspawn -D /var/lib/machines/ubuntu-jammy -b

Если мы увидим ошибку:

Failed to create /init.scope control group: Operation not permitted
Failed to allocate manager object: Operation not permitted

[!!!!!!] Failed to allocate manager object.
Exiting PID 1...

Вводим команду:

grubby --update-kernel=ALL --args="systemd.unified_cgroup_hierarchy=1"

* она задает унифицированный режим работы cgroup (cgroups-v2).

После перезапускаем компьютер.

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

Мы должны попасть в командную строку.

Выходим из контейнера, зажав Ctrl и нажав ]]] (три раза ]).

Автозапуск контейнера

Для автостарта контейнеров предусмотрена команда machinectl.

Сначала разрешаем запуск для стандартного целевого юнита запуска контейнеров:

systemctl enable machines.target

Теперь можно разрешать автостарт контейнеров. Синтаксис следующий:

machinectl enable <имя контейнера в каталоге /var/lib/machines>

Для нашего примера команда будет такой:

machinectl enable ubuntu-jammy

И запускаем:

machinectl start ubuntu-jammy

Посмотреть список запущенных контейнеров можно командой:

machinectl list

Некоторые полезные команды

Ниже перечислим список команд для управления контейнерами.

Показать список контейнеров:

machinectl list

Статус работы контейнера:

machinectl status <имя контейнера>

Подключиться к контейнеру:

machinectl login <имя контейнера>

Запустить shell-оболочку контейнера (без пользовательского входа):

machinectl shell <имя контейнера>

Включить контейнер:

machinectl start <имя контейнера>

Перезагрузить контейнер:

machinectl reboot <имя контейнера>

Выключение контейнера:

machinectl poweroff <имя контейнера>

# DevOps # Linux # Виртуализация
Дмитрий Моск — частный мастер
Была ли полезна вам эта инструкция?

Да            Нет