Контейнеры systemd-nspawn: различия между версиями

Материал из ALT Linux Wiki
м (→‎Проблемы с ID mapped mounts: Оговорка по Фрейду)
 
(не показано 109 промежуточных версий 5 участников)
Строка 1: Строка 1:
{{Внимание|Статья не окончена! Пока не удалось добиться входа в контейнеры штатным способом — только ручным запуском длинной команды с кучей опций.}}
=Подготовка=
Первым делом не обойтись без установки пакета означенной в заголовке системы виртуализации:
# apt-get update && apt-get install systemd-container -y
Вторым — понадобится минимальный образ системы, годный для виртуальных сред контейнерного типа (LXC, Docker и т.п.), взять который можно в репозитории. На момент написания статьи привлекательнее прочих выглядел [http://ftp.altlinux.ru/pub/distributions/ALTLinux/p9/images/cloud/alt-p9-rootfs-systemd-x86_64.tar.xz этот].
=Установка=
=Установка=
Развернём предварительно скачанный тарбол в контейнер (допустим, первый из них будет называться <strong>spawn-1</strong>):
Первым делом не обойтись без поддержки означенной в заголовке системы контейнеризации:
# machinectl import-tar alt-p9-rootfs-systemd-x86_64.tar.xz spawn-1
<source lang="bash"># apt-get update && apt-get install systemd-container -y</source>
Вторым &mdash; понадобится минимальный образ системы, годный для виртуальных сред контейнерного типа ([[LXC]], [[Docker]] и т.п.), взять который можно в репозитории. На момент последней редакции статьи привлекательнее прочих выглядел [http://ftp.altlinux.ru/pub/distributions/ALTLinux/p10/images/cloud/alt-p10-rootfs-systemd-x86_64.tar.xz этот].
 
Контейнер (допустим, первый из них будет называться <strong>spawn-1</strong>) можно развернуть:
{|class="mw-collapsible mw-collapsed wikitable"
!прямо из интернета &nbsp;
|-
|<source lang="bash">
# machinectl pull-tar http://ftp.altlinux.ru/pub/distributions/ALTLinux/p10/images/cloud/alt-p10-rootfs-systemd-x86_64.tar.xz spawn-1 --verify=no
   
   
  Enqueued transfer job 1. Press C-c to continue download in background.
Enqueued transfer job 1. Press C-c to continue download in background.
Importing '/var/lib/machines/alt-p9-rootfs-systemd-x86_64.tar.xz', saving as 'spawn-1'.
Pulling 'http://ftp.altlinux.ru/pub/distributions/ALTLinux/p10/images/cloud/alt-p10-rootfs-systemd-x86_64.tar.xz', saving as 'spawn-1'.
Imported 0%.
Downloading 169B for http://ftp.altlinux.ru/pub/distributions/ALTLinux/p10/images/cloud/alt-p10-rootfs-systemd-x86_64.nspawn.
...
HTTP request to http://ftp.altlinux.ru/pub/distributions/ALTLinux/p10/images/cloud/alt-p10-rootfs-systemd-x86_64.nspawn failed with code 404.
Imported 99%.
Settings file could not be retrieved, proceeding without.
Operation completed successfully.
Downloading 60.9M for http://ftp.altlinux.ru/pub/distributions/ALTLinux/p10/images/cloud/alt-p9-rootfs-systemd-x86_64.tar.xz.
Exiting.
Got 1% of http://ftp.altlinux.ru/pub/distributions/ALTLinux/p10/images/cloud/alt-p10-rootfs-systemd-x86_64.tar.xz.
...
Got 88% of http://ftp.altlinux.ru/pub/distributions/ALTLinux/p10/images/cloud/alt-p10-rootfs-systemd-x86_64.tar.xz. 604ms left at 8.4M/s.
Download of http://ftp.altlinux.ru/pub/distributions/ALTLinux/p10/images/cloud/alt-p10-rootfs-systemd-x86_64.tar.xz complete.
Created new local image 'spawn-1'.
Operation completed successfully.
Exiting.
</source>
|}
либо
{|class="mw-collapsible mw-collapsed wikitable"
!из скачанного тарбола. &nbsp;
|-
|<source lang="bash">
# machinectl import-tar alt-p10-rootfs-systemd-x86_64.tar.xz spawn-1
   
Enqueued transfer job 1. Press C-c to continue download in background.
Importing '/var/lib/machines/alt-p9-rootfs-systemd-x86_64.tar.xz', saving as 'spawn-1'.
Imported 0%.
...
Imported 99%.
Operation completed successfully.
Exiting.
</source>
|}


=Настройка=
=Запуск=
Как контейнеры запускаются, можно подглядеть в пункте <code>ExecStart</code> сервисного шаблона <strong>/lib/systemd/system/systemd-nspawn@.service</strong>, а именно:
{{Совет|Если требуется задать контейнеру какие-то дополнительные параметры, имеет смысл создать файлик <code>/etc/systemd/nspawn/<name>.nspawn</code> и добавлять их туда ''(подробнее см. в {{cmd|man systemd.nspawn}})''.}}
# systemd-nspawn --quiet --keep-unit --boot --link-journal=try-guest --network-veth -U --settings=override --machine=%i
Например, для контейнера под сборочницу [[Hasher]]:
С сокращёнными опциями, не загораживая горизонты, та же команда выглядит так:
{|class="mw-collapsible mw-collapsed wikitable"
# systemd-nspawn -q --keep-unit -b -j -n -U --settings=override -M spawn-1
!/etc/systemd/nspawn/spawn-1.nspawn &nbsp;
Дабы впоследствии не мучиться со входом в контейнер с отлупом по паролю, следует задать таковой пользователю <strong>root</strong>, для чего первый вход произвести в незапущенный контейнер без лишних на данном этапе опций:
|-
# systemd-nspawn -M spawn-1
|<source lang=ini>
Получив приглашение <code>[root@spawn-1 ~]# </code>, задать пароль и выйти:
[Exec]
[root@spawn-1 ~]# passwd
Capability = CAP_SYS_ADMIN
passwd: updating all authentication tokens for user root.
...
Enter new password:
Re-type new password:
passwd: all authentication tokens updated successfully.
[root@spawn-1 ~]# exit
logout


=Запуск=
[Network]
VirtualEthernet = on
</source>
|}
Стартанём новый контейнер, одновременно включив его запуск при каждой загрузке компьютера:
Стартанём новый контейнер, одновременно включив его запуск при каждой загрузке компьютера:
# systemctl enable --now systemd-nspawn@spawn-1
<source lang=bash>
Created symlink /etc/systemd/system/machines.target.wants/systemd-nspawn@spawn-1.service → /lib/systemd/system/systemd-nspawn@.service.
# systemctl enable --now systemd-nspawn@spawn-1
Created symlink /etc/systemd/system/machines.target.wants/systemd-nspawn@spawn-1.service → /lib/systemd/system/systemd-nspawn@.service.
</source>
Проверим, всё ли удалось:
Проверим, всё ли удалось:
[root@comp ~]# systemctl status systemd-nspawn@spawn-1
<source lang=bash>
● systemd-nspawn@spawn-1.service - Container spawn-1
# systemctl status systemd-nspawn@spawn-1
● systemd-nspawn@spawn-1.service - Container spawn-1
   Loaded: loaded (/lib/systemd/system/systemd-nspawn@.service; enabled; vendor preset: disabled)
   Loaded: loaded (/lib/systemd/system/systemd-nspawn@.service; enabled; vendor preset: disabled)
   Active: active (running) since Thu 2020-10-01 21:38:31 +08; 8s ago
   Active: active (running) since Thu 2020-10-01 21:38:31 +08; 8s ago
     Docs: man:systemd-nspawn(1)
     Docs: man:systemd-nspawn(1)
...
...
Работает. Заходим уже штатным образом:
</source>
# machinectl login spawn-1
Работает. Заходим локально:
<source lang=bash>
# machinectl shell spawn-1
Connected to machine spawn-1. Press ^] three times within 1s to exit session.
[root@spawn-1 ~]#
</source>
{{Памятка|Чтоб заходить в контейнер локально не только по {{cmd|machinectl shell <name>}}, но и по {{cmd|machinectl login <name>}}, нужно скомандовать внутри контейнера: {{cmd|# sed -i 's:tty:pts/:' /etc/securetty}}}}
 
=Сеть=
{{Примечание|Не пробовал делать дальнейшее посредством <code>etcnet</code>, поскольку давно использую <code>systemd-networkd</code>, одинаково настраиваемый во всех современных дистрибутивах и интегрирующий массу инструментария, каковой в других случаях требуется установить.}}
Построим с хоста мостик <strong>ve-<имя контейнера></strong> (адрес и сеть выбирать на своё усмотрение, лишь бы не пересекалось с уже имеющимися в системе):
{|class="mw-collapsible mw-collapsed wikitable"
!/etc/systemd/network/ve-spawn-1.network &nbsp;
|-
|<source lang=ini>
[Match]
Name = ve-spawn-1
 
[Network]
DHCPServer = yes
Address = 192.168.222.254/24
IPMasquerade = yes
</source>
|}
А со стороны контейнера примем его на интерфейс <strong>host0</strong>:
{|class="mw-collapsible mw-collapsed wikitable"
!/etc/systemd/network/host0.network &nbsp;
|-
|<source lang=ini>
[Match]
Name = host0


=Первый облом=
[Network]
Если входить в контейнер при остановленном юните из командной строки, получаем:
DHCP = ipv4
# systemd-nspawn -q -b -j -n -U --settings=override -M spawn-1
</source>
systemd v243.8-alt2 running in system mode. (+PAM +AUDIT +SELINUX +IMA -APPARMOR +SMACK +SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT +GNUTLS +ACL +XZ +LZ4 +SECCOMP +BLKID +ELFUTILS +KMOD +IDN2 -IDN +PCRE2 default-hierarchy=hybrid)
|}
Detected virtualization systemd-nspawn.
{{Примечание|Вышеописанное необязательно, поскольку '''systemd-networkd''' умолчально настраивает ve-интерфейсы посредством DHCP ''(см. файлы {{path|/lib/systemd/network/80-container-host0.network}} и {{path|/lib/systemd/network/80-container-ve.network}})''.}}
Detected architecture x86-64.
Перезапустив systemd-networkd прежде на хосте, а после в контейнере, увидим:
{|class="mw-collapsible mw-collapsed wikitable"
Welcome to ALT Starterkit (Hypericum)!
!На хосте &nbsp;
...
|-
spawn-1 login: root
|<source lang=bash>
  Password:
# networkctl
Last login: Thu Aug 27 11:55:00 +08 2020 on pts/0
IDX LINK      TYPE    OPERATIONAL SETUP   
[root@spawn-1 ~]#
  1 lo        loopback carrier    unmanaged
Однако пробовать штатным образом залезть в запущенный юнит бесполезно:
  2 lan        ether    routable    configured
# machinectl login spawn-1
  3 ve-spawn-1 ether    routable    configured
  Connected to machine spawn-1. Press ^] three times within 1s to exit session.
 
3 links listed.
spawn-1 login: root
 
Password:
# ip -o a s ve-spawn-1 | awk '!/inet6/{print $2,$4}'
Login incorrect
ve-spawn-1 192.168.222.254/24
</source>
login:
|}
При этом видно, что строка запуска та же самая, с добавкой опции <code>--keep-unit</code>:
{|class="mw-collapsible mw-collapsed wikitable"
# systemctl status systemd-nspawn@spawn-1 | grep /usr/bin/systemd-nspawn
!В контейнере &nbsp;
            └─238367 /usr/bin/systemd-nspawn -q --keep-unit -b -j -U --settings=override -M spawn-1
|-
=Варианты=
|<source lang=bash>
А всё потому, что, как явствует из мана systemd-nspawn, некоторые операции в образах контейнеров осмысленны, эффективны, да и вообще поддерживаются лишь на файловой системе btrfs.
[root@spawn-1 ~]# networkctl
IDX LINK TYPE    OPERATIONAL SETUP   
  1 lo    loopback carrier    unmanaged
  2 host0 ether    routable    configured
 
2 links listed.
 
[root@spawn-1 ~]# ip -o a s host0 | awk '!/inet6/{print $2,$4}'
  host0 192.168.222.146/24
</source>
|}
{{Совет|Если всё заработало, дальше имеет смысл конфигурировать контейнер по ssh, устанавливая нужные пакеты и настраивая требуемые сервисы.}}
 
=Стрельба по неприятностям (траблшутинг)=
* Из решений: настроить политики Polkit &mdash; [https://wiki.archlinux.org/index.php/Systemd-nspawn#Using_machinectl_without_root_permissions|Using machinectl without root permissions]
 
== Проблемы с ID mapped mounts ==
 
На альтовских ядрах можно наткнуться на ошибку при старте контейнеров. При этом в логах контейнера будет что-то типа:
 
systemd-nspawn[3651]: Failed to set up ID mapped mounts: Operation not permitted
 
А в dmesg:
 
VFS: idmapped mount is not enabled.
 
Это симптомы заботы мейнтейнеров ядра о вашей безопасности, за подробностями [[idmap_mounts|вам сюда]].


С контейнером же в простом каталоге порядок действий изложен ниже.
=Обратная связь=
# Вновь создаваемый контейнер:
*[https://t.me/gbIMoBou @gbIMoBou]
  * разворачиваем,
*[[Участник:Дым#Заметки|Другие статьи]]
  * входим без запуска,
  * меняем пароль рута,
  * перезаходим с запуском,
  * настраиваем сеть,
  * доустанавливаем требуемые пакеты,
  * обеспечиваем дальнейший автозапуск нужных сервисов,
  * выходим.
# Для постоянной работы:
  * стартуем юнит для этого контейнера,
  * рулим им по ссх.
# В случае надобности реконфигурирования и прочей обслуги:
  * стопорим юнит,
  * входим с запуском,
  * обслуживаем,
  * выходим,
  * далее см. п.2.
{{Category navigation|title=Виртуализация|category=Виртуализация|sortkey={{SUBPAGENAME}}}}
{{Category navigation|title=Виртуализация|category=Виртуализация|sortkey={{SUBPAGENAME}}}}
[[category:systemd]]
[[Категория:systemd]]
[[Категория:Admin]]

Текущая версия от 23:10, 6 февраля 2024

Установка

Первым делом не обойтись без поддержки означенной в заголовке системы контейнеризации:

# apt-get update && apt-get install systemd-container -y

Вторым — понадобится минимальный образ системы, годный для виртуальных сред контейнерного типа (LXC, Docker и т.п.), взять который можно в репозитории. На момент последней редакции статьи привлекательнее прочих выглядел этот.

Контейнер (допустим, первый из них будет называться spawn-1) можно развернуть:

прямо из интернета  
# machinectl pull-tar http://ftp.altlinux.ru/pub/distributions/ALTLinux/p10/images/cloud/alt-p10-rootfs-systemd-x86_64.tar.xz spawn-1 --verify=no
 
Enqueued transfer job 1. Press C-c to continue download in background.
Pulling 'http://ftp.altlinux.ru/pub/distributions/ALTLinux/p10/images/cloud/alt-p10-rootfs-systemd-x86_64.tar.xz', saving as 'spawn-1'.
Downloading 169B for http://ftp.altlinux.ru/pub/distributions/ALTLinux/p10/images/cloud/alt-p10-rootfs-systemd-x86_64.nspawn.
HTTP request to http://ftp.altlinux.ru/pub/distributions/ALTLinux/p10/images/cloud/alt-p10-rootfs-systemd-x86_64.nspawn failed with code 404.
Settings file could not be retrieved, proceeding without.
Downloading 60.9M for http://ftp.altlinux.ru/pub/distributions/ALTLinux/p10/images/cloud/alt-p9-rootfs-systemd-x86_64.tar.xz.
Got 1% of http://ftp.altlinux.ru/pub/distributions/ALTLinux/p10/images/cloud/alt-p10-rootfs-systemd-x86_64.tar.xz.
...
Got 88% of http://ftp.altlinux.ru/pub/distributions/ALTLinux/p10/images/cloud/alt-p10-rootfs-systemd-x86_64.tar.xz. 604ms left at 8.4M/s.
Download of http://ftp.altlinux.ru/pub/distributions/ALTLinux/p10/images/cloud/alt-p10-rootfs-systemd-x86_64.tar.xz complete.
Created new local image 'spawn-1'.
Operation completed successfully.
Exiting.

либо

из скачанного тарбола.  
# machinectl import-tar alt-p10-rootfs-systemd-x86_64.tar.xz spawn-1
 
Enqueued transfer job 1. Press C-c to continue download in background.
Importing '/var/lib/machines/alt-p9-rootfs-systemd-x86_64.tar.xz', saving as 'spawn-1'.
Imported 0%.
...
Imported 99%.
Operation completed successfully.
Exiting.

Запуск

Совет: Если требуется задать контейнеру какие-то дополнительные параметры, имеет смысл создать файлик /etc/systemd/nspawn/<name>.nspawn и добавлять их туда (подробнее см. в man systemd.nspawn).

Например, для контейнера под сборочницу Hasher:

/etc/systemd/nspawn/spawn-1.nspawn  
[Exec]
Capability = CAP_SYS_ADMIN

[Network]
VirtualEthernet = on

Стартанём новый контейнер, одновременно включив его запуск при каждой загрузке компьютера:

# systemctl enable --now systemd-nspawn@spawn-1
Created symlink /etc/systemd/system/machines.target.wants/systemd-nspawn@spawn-1.service → /lib/systemd/system/systemd-nspawn@.service.

Проверим, всё ли удалось:

# systemctl status systemd-nspawn@spawn-1
● systemd-nspawn@spawn-1.service - Container spawn-1
   Loaded: loaded (/lib/systemd/system/systemd-nspawn@.service; enabled; vendor preset: disabled)
   Active: active (running) since Thu 2020-10-01 21:38:31 +08; 8s ago
     Docs: man:systemd-nspawn(1)
...

Работает. Заходим локально:

# machinectl shell spawn-1
Connected to machine spawn-1. Press ^] three times within 1s to exit session.
[root@spawn-1 ~]#
Памятка: Чтоб заходить в контейнер локально не только по machinectl shell <name>, но и по machinectl login <name>, нужно скомандовать внутри контейнера: # sed -i 's:tty:pts/:' /etc/securetty

Сеть

Примечание: Не пробовал делать дальнейшее посредством etcnet, поскольку давно использую systemd-networkd, одинаково настраиваемый во всех современных дистрибутивах и интегрирующий массу инструментария, каковой в других случаях требуется установить.

Построим с хоста мостик ve-<имя контейнера> (адрес и сеть выбирать на своё усмотрение, лишь бы не пересекалось с уже имеющимися в системе):

/etc/systemd/network/ve-spawn-1.network  
[Match]
Name = ve-spawn-1

[Network]
DHCPServer = yes
Address = 192.168.222.254/24
IPMasquerade = yes

А со стороны контейнера примем его на интерфейс host0:

/etc/systemd/network/host0.network  
[Match]
Name = host0

[Network]
DHCP = ipv4
Примечание: Вышеописанное необязательно, поскольку systemd-networkd умолчально настраивает ve-интерфейсы посредством DHCP (см. файлы /lib/systemd/network/80-container-host0.network и /lib/systemd/network/80-container-ve.network).

Перезапустив systemd-networkd прежде на хосте, а после в контейнере, увидим:

На хосте  
# networkctl 
IDX LINK       TYPE     OPERATIONAL SETUP     
  1 lo         loopback carrier     unmanaged 
  2 lan        ether    routable    configured
  3 ve-spawn-1 ether    routable    configured

3 links listed.

# ip -o a s ve-spawn-1 | awk '!/inet6/{print $2,$4}'
ve-spawn-1 192.168.222.254/24
В контейнере  
[root@spawn-1 ~]# networkctl 
IDX LINK  TYPE     OPERATIONAL SETUP     
  1 lo    loopback carrier     unmanaged 
  2 host0 ether    routable    configured

2 links listed.

[root@spawn-1 ~]# ip -o a s host0 | awk '!/inet6/{print $2,$4}'
 host0 192.168.222.146/24
Совет: Если всё заработало, дальше имеет смысл конфигурировать контейнер по ssh, устанавливая нужные пакеты и настраивая требуемые сервисы.

Стрельба по неприятностям (траблшутинг)

Проблемы с ID mapped mounts

На альтовских ядрах можно наткнуться на ошибку при старте контейнеров. При этом в логах контейнера будет что-то типа:

systemd-nspawn[3651]: Failed to set up ID mapped mounts: Operation not permitted

А в dmesg:

VFS: idmapped mount is not enabled.

Это симптомы заботы мейнтейнеров ядра о вашей безопасности, за подробностями вам сюда.

Обратная связь