Инструкции по разворачиванию LXC на Debian-мащине. Всё рассчитано на Debian Stable (Debian 10 Buster на момент написания статьи) и версию lxc 3.0.x.
LXC (LinuX Containers, http://linuxcontainers.org/) — это система виртуализации на уровне операционной системы, по сути нечто вроде продвинутого chroot. Удобно использовать для разработки и тестирования софта. Здесь рассматривается работа с lxc только средствами пакета lxc, а другие — например, через libvirt — нет.
Устанавливается стандартным образом:
$ sudo apt install lxc
После установки проверяем:
$ 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
Теперь можно создавать контейнеры (указываем название контейнера в аргументе -n
и название шаблона в аргументе -t
):
$ sudo lxc-create -n myfirstcontainer -t debian
lxc-create: No config file specified, using the default config /etc/lxc/default.conf
debootstrap is /usr/sbin/debootstrap
Checking cache download in /var/cache/lxc/debian/rootfs-squeeze-amd64 ...
Downloading debian minimal ...
I: Retrieving Release
I: Retrieving Release.gpg
I: Checking Release signature
I: Valid Release signature (key id 0E4EDE2C7F3E1FC0D033800E64481591B98321F9)
....ещё 100500 строчек вывода....
update-rc.d: using dependency based boot sequencing
Root password is 'root', please change !
'debian' template installed
'myfirstcontainer' created
Создать контейнер можно в интерактивном режиме, указав шаблон download
:
$ sudo lxc-create -n myfirstcontainer -t download
Setting up the GPG keyring
Downloading the image index
---
DIST RELEASE ARCH VARIANT BUILD
---
alpine 3.10 amd64 default 20190925_13:00
alpine 3.10 arm64 default 20190925_13:00
alpine 3.10 armhf default 20190925_13:00
alpine 3.10 i386 default 20190925_13:00
alpine 3.10 ppc64el default 20190925_13:06
...
... десятки вариантов
...
voidlinux current arm64 default 20190924_17:10
voidlinux current armhf default 20190924_17:10
voidlinux current i386 default 20190924_17:10
---
Distribution:
ubuntu <<<< вводим это
Release:
bionic <<<< вводим это
Architecture:
amd64 <<<< вводим это
Downloading the image index
Downloading the rootfs
...
Или можно указать сразу параметры нужного контейнера (в данном случае ubuntu 18.04 "bionic" amd64):
$ sudo lxc-create -n myfirstcontainer -t download -- --dist ubuntu --release bionic --arch amd64
Setting up the GPG keyring
Downloading the image index
Downloading the rootfs
Downloading the metadata
The image cache is now ready
Unpacking the rootfs
---
You just created an Ubuntu bionic amd64 (20190925_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 -n myfirstcontainer
К запущенному контейнеру можно подключиться так:
$ sudo lxc-attach -n myfirstcontainer
Выйти из этого режима можно стандартной командой exit
.
Пароль для юзера по умолчанию зависит от используемого шаблона, его можно изменить командой:
% sudo lxc-attach -n myfirstcontainer passwd
Остановка контейнера:
$ sudo lxc-stop -n myfirstcontainer
Полное уничтожение контейнера:
$ sudo lxc-destroy -n myfirstcontainer
Настройка сети¶
По умолчанию контейнер создаётся совсем без поддержки внешней сети, внутри нет никаких сетевых интерфейсов кроме lo
, так что сейчас будем настраивать сеть. Для lxc есть несколько вариантов сети, здесь пока только один рассмотрим — через libvirt.
Сначала ставим нужные пакеты на хостовую систему (НЕ в контейнер!):
$ sudo apt install -y libvirt-clients libvirt-daemon-system iptables ebtables dnsmasq-base
Проверяем, что libvirt вообще работает (здесь и далее пользуемся программой управления virsh
):
$ sudo virsh net-list --all
Name State Autostart Persistent
----------------------------------------------
default inactive no yes
$ sudo virsh net-info default
Name default
UUID db05966a-cd06-43ef-9add-4e5c9cd8a871
Active: yes
Persistent: yes
Autostart: no
Bridge: virbr0
Это сеть по умолчанию с названием default
, но мы её использовать не будем (не стоит полагаться на настройки по умолчанию), а сделаем отдельную виртуальную сеть специально для lxc.
Все настройки сети определяются через xml-файл (uuid не указываем, он автоматически сгенерится при создании, содержимое сохраняем в файл /tmp/lxc-network.xml
):
<network>
<name>lxc-network</name>
<bridge name="virbrlxc0" />
<forward mode="nat" />
<ip address="10.10.45.1" netmask="255.255.255.0">
<dhcp>
<range start='10.10.45.101' end='10.10.45.254'/>
</dhcp>
</ip>
</network>
В этом файле мы задаём диапазон автоматически выделяемых черех dhcp адресов примерно с середины диапазона, а первые адреса (10.10.45.2 ÷ 10.10.45.100) будут использоваться для ручного назначения изнутри контейнеров.
Добавляем постоянную сеть и включаем для неё автозапуск при старте системы:
$ sudo virsh net-define /tmp/lxc-network.xml
Network lxc-network defined from /tmp/lxc-network.xml
$ sudo virsh net-autostart lxc-network
Network lxc-network marked as autostarted
Файл /tmp/lxc-network.xml
больше не нужен и его можно спокойно удалить.
Проверяем, что сеть добавилась:
$ sudo virsh net-list --all
Name State Autostart Persistent
--------------------------------------------------
default inactive no yes
lxc-network inactive yes yes
И запускаем:
$ sudo virsh net-start lxc-network
Network lxc-network started
Проверяем, что сеть запустилась и что соответствующий интерфейс (virbrlxc0) поднялся:
$ sudo virsh net-list
Name State Autostart Persistent
------------------------------------------------
lxc-network active yes yes
$ ip addr show virbrlxc0
4: virbrlxc0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000
link/ether 52:54:00:6e:53:fa brd ff:ff:ff:ff:ff:ff
inet 10.10.45.1/24 brd 10.10.45.255 scope global virbrlxc0
valid_lft forever preferred_lft forever
Меняем дефолтный конфиг LXC, это файл /etc/lxc/default.conf
, прописываем в него следующее (вместо строчки lxc.net.0.type = empty
):
lxc.net.0.type = veth
lxc.net.0.flags = up
lxc.net.0.link = virbrlxc0
Теперь все новые контейнеры будут создаваться с такой сетью.
Если вы хотите добавить в уже существующий контейнер, откройте его конфиг (для нашего примера он находится в файле /var/lib/lxc/myfirstcontainer/config
) и пишем в него вместо строчки lxc.network.type = empty
:
lxc.network.type = veth
lxc.network.flags = up
lxc.network.link = virbrlxc0
lxc.network.hwaddr = 00:FF:AA:00:00:01
lxc.network.ipv4 = 0.0.0.0/24
Останавливаем и снова запускаем контейнер, заходит внутрь и убеждаемся, что сеть есть (адрес выделился автоматически из указанного ранее диапазона 10.10.45.101 ÷ 10.10.45.254):
$ sudo lxc-attach -n ubuntu-18.04
root@ubuntu-18:/# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
6: eth0@if7: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether 3e:aa:76:f4:07:45 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 10.10.45.209/24 brd 10.10.45.255 scope global dynamic eth0
valid_lft 3490sec preferred_lft 3490sec
inet6 fe80::3caa:76ff:fef4:745/64 scope link
valid_lft forever preferred_lft forever
Теперь можно как минимум apt-get update
сделать.
Поддержка и обслуживание¶
Дальше команды россыпью для сопровождения 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
Потом ещё допишу, если какие идеи или проблемы возникнут.
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 и проверка
-
cgroup расшифровывается как control group, подробнее — в википедии. ↩
-
Я сделал шаблон на основе файла из стандартного пакета
lxc
, а помимо выбора архитектуры также включил в него установку некоторых дополнительных приложений (например, vim, file и других). ↩
Спасибо за статью. Как пробросить 22 порт ssh'a через NAT не подскажите?
Без внешнего сервиса, думаю, никак.
Отличная статья. Но как всегда есть недочет. И хочется узнать где создается файл lxc-network.xml а то совсем запутался. И какие еще варианты настройки сети возможны....