Инструкции по разворачиванию LXC на Debian-машине. Всё рассчитано на Debian Stable (Debian 12 Bookworm на момент написания статьи) и версию lxc 5.0.x.
LXC (LinuX Containers, http://linuxcontainers.org/) — это система виртуализации на уровне операционной системы, по сути нечто вроде продвинутого chroot. Удобно использовать для разработки и тестирования софта. Здесь рассматривается работа с lxc только средствами пакета lxc, а другие — например, через libvirt — нет.
Устанавливается стандартным образом в debian:
$ sudo apt install lxc
В Ubuntu (да, пакет называется lxc1):
$ sudo apt install lxc1
После установки проверяем:
$ sudo lxc-checkconfig
Kernel configuration not found at /proc/config.gz; searching...
Kernel configuration found at /boot/config-4.19.0-5-amd64
--- Namespaces ---
Namespaces: enabled
Utsname namespace: enabled
Ipc namespace: enabled
Pid namespace: enabled
User namespace: enabled
Network namespace: enabled
--- Control groups ---
Cgroups: enabled
Cgroup v1 mount points:
/sys/fs/cgroup/systemd
/sys/fs/cgroup/cpuset
/sys/fs/cgroup/cpu,cpuacct
/sys/fs/cgroup/freezer
/sys/fs/cgroup/blkio
/sys/fs/cgroup/pids
/sys/fs/cgroup/net_cls,net_prio
/sys/fs/cgroup/memory
/sys/fs/cgroup/devices
/sys/fs/cgroup/rdma
/sys/fs/cgroup/perf_event
Cgroup v2 mount points:
/sys/fs/cgroup/unified
Cgroup v1 clone_children flag: enabled
Cgroup device: enabled
Cgroup sched: enabled
Cgroup cpu account: enabled
Cgroup memory controller: enabled
Cgroup cpuset: enabled
--- Misc ---
Veth pair device: enabled, not loaded
Macvlan: enabled, not loaded
Vlan: enabled, not loaded
Bridges: enabled, not loaded
Advanced netfilter: enabled, not loaded
CONFIG_NF_NAT_IPV4: enabled, not loaded
CONFIG_NF_NAT_IPV6: enabled, not loaded
CONFIG_IP_NF_TARGET_MASQUERADE: enabled, not loaded
CONFIG_IP6_NF_TARGET_MASQUERADE: enabled, not loaded
CONFIG_NETFILTER_XT_TARGET_CHECKSUM: enabled, not loaded
CONFIG_NETFILTER_XT_MATCH_COMMENT: enabled, not loaded
FUSE (for use with lxcfs): enabled, loaded
--- Checkpoint/Restore ---
checkpoint restore: enabled
CONFIG_FHANDLE: enabled
CONFIG_EVENTFD: enabled
CONFIG_EPOLL: enabled
CONFIG_UNIX_DIAG: enabled
CONFIG_INET_DIAG: enabled
CONFIG_PACKET_DIAG: enabled
CONFIG_NETLINK_DIAG: enabled
File capabilities:
Note : Before booting a new kernel, you can check its configuration
usage : CONFIG=/path/to/config /usr/bin/lxc-checkconfig
Иногда вы можете увидеть в этом выводе User namespace: missing
, но сделать с этим ничего нельзя, придётся так жить, если не хотите пересобирать ядро и отказываться от XFS, в новых ядрах проблема уже исправлена.
Дальше устанавливаем другие нужные пакеты:
$ sudo apt install debootstrap
Следующий шаг опциональный, он нужен, только если команда mount | grep cgroup
не возвращает ничего. Но обычно в нём нет необходимости.
Дописываем в /etc/fstab
строчку для автоматического монтирования файловой системы cgroup
1 (и сразу же монтируем):
$ sudo -i
# echo "cgroup /sys/fs/cgroup cgroup defaults 0 0" >> /etc/fstab
# mount /sys/fs/cgroup
Теперь можно создавать контейнеры (указываем название контейнера первым аргументом и название шаблона в аргументе -t
):
$ sudo lxc-create myfirstcontainer -t debian
debootstrap is /usr/sbin/debootstrap
Checking cache download in /var/cache/lxc/debian/rootfs-stable-amd64 ...
Downloading debian minimal ...
I: Target architecture can be executed
I: Retrieving InRelease
I: Checking Release signature
I: Valid Release signature (key id 4D64FEC119C2029067D6E791F8D2585B8783D481)
I: Retrieving Packages
I: Validating Packages
I: Resolving dependencies of required packages...
I: Resolving dependencies of base packages...
I: Checking component main on http://deb.debian.org/debian...
I: Retrieving adduser 3.134
I: Validating adduser 3.134
I: Retrieving apt 2.6.1
... много таких запросов ...
I: Configuring libc-bin...
I: Configuring ca-certificates...
I: Base system installed successfully.
Download complete.
Copying rootfs to /var/lib/lxc/myfirstcontainer/rootfs...ln: failed to create symbolic link '/var/lib/lxc/myfirstcontainer/rootfs/etc/mtab': File exists
Generating locales (this might take a while)...
en_US.UTF-8... done
en_US.UTF-8... done
Generation complete.
Failed to disable unit, unit hwclock.sh.service does not exist.
update-rc.d: error: cannot find a LSB script for hwclockfirst.sh
Current default time zone: 'Asia/Krasnoyarsk'
Local time is now: Thu Nov 28 23:45:41 +07 2024.
Universal Time is now: Thu Nov 28 16:45:41 UTC 2024.
Скачанные пакеты кешируются и далее используются при других вызовах.
В ранних версиях LXC нужно было обязательно использовать аргумент
-n
для указания имени контейнера, теперь это необязательно,lxc-
команды принимают название контейнера первым аргументом. Но-n
по-прежнему можно использовать.
Создать контейнер можно в интерактивном режиме, указав шаблон download
:
$ sudo lxc-create myfirstcontainer -t download
Downloading the image index
---
DIST RELEASE ARCH VARIANT BUILD
---
almalinux 8 amd64 default 20241127_23:08
almalinux 8 arm64 default 20241127_23:08
almalinux 9 amd64 default 20241127_23:08
almalinux 9 arm64 default 20241127_23:08
alpine 3.17 amd64 default 20241127_13:00
...
... десятки вариантов
...
ubuntu jammy amd64 default 20241127_07:42
...
ubuntu oracular armhf default 20241127_07:42
voidlinux current amd64 default 20241127_17:10
voidlinux current arm64 default 20241127_17:10
---
Distribution:
ubuntu <<<< вводим это
Release:
jammy <<<< вводим это
Architecture:
amd64 <<<< вводим это
Downloading the image index
Downloading the rootfs
Unpacking the rootfs
---
You just created an Ubuntu jammy amd64 (20241127_07:42) container.
To enable SSH, run: apt install openssh-server
No default root or user password are set by LXC.
Или можно указать сразу параметры нужного контейнера (в данном случае ubuntu 22.04 "jammy" amd64):
$ sudo lxc-create myfirstcontainer -t download -- --dist ubuntu --release jammy --arch amd64
Using image from local cache
Unpacking the rootfs
---
You just created an Ubuntu jammy amd64 (20241127_07:42) container.
To enable SSH, run: apt install openssh-server
No default root or user password are set by LXC.
Сами контейнеры создаются в каталоге /var/lib/lxc/
, в нём по одному каталогу для каждого контейнера, имя каталога совпадает с названием контейнера.
Контейнер создан, можно его запускать:
# lxc-start myfirstcontainer
К запущенному контейнеру можно подключиться так:
$ sudo lxc-attach myfirstcontainer
Выйти из этого режима можно стандартной командой exit
.
Пароль для юзера по умолчанию зависит от используемого шаблона, его можно изменить командой:
% sudo lxc-attach myfirstcontainer passwd
Остановка контейнера:
$ sudo lxc-stop myfirstcontainer
Полное уничтожение контейнера:
$ sudo lxc-destroy myfirstcontainer
Настройка сети¶
В прошлых версиях lxc после установки сеть нужно было настраивать вручную, но сейчас этого уже не нужно — автоматически создаётся пустой bridge-адаптер lxcbr0
. Этот адаптер прописан в настройках по умолчанию для новых контейнеров в файле /etc/lxc/default.conf
. В принципе такая схема уже годится для нормального использования: в новых контейнерах сразу будет доступна сеть, но доступа снаружи хостовой машины до контейнеров не будет.
По умолчанию используется режим сети veth, при котором для каждого контейнера создаётся пара виртуальных сетевых интерфейсов (один внутри контейнера, другой снаружи).
Если вы используете на хостовой машине connman для конфигурации сети, то для корректной работы сети в контейнерах нужно запретить connman управлять veth-интерфейсами (в противном случае connman будет их конфигурить и ломать маршрутизацию). Для этого отредактируйте файл /etc/connman/main.conf
, найдите строчку типа такой:
# NetworkInterfaceBlacklist = vmnet,vboxnet,virbr,ifb,ve-,vb-
раскомментируйте и допишите в конце через запятую veth
, в итоге должно выглядеть так:
NetworkInterfaceBlacklist = vmnet,vboxnet,virbr,ifb,ve-,vb-,veth
Перезагрузите connman:
$ sudo systemctl restart connman
──────────────────
Контейнер получает адрес из приватной сети типа 10.0.3.208
, по нему он доступен с хостовой машины, однако снаружи хостовой машины достучаться до контейнера не получится.
Есть несколько способов организовать доступ. Например, добавить системный интерфейс в bridge и настроить veth на его использование, в этом случае в контейнере можно будет получить адрес в той же подсети, что и хостовая машина. Об этом подробно написано на сайте debian: https://wiki.debian.org/LXC/SimpleBridge#Host_device_as_bridge.
Другой способ — через iptables организовать проброс порта до конкретного сервиса. Например, проброс порта 2222 хостовой машины до порта 22 (ssh) контейнера с адресом 10.0.3.208:
$ sudo iptables -t nat -A PREROUTING -p tcp --dport 2222 -j DNAT --to-destination 10.0.3.208:22
Если адрес хостовой машины 192.168.64.3, то получить доступ до ssh-сервера контейнера можно командой:
$ ssh -p 2222 192.168.64.3
Поддержка и обслуживание¶
Дальше команды россыпью для сопровождения lxc-виртуалок.
Список всех виртуалок¶
$ sudo lxc-ls -f
NAME STATE IPV4 IPV6 GROUPS AUTOSTART
------------------------------------------------------------------
debian-jessie-i386-testing STOPPED - - - NO
myfirstcontainer-i386 STOPPED - - - NO
ubuntu-12.04-i386-drupal STOPPED - - - NO
ubuntu-12.04-i386-sample STOPPED - - - NO
Рестарт сетевой поддержки LXC¶
Это нужно делать после изменений в /etc/default/lxc-net
, например.
shell-session $ sudo service lxn-net restart ~
Потом ещё допишу, если какие идеи или проблемы возникнут.
Links¶
- https://wiki.debian.org/LXC
- http://www.hansconstantine.com/installing-lxc-linux-containers-ubuntu-13-04
- http://sylvain.fankhauser.name/blog/LxcIn30Minutes.html
- https://wiki.debian.org/LXC/LibVirtDefaultNetwork
Примечания¶
История изменений¶
- 2014-01-23 — первая версия
- 2015-05-05 — актуализация и проверка работоспособности примеров
- 2018-04-20 — актуализация и проверка
- 2019-09-25 — актуализация до debian buster и проверка
- 2024-11-30 — актуализация до debian bookworm, проверка, переписан раздел про сеть
-
cgroup расшифровывается как control group, подробнее — в википедии. ↩
-
Я сделал шаблон на основе файла из стандартного пакета
lxc
, а помимо выбора архитектуры также включил в него установку некоторых дополнительных приложений (например, vim, file и других). ↩
Спасибо за статью. Как пробросить 22 порт ssh'a через NAT не подскажите?
Без внешнего сервиса, думаю, никак.
Отличная статья. Но как всегда есть недочет. И хочется узнать где создается файл lxc-network.xml а то совсем запутался. И какие еще варианты настройки сети возможны....