Expertus metuit
LXC в Debian
2014-01-23 11:10
Теги: debian, linux, kb

Не нашёл ни одной вменяемой инструкции по разворачиванию LXC на debian-хосте, поэтому пишу свою (на основе других статей, список которых в самом конце документа). Все инструкции рассчитаны на Debian Stable (Debian 8 jessie на момент написания статьи) и версию lxc 1.0.7.

LXC (LinuX Containers, http://linuxcontainers.org/) — это система виртуализации на уровне операционной системы, по сути нечто вроде продвинутого chroot. Удобно использовать для разработки и тестирования софта. Здесь рассматривается работа с lxc только средствами пакета lxc, а другие — например, через libvirt — нет.

Устанавливается традиционно (далее следую традиционному соглашению: если команда начинается с символа #, то она выполняется с правами суперюзера; если начинается с % — с правами обычного юзера; строчки без такого символа в начале являются выводом команды):

# apt-get install lxc

После установки проверяем:

# lxc-checkconfig 
Kernel configuration not found at /proc/config.gz; searching...
Kernel configuration found at /boot/config-3.16.0-4-amd64
--- Namespaces ---
Namespaces: enabled
Utsname namespace: enabled
Ipc namespace: enabled
Pid namespace: enabled
User namespace: enabled
Network namespace: enabled
Multiple /dev/pts instances: enabled

--- Control groups ---
Cgroup: enabled
Cgroup 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
Macvlan: enabled
Vlan: enabled
File capabilities: enabled

Note : Before booting a new kernel, you can check its configuration
usage : CONFIG=/path/to/config /usr/bin/lxc-checkconfig

Иногда вы можете увидеть в этом выводе User namespace: missing, но сделать с этим ничего нельзя, придётся так жить, если не хотите пересобирать ядро и отказываться от XFS, в новых ядрах проблема уже исправлена.

Дальше устанавливаем другие нужные пакеты:

# apt-get install debootstrap

Следующий шаг опциональный, он нужен, только если команда mount | grep cgroup не возвращает ничего.

Дописываем в /etc/fstab строчку для автоматического монтирования файловой системы cgroup1 (и сразу же монтируем):

# echo "cgroup  /sys/fs/cgroup  cgroup  defaults  0   0" >> /etc/fstab
# mount /sys/fs/cgroup

Теперь можно создавать контейнеры (указываем название контейнера в аргументе -n и название шаблона в аргументе -t):

# 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

А вот так можно создать контейнер с убунтой 12.04 и архитектурой i386 (в шаблоне для убунты выбор архитектуры есть):

# lxc-create -n ubuntu-12.04-i386-sample -t ubuntu -- -r precise -a i386

Стандартные шаблоны лежат в каталоге /usr/share/lxc/templates/.

Сами контейнеры создаются в каталоге /var/lib/lxc/, в нём по одному каталогу для каждого контейнера, имя каталога совпадает с названием контейнера.

А вот команда для создания контейнера с Debian Jessie на архитектуре i386:

# lxc-create -n i386-debian-jessie -t debian -- -r jessie -a i386

Когда контейнер создан, вам могут показать пароль для него:

Root password is '45vHBQ/M', please change !

Контейнер создан, можно его запускать (не забудьте флаг -d, он нужен для запуска контейнера в виде демона, иначе попытки выхода из vim покажутся вам сказкой по сравнению с ЭТИМ):

# lxc-start -d -n myfirstcontainer

К запущенному контейнеру можно подключиться так:

lxc-console -n myfirstcontainer

Пароль для юзера root по умолчанию тоже root (если не было сообщения о специально установленном случайном пароле).

Выйти из консоли можно по хоткею Ctrl+a q (то есть нажать сначала Ctrl+a, а затем q).

Остановка контейнера:

# lxc-stop -n myfirstcontainer

Полное уничтожение контейнера:

# lxc-destroy -n myfirstcontainer

Настройка сети

По умолчанию контейнер создаётся совсем без поддержки внешней сети, внутри нет никаких сетевых интерфейсов кроме lo, так что сейчас будем настраивать сеть. Для lxc есть несколько вариантов сети, здесь пока только один рассмотрим — через libvirt.

Сначала ставим нужные пакеты:

# apt-get install libvirt-bin

Проверяем, что libvirt вообще работает (здесь и далее пользуемся программой управления virsh):

# virsh net-list --all
 Name                 State      Autostart     Persistent
----------------------------------------------------------
 default              active     no            yes

# virsh net-info default
Name            default
UUID            7bfe224a-eb91-4fb1-8227-b519ef5d23bc
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) будут использоваться для ручного назначения изнутри контейнеров.

Добавляем постоянную сеть и включаем для неё автозапуск при старте системы:

# virsh net-define /tmp/lxc-network.xml
Network lxc-network defined from /tmp/lxc-network.xml
# virsh net-autostart lxc-network
Network lxc-network marked as autostarted

Проверяем, что сеть добавилась:

# virsh net-list --all         
 Name                 State      Autostart     Persistent
----------------------------------------------------------
 default              inactive   no            yes
 lxc-network          inactive   yes           yes

И запускаем:

# virsh net-start lxc-network
Network lxc-network started

Проверяем, что сеть запустилась и что соответствующий интерфейс (virbrlxc0) поднялся:

# virsh net-list             
 Name                 State      Autostart     Persistent
----------------------------------------------------------
 lxc-network          active     yes           yes

# ip addr show virbrlxc0
23: virbrlxc0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default 
    link/ether 52:14:15:16:17:18 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

Теперь нужно добавить его в контейнер, для этого открываем его конфиг (для нашего примера он находится в файле /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.2 ÷ 10.10.45.100):

# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default 
    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: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:ff:aa:00:00:01 brd ff:ff:ff:ff:ff:ff
    inet 10.10.45.110/24 brd 10.10.45.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::2ff:aaff:fe00:1/64 scope link 
       valid_lft forever preferred_lft forever

Теперь можно как минимум apt-get update сделать.

Поддержка и обслуживание

Дальше команды россыпью для сопровождения lxc-виртуалок.

Список всех виртуалок

# 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

Примечания

История изменений

  • 2014-01-23 — первая версия
  • 2015-05-05 — актуализация и проверка работоспособности примеров

  1. cgroup расшифровывается как control group, подробнее — в википедии

  2. Я сделал шаблон на основе файла из стандартного пакета lxc, а помимо выбора архитектуры также включил в него установку некоторых дополнительных приложений (например, vim, file и других). 

Комментарии

serg | 2014-04-19 в 09:39

Отличная статья. Но как всегда есть недочет. И хочется узнать где создается файл lxc-network.xml а то совсем запутался. И какие еще варианты настройки сети возможны....

Максим | 2015-08-29 в 06:00

Спасибо за статью. Как пробросить 22 порт ssh'a через NAT не подскажите?

| 2015-08-29 в 13:49

Без внешнего сервиса, думаю, никак.

Текст комментария (разметка: *курсив*, **полужирная**, [ссылка](http://example.com) или <http://example.com> ещё)
Имя (обязательно, 50 символов или меньше)
Email, на который получать ответы (не будет опубликован)
Веб-сайт
© 2006—2016 Sergey Stolyarov | Работает на Pyrone