Установка и настройка LXC под Ubuntu 22.04. Непривилегированные контейнеры.
Перед настройкой LXC рекомендуется выполнить базовую настройку Ubuntu .
Воспользуйтесь инструкцией для настройки nvidia в LXC
UID и GID Maping
Убедитесь, что у вас корректно настроены map uig и gid. Mapping нужен для того, чтобы запускать непривелигированные контейнера. Т.е. root в контейнере на хост машине будет работать с ID 100000, а не 0. Соостветственно файлы в контейнеры будут иметь владельца, начиная с 100000.
nano /etc/subuid
_x000D_lxc:100000:65536_x000D_lxd:100000:65536_x000D_root:100000:65536 nano /etc/subgid
_x000D_lxc:100000:65536_x000D_lxd:100000:65536_x000D_root:100000:65536 Для удобства вы можете добавить пользователя lxc-root, чтобы в htop видеть процессы запущенные в lxc
_x000D_groupadd -r --gid 100000 lxc-root_x000D_useradd -r -M --uid 100000 -g lxc-root lxc-root Установка LXC
_x000D_aptitude install lxc Установите права доступа, чтобы корректно запускались контейнеры:
_x000D_chown lxc-root:root /var/lib/lxc_x000D_chmod 755 /var/lib/lxc Также вам потребуется настроить UID для LXC. Пропишите в конце файла следующие строки, выполнив команду nano /etc/lxc/default.conf
_x000D_lxc.idmap = u 0 100000 65536_x000D_lxc.idmap = g 0 100000 65536 Настройка сети
Рекомендуется использовать сеть 172.30.0.1/24. Более подробный список указан в списке сетей .
В файле /etc/default/lxc-net пропишите
_x000D_USE_LXC_BRIDGE="true"_x000D_LXC_BRIDGE="lxcbr0"_x000D_LXC_ADDR="172.30.0.1"_x000D_LXC_NETMASK="255.255.255.0"_x000D_LXC_NETWORK="172.30.0.0/24"_x000D_LXC_DHCP_RANGE="172.30.0.2,172.30.0.254"_x000D_LXC_DHCP_MAX="253"_x000D_LXC_DHCP_CONFILE=/etc/lxc/dnsmasq.conf_x000D_#LXC_DOMAIN="lxc" Создайте файл /etc/lxc/dnsmasq.conf и пропишите в нем:
_x000D_port=53_x000D_listen-address=172.30.0.1_x000D_resolv-file=/etc/resolv.conf_x000D_domain-needed Если у вас уже запущен dnsmasq на 53 порту, то можно изменить порт на 53172
_x000D_port=53172 Включите драйвера br_netfilter
_x000D_echo overlay >> /etc/modules-load.d/docker.conf_x000D_echo br_netfilter >> /etc/modules-load.d/docker.conf Установка контейнера
Установка контейнера LXC Centos 7:
_x000D_lxc-create -t download -n test-centos -- --dist centos --release 7 --arch amd64 Установка контейнера LXC Ubuntu 22.04:
_x000D_lxc-create -t download -n test-ubuntu -- --dist ubuntu --release bionic --arch amd64 Установка контейнера LXC Ubuntu 24.04:
_x000D_lxc-create -t download -n test-ubuntu -- --dist ubuntu --release noble --arch amd64 Установка контейнера LXC Debian Jessie:
_x000D_lxc-create -t download -n test-debian -- --dist debian --release jessie --arch amd64 Установка контейнера Alpine Linux 3.10:
_x000D_lxc-create -t download -n test-alpine -- --dist alpine --release 3.10 --arch amd64 Список шаблонов: https://us.images.linuxcontainers.org/
Если выдает ошибку «ERROR: Unable to fetch GPG key from keyserver» то нужно прописать keyserver:
_x000D_lxc-create -t download -n test-ubuntu-focal -- --dist ubuntu --release focal --arch amd64 --keyserver hkp://keyserver.ubuntu.com Настройка nested контейнера
Nested контейнер — это возможность запустить контейнер в контейнере. Например, если вам нужно будет запустить Docker внутри LXC контейнера, то нужно включить данную опцию.
Опция включается в файле конфига контейнера /var/lib/lxc/<название контейнера>/config
Раскоментируйте строчку:
_x000D_#lxc.include = /usr/share/lxc/config/nesting.conf Также может понадобится прописать параметр для монтирования файловой системы cgroup
_x000D_lxc.mount.auto = cgroup-full:rw Настройка сети контейнера
В конце файла настроек контейнера /var/lib/lxc/<название контейнера>/config укажите слоедующие параметры:
_x000D_# Network configuration_x000D_lxc.net.0.type = veth_x000D_lxc.net.0.link = lxcbr0_x000D_lxc.net.0.flags = up_x000D_lxc.net.0.hwaddr = 00:16:3e:6b:aa:11_x000D_lxc.net.0.ipv4.address = 172.30.0.10/24_x000D_lxc.net.0.ipv4.gateway = 172.30.0.1 172.30.0.10 — Это IP адрес контейнера
172.30.0.1 — Адрес шлюза
00:16:3e:6b:aa:11 — MAC Адрес должен быть уникальный
lxcbr0 — Имя LXC bridge. Обычно ставится автоматически
Настройка IP адреса для контейнера с Alpine Linux
Бывает, что первого способа не достаточно чтобы выдать IP адрес. Тогда нужно задать IP адрес в самом контейнере.
Подключитесь к контейнеру через команду
_x000D_lxc-attach название контейнера Откройте файл /etc/network/interfaces
Вместо iface eth0 inet dhcp Пропишите:
_x000D_iface eth0 inet static_x000D_ address 172.30.0.10_x000D_ netmask 255.255.255.0_x000D_ gateway 172.30.0.1 Выйдите из контейнера командой:
_x000D_exit Перезапустить контейнер:
_x000D_lxc-stop название контейнера_x000D_lxc-start название контейнера Настройка IP адреса для контейнера с Centos
Подключитесь к контейнеру через команду
_x000D_lxc-attach название контейнера Для Centos7 в файле /etc/sysconfig/network-scripts/ifcfg-eth0 укажите
_x000D_DEVICE=eth0_x000D_ONBOOT=yes_x000D__x000D_IPADDR=172.30.0.20_x000D_NETMASK=255.255.255.0_x000D_GATEWAY=172.30.0.1_x000D_DNS1=172.30.0.1_x000D__x000D_#BOOTPROTO=dhcp_x000D_HOSTNAME=test-centos_x000D_NM_CONTROLLED=no_x000D_TYPE=Ethernet_x000D_MTU=_x000D_DHCP_HOSTNAME=`hostname` Настройка IP адреса для контейнера с Ubuntu
Подключитесь к контейнеру через команду
_x000D_lxc-attach название контейнера Откройте файл nano /etc/netplan/10-lxc.yaml и пропишите следующее содержимое
_x000D_network:_x000D_ version: 2_x000D_ ethernets:_x000D_ eth0:_x000D_ dhcp4: no_x000D_ dhcp6: no_x000D_ addresses: [172.30.0.20/24]_x000D_ gateway4: 172.30.0.1_x000D_ nameservers:_x000D_ addresses: [172.30.0.1] Если IP адрес был задан в адресе конфига, то в netplan их можно не указывать.
Перезапустить контейнер:
_x000D_lxc-stop название контейнера_x000D_lxc-start название контейнера Настройка DNS
Подключитесь к контейнеру и удалите файл resolv
_x000D_rm -f /etc/resolv.conf И создайте его заново:
nano /etc/resolv.conf
_x000D_nameserver 172.30.0.1_x000D_ Перенос папки на другой диск
К примеру, вам нужно перенести папку lxc в /srv.
Перед переносом папки, остановите все контейнеры.
Создайте папку lxc в srv
_x000D_mkdir /srv/lxc_x000D_chown lxc-root:root /srv/lxc_x000D_chmod 755 /srv/lxc перенесите все содержимое из папки /var/lib/lxc в /srv/lxc
_x000D_mv -f /var/lib/lxc/* /srv/lxc Убедитесь что папка /var/lib/lxc пустая
_x000D_ls -la /var/lib/lxc /etc/fstab пропишите строчку в конце
_x000D_/srv/lxc /var/lib/lxc none bind Сделайте монтирование папки:
_x000D_mount -a По умолчанию при загрузке будет монтироваться папка
Перенос контейнера на другой хост
Остановите контейнер:
_x000D_lxc-stop название_контейнера Создайте на другом сервере папку:
_x000D_/var/lib/lxc/название_контейнера/ Перенесите контейнер через rsync:
_x000D_rsync -aSsuh --info=progress2 --numeric-ids /var/lib/lxc/название_контейнера/ server:/var/lib/lxc/название_контейнера/ Автозапуск контейнера
Чтобы настроить автоматическое включение контейнера, укажите следующие строки для файла /var/lib/lxc/<название контейнера>/config :
_x000D_lxc.start.auto = 1_x000D_lxc.start.delay = 5 # Задержка, когда будет запущен контейнер Если хотите, чтобы контейнер не запускался при старте, укажите 0
Ограничение ресурсов CPU
Иногда нужно ограничить cpu для контейнера. Чтобы это сделать, пропишите строчку в конфиге контейнера
_x000D_# CPU Limit_x000D_lxc.cgroup.cpuset.cpus = 0,1 0,1 — означает запустить контейнер на 1м и 2м ядре.
Отключение AppArmor в LXC
Иногда AppArmor мешает контейнеру запуститься. Тогда в конце файла настроек контейнера /var/lib/lxc/<название контейнера>/config пропишите следующую строку
Прописывайте, только если контейнер не запускается.
_x000D_lxc.apparmor.profile = unconfined Команды для работы с контейнерами
Чтобы запустить контейнер выполните:
_x000D_lxc-start название контейнера Чтобы остановить контейнер выполните:
_x000D_lxc-stop название контейнера Чтобы подключиться к контейнеру под рутом:
_x000D_lxc-attach название контейнера Просмотреть список контейнеров и их IP адреса
_x000D_lxc-ls -f Установка SSH
С хоста. Сгенерируйте ключ ssh, если его у вас нет в домашней папке:
_x000D_ssh-keygen Установите ваш публичный сертификат в контейнер:
_x000D_mkdir -p /var/lib/lxc/test-ubuntu/rootfs/root/.ssh/_x000D_cat ~/.ssh/id_rsa.pub >> /var/lib/lxc/test-ubuntu/rootfs/root/.ssh/authorized_keys_x000D_chown -R lxc-root:lxc-root /var/lib/lxc/test-ubuntu/rootfs/root/.ssh_x000D_chmod 700 /var/lib/lxc/test-ubuntu/rootfs/root/.ssh_x000D_chmod 400 /var/lib/lxc/test-ubuntu/rootfs/root/.ssh/authorized_keys Подключитесь к контейнеру через консоль командой:
_x000D_lxc-attach test-ubuntu Установите SSH сервер в контейнере.
Для Ubuntu:
_x000D_apt install openssh-server -y Для Centos:
_x000D_yum install openssh-server -y_x000D_systemctl enable sshd Установите root пароль:
_x000D_passwd Завершите текущий сеанс в контейнере:
_x000D_exit Теперь вы можете подключиться к контейнеру через SSH:
_x000D_ssh root@IP-адрес-контейнера Проброс портов
Проброс портов нужен, чтобы расшарить контейнер в интернет. Иногда этого не требуется, например, если вы проксируете трафик через nginx. Делать нужно на хосте.
Чтобы пробросить порты, нужно установить и настроить iptables-persistent
При работе с iptables будьте осторожны.
Одно неверное движение и доступ к серверу может быть заблокирован !!!
После этого в файле /etc/iptables/rules.v4 и /etc/iptables/rules.v6 в секцию *nat нужно указать строчки
_x000D_# Проброс SSH на 172.30.0.10_x000D_-A PREROUTING ! -i lxcbr0 -p tcp -m tcp --dport 22340 -j DNAT --to-destination 172.30.0.10:22_x000D__x000D_# Проброс HTTP на 172.30.0.10_x000D_-A PREROUTING ! -i lxcbr0 -p tcp -m tcp --dport 80 -j DNAT --to-destination 172.30.0.10:80_x000D_-A PREROUTING ! -i lxcbr0 -p tcp -m tcp --dport 443 -j DNAT --to-destination 172.30.0.10:443_x000D__x000D_# Проброс FTP на 172.30.0.10_x000D_-A PREROUTING ! -i lxcbr0 -p tcp -m tcp --dport 21 -j DNAT --to-destination 172.30.0.10:21_x000D_-A PREROUTING ! -i lxcbr0 -p tcp -m tcp --dport 30000:50000 -j DNAT --to-destination 172.30.0.10:30000-50000_x000D__x000D_ и выполнить:
_x000D_iptables-restore < /etc/iptables/rules.v4_x000D_ip6tables-restore < /etc/iptables/rules.v6_x000D_systemctl stop lxc_x000D_systemctl stop lxc-net_x000D_systemctl start lxc-net_x000D_systemctl start lxc