Опишу свой опыт установки и настройки LXC в пространстве пользователя (не root). Поскольку работа с контейнером в пространстве root накладывает некоторые ограничения и не очень удобна (для меня).
Если я выбрал не тот путь или пошел слишком длинной дорогой, надеюсь соратники меня поправят.
Что у меня есть:
Astra Linux Common Edition (Orel) 2.12.8;
Сетевой интерфейс eth0;
Учетная запись administrator.
1) Для начала устанавливаю собственно пакет lxc:
sudo apt install lxc
2) Проверяю всё ли прошло хорошо:
sudo lxc-checkconfig
3) Заодно посмотрю какие доступны контейнеры:
sudo ls /usr/share/lxc/templates/
4) Поскольку я не исключаю возможности в дальнейшем создавать контейнеры в пространстве root, то сразу сконфигурирую настройки по умолчанию для root. Для этого приведу файл "/etc/lxc/default.conf" к такому виду:
sudo nano /etc/lxc/default.conf
Код:
lxc.network.type = veth
lxc.network.link = br0
lxc.network.flags = up
5) Создаю сетевой мост на интерфейсе eth0, в который будут подключаться контейнеры. Для этого приведу файл "/etc/network/interfaces" к такому виду:
sudo nano /etc/network/interfaces
Код:
source /etc/network/interfaces.d/*
auto lo
iface lo inet loopback
auto br0
iface br0 inet dhcp
bridge_ports eth0
bridge_stp off
bridge_fd 0
bridge_maxwait 0
6) Перезагружаю систему, чтобы сетевые настройки вступили в силу (Результат команды "sudo service networking restart" немного насторожил, поэтому всё таки лучше перезагружу).
7) Теперь создаю каталог, в котором будут лежать настройки по умолчанию контейнеров в пространстве пользователя (administrator). (Взято
отсюда)
mkdir -p ~/.config/lxc
8) Теперь сконфигурирую настройки по умолчанию для контейнеров в пространстве пользователя (administrator). (Взято
отсюда)
Настраиваю пользовательские пространства имен:
echo "lxc.id_map = u 0 100000 65536" >> ~/.config/lxc/default.conf
echo "lxc.id_map = g 0 100000 65536" >> ~/.config/lxc/default.conf
Настраиваю сеть:
echo "lxc.network.type = veth" >> ~/.config/lxc/default.conf
echo "lxc.network.link = br0" >> ~/.config/lxc/default.conf
echo "lxc.network.flags = up" >> ~/.config/lxc/default.conf
9) Затем в файле /etc/lxc/lxc-usernet нужно разрешить использовать сетевые интерфейсы текущему пользователю, чтобы получить возможность запускать контейнер без root прав. (Взято
отсюда)
echo "$USER veth br0 2" | sudo tee -a /etc/lxc/lxc-usernet
10) Для того чтобы пространства имен пользователей linux в контейнере работали, нужно присвоить своему пользователю подпространство UID и GID 100000-165536. (Взято
отсюда)
sudo usermod --add-subuids 100000-165536 $USER
sudo usermod --add-subgids 100000-165536 $USER
11) Теперь запускаю LXC:
sudo service lxc start
12) Установлю контейнер в пространстве пользователя на базе ubuntu 18.10 с архитектурой i386 и назову его "ubuntu02":
lxc-create -t download -n ubuntu02 -- --dist ubuntu --release cosmic --arch i386
13) После установки сразу задам пароль "12345678" для пользователя "ubuntu" и пользователя "root" в контейнере. Для этого отредактирую файл "~/.local/share/lxc/ubuntu02/rootfs/etc/shadow", а именно приведу строки с этими пользователями к виду:
sudo nano ~/.local/share/lxc/ubuntu02/rootfs/etc/shadow
Код:
root:$6$THtH1yko$.rDzWsGt3Cem1.6iRBs/qklDVs2tGWvZzvYekIuUJo6tWH/xdW5vyGf57CJhIfxZZ.tWMyJJ9BxQlvAnGgrn50:17999:0:99999:7:::
ubuntu:$6$THtH1yko$.rDzWsGt3Cem1.6iRBs/qklDVs2tGWvZzvYekIuUJo6tWH/xdW5vyGf57CJhIfxZZ.tWMyJJ9BxQlvAnGgrn50:17999:0:99999:7:::
14) Проверю конфигурацию контейнера, она должна иметь такой вид:
nano ~/.local/share/lxc/ubuntu02/config
Код:
# Distribution configuration
lxc.include = /usr/share/lxc/config/ubuntu.common.conf
lxc.include = /usr/share/lxc/config/ubuntu.userns.conf
lxc.arch = linux32
# Container specific configuration
lxc.id_map = u 0 100000 65536
lxc.id_map = g 0 100000 65536
lxc.rootfs = /home/administrator/.local/share/lxc/ubuntu02/rootfs
lxc.rootfs.backend = dir
lxc.utsname = ubuntu02
# Network configuration
lxc.network.type = veth
lxc.network.link = br0
lxc.network.flags = up
Теперь если попытаться запустить контейнер от пользователя без прав root (administrator), то появятся ошибки, суть которых заключается в том, что у текущего пользователя не хватает прав. Если бы у текущего пользователя были права root, то контейнер бы запустился. Но если попытаться запустить этот контейнер от root, то root будет искать контейнер по адресу "/var/lib/lxc/", а там его соответственно нет. Решение нашел
здесь, адаптировав его под ситуацию.
15) Добавлю прав домашней директории:
sudo chmod -R o+X $HOME
Теперь нужно установить пакет cgmanager.
16) Пакета cgmanager в репозитории astra linux нет. Поэтому подключаю репозиторий debian:
sudo echo "deb https://mirror.yandex.ru/debian/ stretch main contrib non-free" >> /etc/apt/sources.list
sudo apt update
17) Устанавливаю пакет:
sudo apt install cgmanager
18) Теперь отключаю репозиторий debian, для этого я вручную отредактирую файл /etc/apt/sources.list (удалю последнюю строку):
sudo vi /etc/apt/sources.list
sudo apt update
19) Теперь запускаю cgmanager:
sudo service cgmanager start
20) Теперь нужно выполнить "заветные" три команды, суть которых я не до конца понял:
sudo cgm create all user
sudo cgm chown all user $(id -u) $(id -g)
cgm movepid all user $$
21) И теперь наконец-то запускаю контейнер:
lxc-start -n ubuntu02 -d
Вот теперь вроде бы всё хорошо, но не совсем. После перезагрузки системы для запуска контейнера необходимо выполнить такой список команд:
sudo service lxc start
sudo service cgmanager start
sudo cgm create all user
sudo cgm chown all user $(id -u) $(id -g)
cgm movepid all user $$
lxc-start -n ubuntu02 -d
И это совсем не радует, поэтому:
22) LXC и cgmanager сразу ставим в автозагрузку:
sudo systemctl enable lxc
sudo systemctl enable cgmanager
Кроме того заметил, что три "заветные" команды из п.20 нужно выполнять непосредственно перед стартом контейнера. При чем если открыть 2 окна терминала и команды выполнить в одном, а контейнер запустить в другом, то контейнер не запустится. Углубляться в суть проблемы не стал (хотя стоило бы) и просто создал скрипт, который выполняет три "заветные команды" и сразу стартует контейнер.
23) Создаю каталог, в котором будет лежать скрипт:
mkdir ~/scripts
24) Создаю скрипт:
nano ~/scripts/lxc-start
Код:
sudo cgm create all user
sudo cgm chown all user $(id -u) $(id -g)
cgm movepid all user $$
lxc-start -n ubuntu02 -d
25) Выдаю файлу скрипта права на выполнение:
chmod +x ~/scripts/lxc-start
Теперь, если я захочу запустить контейнер, то я просто выполню этот скрипт (вот такой костыль).
Кроме всего, что уже сделано, мне нужно чтобы контейнер стартовал при запуске системы. Но этот контейнер существует только в пространстве моего пользователя (administrator), поэтому стартовать он должен после входа пользователя в систему. Поэтому я воспользуюсь "Автозапуском", который предлагает Astra Linux:
26) Захожу (в GUI) "Звезда/Панель управления/Система/Автозапуск" и нажимаю "Добавить приложение".
27) В строке "Имя" я указал "lxc-start". В строке "Команда" указываю "/home/administrator/scripts/lxc-start". Всё это сохраняю и закрываю.
28) Теперь у меня появился такой файл "~/.config/autostart/userapp_NyyzWL.desktop" с таким содержимым:
cat ~/.config/autostart/userapp_NyyzWL.desktop
Код:
[Desktop Entry]
Name=lxc-start
Type=Application
NoDisplay=false
Exec=/home/administrator/scripts/lxc-start
Hidden=false
Terminal=false
StartupNotify=false
29) Теперь перезагружаю систему и выполняю команду "lxc-ls -f". И вижу в колонке "State" напротив "ubuntu02" значение "RUNNING", этого я и добивался.