Установка и настройка LXC в Ubuntu 22.04
Установка и настройка LXC под Ubuntu 22.04. Непривилегированные контейнеры.
Перед настройкой LXC рекомендуется выполнить базовую настройку Ubuntu.
Воспользуйтесь инструкцией для настройки nvidia в LXC
UID и GID Maping
Убедитесь, что у вас корректно настроены map uig и gid. Mapping нужен для того, чтобы запускать непривелигированные контейнера. Т.е. root в контейнере на хост машине будет работать с ID 100000, а не 0. Соостветственно файлы в контейнеры будут иметь владельца, начиная с 100000.
nano /etc/subuid
lxc:100000:65536
lxd:100000:65536
root:100000:65536
nano /etc/subgid
lxc:100000:65536
lxd:100000:65536
root:100000:65536
Для удобства вы можете добавить пользователя lxc-root, чтобы в htop видеть процессы запущенные в lxc
groupadd -r --gid 100000 lxc-root
useradd -r -M --uid 100000 -g lxc-root lxc-root
Установка LXC
aptitude install lxc
Установите права доступа, чтобы корректно запускались контейнеры:
chown lxc-root:root /var/lib/lxc
chmod 755 /var/lib/lxc
Также вам потребуется настроить UID для LXC. Пропишите в конце файла следующие строки, выполнив команду nano /etc/lxc/default.conf
lxc.idmap = u 0 100000 65536
lxc.idmap = g 0 100000 65536
Настройка сети
Рекомендуется использовать сеть 172.30.0.1/24. Более подробный список указан в списке сетей.
В файле /etc/default/lxc-net пропишите
USE_LXC_BRIDGE="true"
LXC_BRIDGE="lxcbr0"
LXC_ADDR="172.30.0.1"
LXC_NETMASK="255.255.255.0"
LXC_NETWORK="172.30.0.0/24"
LXC_DHCP_RANGE="172.30.0.2,172.30.0.254"
LXC_DHCP_MAX="253"
LXC_DHCP_CONFILE=/etc/lxc/dnsmasq.conf
#LXC_DOMAIN="lxc"
Создайте файл /etc/lxc/dnsmasq.conf и пропишите в нем:
port=53
listen-address=172.30.0.1
resolv-file=/etc/resolv.conf
domain-needed
Если у вас уже запущен dnsmasq на 53 порту, то можно изменить порт на 53172
port=53172
Включите драйвера br_netfilter
echo overlay >> /etc/modules-load.d/docker.conf
echo br_netfilter >> /etc/modules-load.d/docker.conf
Установка контейнера
Установка контейнера LXC Centos 7:
lxc-create -t download -n test-centos -- --dist centos --release 7 --arch amd64
Установка контейнера LXC Ubuntu 22.04:
lxc-create -t download -n test-ubuntu -- --dist ubuntu --release bionic --arch amd64
Установка контейнера LXC Ubuntu 24.04:
lxc-create -t download -n test-ubuntu -- --dist ubuntu --release noble --arch amd64
Установка контейнера LXC Debian Jessie:
lxc-create -t download -n test-debian -- --dist debian --release jessie --arch amd64
Установка контейнера Alpine Linux 3.10:
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:
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
Раскоментируйте строчку:
#lxc.include = /usr/share/lxc/config/nesting.conf
Также может понадобится прописать параметр для монтирования файловой системы cgroup
lxc.mount.auto = cgroup-full:rw
Настройка сети контейнера
В конце файла настроек контейнера /var/lib/lxc/<название контейнера>/config укажите слоедующие параметры:
# Network configuration
lxc.net.0.type = veth
lxc.net.0.link = lxcbr0
lxc.net.0.flags = up
lxc.net.0.hwaddr = 00:16:3e:6b:aa:11
lxc.net.0.ipv4.address = 172.30.0.10/24
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 адрес в самом контейнере.
Подключитесь к контейнеру через команду
lxc-attach название контейнера
Откройте файл /etc/network/interfaces
Вместо iface eth0 inet dhcp Пропишите:
iface eth0 inet static
address 172.30.0.10
netmask 255.255.255.0
gateway 172.30.0.1
Выйдите из контейнера командой:
exit
Перезапустить контейнер:
lxc-stop название контейнера
lxc-start название контейнера
Настройка IP адреса для контейнера с Centos
Подключитесь к контейнеру через команду
lxc-attach название контейнера
Для Centos7 в файле /etc/sysconfig/network-scripts/ifcfg-eth0 укажите
DEVICE=eth0
ONBOOT=yes
IPADDR=172.30.0.20
NETMASK=255.255.255.0
GATEWAY=172.30.0.1
DNS1=172.30.0.1
#BOOTPROTO=dhcp
HOSTNAME=test-centos
NM_CONTROLLED=no
TYPE=Ethernet
MTU=
DHCP_HOSTNAME=`hostname`
Настройка IP адреса для контейнера с Ubuntu
Подключитесь к контейнеру через команду
lxc-attach название контейнера
Откройте файл nano /etc/netplan/10-lxc.yaml и пропишите следующее содержимое
network:
version: 2
ethernets:
eth0:
dhcp4: no
dhcp6: no
addresses: [172.30.0.20/24]
gateway4: 172.30.0.1
nameservers:
addresses: [172.30.0.1]
Если IP адрес был задан в адресе конфига, то в netplan их можно не указывать.
Перезапустить контейнер:
lxc-stop название контейнера
lxc-start название контейнера
Настройка DNS
Подключитесь к контейнеру и удалите файл resolv
rm -f /etc/resolv.conf
И создайте его заново:
nano /etc/resolv.conf
nameserver 172.30.0.1
Перенос папки на другой диск
К примеру, вам нужно перенести папку lxc в /srv.
Перед переносом папки, остановите все контейнеры.
Создайте папку lxc в srv
mkdir /srv/lxc
chown lxc-root:root /srv/lxc
chmod 755 /srv/lxc
перенесите все содержимое из папки /var/lib/lxc в /srv/lxc
mv -f /var/lib/lxc/* /srv/lxc
Убедитесь что папка /var/lib/lxc пустая
ls -la /var/lib/lxc
/etc/fstab пропишите строчку в конце
/srv/lxc /var/lib/lxc none bind
Сделайте монтирование папки:
mount -a
По умолчанию при загрузке будет монтироваться папка
Перенос контейнера на другой хост
Остановите контейнер:
lxc-stop название_контейнера
Создайте на другом сервере папку:
/var/lib/lxc/название_контейнера/
Перенесите контейнер через rsync:
rsync -aSsuh --info=progress2 --numeric-ids /var/lib/lxc/название_контейнера/ server:/var/lib/lxc/название_контейнера/
Автозапуск контейнера
Чтобы настроить автоматическое включение контейнера, укажите следующие строки для файла /var/lib/lxc/<название контейнера>/config:
lxc.start.auto = 1
lxc.start.delay = 5 # Задержка, когда будет запущен контейнер
Если хотите, чтобы контейнер не запускался при старте, укажите 0
Ограничение ресурсов CPU
Иногда нужно ограничить cpu для контейнера. Чтобы это сделать, пропишите строчку в конфиге контейнера
# CPU Limit
lxc.cgroup.cpuset.cpus = 0,1
0,1 - означает запустить контейнер на 1м и 2м ядре.
Отключение AppArmor в LXC
Иногда AppArmor мешает контейнеру запуститься. Тогда в конце файла настроек контейнера /var/lib/lxc/<название контейнера>/config пропишите следующую строку
Прописывайте, только если контейнер не запускается.
lxc.apparmor.profile = unconfined
Команды для работы с контейнерами
Чтобы запустить контейнер выполните:
lxc-start название контейнера
Чтобы остановить контейнер выполните:
lxc-stop название контейнера
Чтобы подключиться к контейнеру под рутом:
lxc-attach название контейнера
Просмотреть список контейнеров и их IP адреса
lxc-ls -f
Установка SSH
С хоста. Сгенерируйте ключ ssh, если его у вас нет в домашней папке:
ssh-keygen
Установите ваш публичный сертификат в контейнер:
mkdir -p /var/lib/lxc/test-ubuntu/rootfs/root/.ssh/
cat ~/.ssh/id_rsa.pub >> /var/lib/lxc/test-ubuntu/rootfs/root/.ssh/authorized_keys
chown -R lxc-root:lxc-root /var/lib/lxc/test-ubuntu/rootfs/root/.ssh
chmod 700 /var/lib/lxc/test-ubuntu/rootfs/root/.ssh
chmod 400 /var/lib/lxc/test-ubuntu/rootfs/root/.ssh/authorized_keys
Подключитесь к контейнеру через консоль командой:
lxc-attach test-ubuntu
Установите SSH сервер в контейнере.
Для Ubuntu:
apt install openssh-server -y
Для Centos:
yum install openssh-server -y
systemctl enable sshd
Установите root пароль:
passwd
Завершите текущий сеанс в контейнере:
exit
Теперь вы можете подключиться к контейнеру через SSH:
ssh root@IP-адрес-контейнера
Проброс портов
Проброс портов нужен, чтобы расшарить контейнер в интернет. Иногда этого не требуется, например, если вы проксируете трафик через nginx. Делать нужно на хосте.
Чтобы пробросить порты, нужно установить и настроить iptables-persistent
При работе с iptables будьте осторожны.
Одно неверное движение и доступ к серверу может быть заблокирован !!!
После этого в файле /etc/iptables/rules.v4 и /etc/iptables/rules.v6 в секцию *nat нужно указать строчки
# Проброс SSH на 172.30.0.10
-A PREROUTING ! -i lxcbr0 -p tcp -m tcp --dport 22340 -j DNAT --to-destination 172.30.0.10:22
# Проброс HTTP на 172.30.0.10
-A PREROUTING ! -i lxcbr0 -p tcp -m tcp --dport 80 -j DNAT --to-destination 172.30.0.10:80
-A PREROUTING ! -i lxcbr0 -p tcp -m tcp --dport 443 -j DNAT --to-destination 172.30.0.10:443
# Проброс FTP на 172.30.0.10
-A PREROUTING ! -i lxcbr0 -p tcp -m tcp --dport 21 -j DNAT --to-destination 172.30.0.10:21
-A PREROUTING ! -i lxcbr0 -p tcp -m tcp --dport 30000:50000 -j DNAT --to-destination 172.30.0.10:30000-50000
и выполнить:
iptables-restore < /etc/iptables/rules.v4
ip6tables-restore < /etc/iptables/rules.v6
systemctl stop lxc
systemctl stop lxc-net
systemctl start lxc-net
systemctl start lxc
Дополнительно: