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

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

Непривилегированный режим LXC в ALT Linux


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

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

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

01.01 Подготовка ОС Linux

На уровне ядра ОС разрешить непривилегированным пользователям создавать пространства имен:

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

02.02 Конфигурация по умолчанию

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|g} 0” полученные в п.02.01

#/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
# Mount /proc as rw but /proc/sys and /proc/sysrq-trigger as ro:
lxc.mount.auto = proc:mixed
# mount /sys read only but /sys/devices/virtual/net as rw:
lxc.mount.auto = sys:mixed
# Mount tmpfs in /sys/fs/cgroups:
lxc.mount.auto = cgroup:mixed
# Allow for 1024 pseudo terminals:
lxc.pty.max = 1024

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

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.03 Создать контейнер

TMPDIR=/tmp lxc-create -t local -n container01 -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

export XDG_RUNTIME_DIR="/run/user/$UID"
export DBUS_SESSION_BUS_ADDRESS="unix:path=${XDG_RUNTIME_DIR}/bus"
systemd-run --unit=my-unit --user --scope -p "Delegate=yes" -- lxc-start container

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

Для автоматического запуска непривилегированных контейнеров требуеся настроить unit-ы systemd в окружении пользователя

lxc@.service

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

mkdir -p ~/.config/systemd/user/
cp /usr/lib/systemd/system/lxc@.service ~/.config/systemd/user/

Подготовить файл юнита:

nano ~/.config/systemd/user/lxc\@.service
[Unit]
Description=LXC Container: %i
# This pulls in apparmor, dev-setup, lxc-net
After=lxc-net.service
Wants=lxc-net.service
Documentation=man:lxc-start man:lxc

[Service]
Type=simple
KillMode=mixed
TimeoutStopSec=120s
ExecStart=/usr/bin/lxc-start -F -n %i
ExecStop=/usr/bin/lxc-stop -n %i
# Environment=BOOTUP=serial
# Environment=CONSOLETYPE=serial
StateDirectory=lxc
Delegate=yes

[Install]
WantedBy=default.target

Добавить переменные в окружение

nano ~/.bashrc
# ~/.bashrc
# The individual per-interactive-shell startup file.

# Source global definitions.
if [ -r /etc/bashrc ]; then
        . /etc/bashrc
fi

# Define user specific aliases and functions.
export XDG_RUNTIME_DIR="/run/user/$UID"
export DBUS_SESSION_BUS_ADDRESS="unix:path=${XDG_RUNTIME_DIR}/bus"

еще немного колдовства от имени пользователя:

systemctl --user daemon-reload
systemctl --user enable lxc@container.service

user@.service.d

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

sudo loginctl enable-linger lxc-user