Непривилегированные LXC-контейнеры

Непривилегированные контейнеры на ALT Server 11.1 (Mendelevium)

01 Непривилегированный режим

Хорошее описание тут: https://wiki.gentoo.org/wiki/LXC#Sub_UID_and_GID_mapping

Непривилегированный режим работы контейнеров базируется на cgroup. На уровне ядра ОС разрешить непривилегированным пользователям создавать пространства имен

echo 'kernel.unprivileged_userns_clone=1' >> /etc/sysctl.conf
sysctl -p

Предоставить непривилегированным пользователям права доступа к утилитам:

chmod u+s /usr/bin/newuidmap
chmod u+s /usr/bin/newgidmap
chmod 04755 /usr/bin/newuidmap
chmod 04755 /usr/bin/newgidmap
chmod u+s /usr/lib/lxc/lxc-user-nic
chmod 04755 /usr/lib/lxc/lxc-user-nic

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

touch /etc/lxc/lxc-usernet
nano /etc/lxc/lxc-usernet

Добавить в файл строки:

# USERNAME      TYPE    BRIDGE  COUNT
lxc-user     veth    lxcbr0  10

02 Окружение пользователя

02.01 SUBGID и SUBUID

Все контейнеры запускаемые от имени непривилегированного пользователя система назначает PID из диапазона UID и GID принадлежащих пользователю. Диапазон пользователя можно посмотреть командой:

echo $(grep $(whoami) /etc/subgid) | awk -F: '{print $2, $3}'
427680 65536

Подготовить конфигурацию по умолчанию

mkdir /home/lxc-user/.config/lxc/
cp /etc/lxc/default.conf /home/lxc-user/.config/lxc/default.conf
nano /home/lxc-user/.config/lxc/default.conf

Обязательно указываем «427680 65536» для параметра «lxc.idmap = u 0»

#/home/lxc-user/.config/lxc/default.conf
# Interface
lxc.net.0.type = veth
lxc.net.0.link = lxcbr0
lxc.net.0.flags = up
lxc.net.0.hwaddr = 10:66:6a:xx:xx:xx
# CSGroup
lxc.idmap = u 0 427680 65536
lxc.idmap = g 0 427680 65536
lxc.mount.auto = proc:mixed
lxc.mount.auto = sys:ro
lxc.mount.auto = cgroup:rw:force

Подготовить метадату

mkdir /home/lxc-user/.local/share/lxc/
cd /home/lxc-user/.local/share/lxc/
chmod -R +x /home/lxc-user
touch config
tar -cJf metadata.tar.xz config

02.02 Создать контейнер

TMPDIR=/tmp lxc-create -t local -n bkr01 -B dir -- --metadata metadata.tar.xz --fstree /tmp/alt-p11-rootfs-systemd-etcnet-x86_64.tar.xz --no-dev

Почему запускать lxc-create с префиксом TEMPDIR=/tmp: https://lists.linuxcontainers.org/pipermail/lxc-users/2015-July/009761.html


03 systemd

03.01 Ручной способ запуска/остановки

Непривилегированный контейнер на базе systemd требует наличие иерархии каталогов cgroupv1 в каталоге /sys/fs/cgroup/systemd, который по умолчанию отсутствует и требует ручного выполнения команд:

mkdir /sys/fs/cgroup/systemd 
mount -t cgroup -o none,name=systemd cgroup /sys/fs/cgroup/systemd
chmod -R o+rwx /sys/fs/cgroup/systemd/

В случает отсутствия каталога /sys/fs/cgroup/systemd при старте контейнера будет ошибка:

Failed to mount cgroup (type cgroup) on /sys/fs/cgroup/systemd (MS_NOSUID|MS_NODEV|MS_NOEXEC "none,name=systemd"): Operation not permitted

Проблема в том, что после перезагрузки каталог «/sys/fs/cgroup/systemd» исчезнет и LXC контейнер в непривилегированном режиме не стартанет. Можно использовать контейнеры на базе sysvinit, но они очень тормозят при старте, остановке. Второй вариант настроить slice для lxc@{name_lxc}.service

Вся вышеприведенная последовательность команд будет работать только от имени пользователя выполнившего доступ по ssh и для которого были создано окружение в /run/users/{id}. Проблема в том, что если вход не выполнен или пользователь разлогинился, то окружение /run/users/{id} пропадает и контейнера не работают. Решение (постоянное):

loginctl enable-linger lxc-user

Было:

ls /run/user/
0  1000

Стало:

ls /run/user/
0  1000  1005

https://unix.stackexchange.com/questions/798670/debian-trixie-problems-with-lxc-unprivileged-containers

03.02 Автоматический запуск контейнеров systemd

Когда я понял, что к чему со всеми этими cgroup и systemd, оказалось, что достаточно создать для каждого контейнера свой демон и весь геморрой с ручным запуском отпадает. Однако…

Надо подредактировать файл демона: /usr/lib/systemd/system/lxc@.service

[Unit]
Description=LXC Container: %i
# This pulls in apparmor, dev-setup, lxc-net
After=lxc.service
Wants=lxc.service
Documentation=man:lxc-start man:lxc

[Service]
Type=simple
KillMode=mixed
TimeoutStopSec=120s
ExecStart=/usr/bin/lxc-start -F -n %i -f /home/lxc-user/.local/share/lxc/%i/config
ExecStop=/usr/bin/lxc-stop -n %i
# Environment=BOOTUP=serial
# Environment=CONSOLETYPE=serial
StateDirectory=lxc
Delegate=yes
User=lxc-user
Group=lxc-user

[Install]
WantedBy=multi-user.target

еще немного колдовства:

systemctl daemon-reload
systemctl enable lxc@bkr01.service


Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *