Установка и использование контейнеров LXC 1.0 в RHEL/CentOS 6.5

Feb 23, 2014 16:36


Внезапно, чуваки из linuxcontainers.org выкатили LXC-контейнеры версии 1.0.0 готовые, как они утверждают, к промышленной эксплуатации. Разумеется, это надо немедленно проверить и, разумеется, на RHEL/CentOS 6.5. Для этого соберём lxc-1.0.0 из исходников, так как в репозитории EPEL для RHEL/CentOS доступна только версия lxc-0.9.0-2.el6.

[дополнение от 18.11.2015] Это было верно на момент написания статьи. Сейчас в репозитории EPEL для RHEL/CentOS 6/7 доступен пакет lxc-1.0.7-4.

Которые не в курсе, что такое LXC-контейнеры, тем поясняем, что это такой OpenVZ, только построенный на namespaces и cgroups ядра Linux, то есть для использования их не нужно специальное openvz-ядро, так как нужные фичи были добавлены в mainline ядро. Которые не в курсе, что такое OpenVZ, тем поясняем, что это такой тип виртуализации, посередине между chroot и KVM (или Xen, или VMWare, или VirtualBox), когда процессы контейнера (гостя) бегут на том же ядре, что и основная система, но изолированы от неё средствами namespaces и cgroups. Такой тип виртуализации отличается от KVM/Xen, которые эмулируют для гостя железо сервера целиком и гость использует своё собственное ядро. Которые не в курсе, что такое вышеупомянутые chroot, KVM, namespaces и cgroups - тем пичалька.

Итак, предположим у нас есть свежий минимальный Red Hat Enterprise Linux или CentOS 6.5. Нам надо установить компилятор, auto-tools, вот это всё для, собственно, сборки LXC из исходников. Проще всего для этого установить группу Development tools целиком. Также понадобится пакет libcap-devel для сборки LXC с поддержкой capabilities, пакет busybox для шаблона busybox и пакет bridge-utils для управления бриджами (bridge).

[root@serv ~]# yum groupinstall 'Development tools' [root@serv ~]# yum install libcap-devel busybox bridge-utils
Если собрать LXC без поддержки capabilities (библиотеки libcap), то он ругнётся о невозможности их сбросить при старте контейнера вот таким образом:

[root@serv ~]# lxc-start -n test1 lxc-start: unknown capability mac_admin lxc-start: failed to drop capabilities lxc-start: failed to setup the container
Скачиваем исходники lxc-1.0.0 в куда-нибудь, распаковываем, собираем их с правильными путями и устанавливаем:

[root@serv ~]# wget http://linuxcontainers.org/downloads/lxc-1.0.0.tar.gz ...качаем... 2066-66-66 66:66:66 (1.2 MB/s) - “lxc-1.0.0.tar.gz” saved [779679/779679] [root@serv ~]# tar -xf lxc-1.0.0.tar.gz [root@serv ~]# cd lxc-1.0.0 [root@serv lxc-1.0.0]# ./autogen.sh + test -d autom4te.cache + aclocal -I config + autoheader + autoconf + automake --add-missing --copy [root@serv lxc-1.0.0]# ./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var ...много всего... Environment: - compiler: gcc - distribution: centos - init script type(s): sysvinit - rpath: no - GnuTLS: no - Bash integration: yes Security features: - Apparmor: no - Linux capabilities: yes - seccomp: no - SELinux: no - cgmanager: no Bindings: - lua: no - python3: no Documentation: - examples: yes - API documentation: yes - user documentation: no Debugging: - tests: no - mutex debugging: no Paths: - Logs in configpath: no [root@serv lxc-1.0.0]# make ...много всего... [root@serv lxc-1.0.0]# make install ...много всего...
После установки библиотек LXC необходимо запустить ldconfig, чтобы перестроить библиотечный кэш, иначе все бинарники LXC будут ругаться:

[root@serv lxc-1.0.0]# lxc-ls lxc-ls: error while loading shared libraries: liblxc.so.1: cannot open shared object file: No such file or directory [root@serv lxc-1.0.0]# ldconfig [root@serv lxc-1.0.0]# lxc-ls
Далее, для запуска контейнера кроме самого LXC нам нужна rootfs - корневая файловая система той операционной системы, которая будет запускаться в контейнере. Cамый простой способ - это хранить файловые системы контейнера как файлы в обычных директориях, по умолчанию путь к ним /var/lib/lxc/имя-контейнера/rootfs/. Также LXC умеет хранить rootfs в подтомах (subvolume) btrfs, в логическом томе (logical volume) LVM, в overlayfs и, внезапно, в подтомах zfs. Для создания rootfs какой-нибудь операционной системы существуют шаблоны (templates) - это (чаще всего) shell-скрипты, которые копируют откуда-нибудь (например, скачивают из интернетов) архив или файлы соответствующей корневой файловой системы и меняют конфигурационные файлы системы для работы внутри контейнера. Для каждого типа операционной системы - свой шаблон, они все разные и не все правильно работают. Шаблоны лежат по-умолчанию в /usr/share/lxc/templates/ (при использовании --prefix=/usr в ./configure):

[root@serv ~]# ls /usr/share/lxc/templates/ lxc-alpine lxc-centos lxc-fedora lxc-oracle lxc-ubuntu-cloud lxc-altlinux lxc-cirros lxc-gentoo lxc-plamo lxc-archlinux lxc-debian lxc-openmandriva lxc-sshd lxc-busybox lxc-download lxc-opensuse lxc-ubuntu
Используем самый простой шаблон busybox чтобы проверить можем ли мы вообще стартовать контейнер. Контейнер максимально прост, так как используется один выполнимый файл busybox для всего, включая init. Создаём контейнер с помощью команды lxc-create -t имя-шаблона -n имя-контейнера и запускаем (пытаемся запустить) с помощью lxc-start -n имя-контейнера

[root@serv ~]# lxc-create -t busybox -n busytest setting root password to "root" Password for 'root' changed [root@serv ~]# lxc-start -n busytest lxc-start: failed to attach 'vethX6WD9V' to the bridge 'virbr0' : No such device lxc-start: failed to create netdev lxc-start: failed to create the network lxc-start: failed to spawn 'busytest'
Внезапно, нифига! Строчка «failed to attach … to the bridge … : No such device» как бы говорит нам, что контейнер хочет прицепить свой сетевой интерфейс к бриджу virbr0, которого у нас нет. Делать это заставляет конфиг контейнера, который лежит в /var/lib/lxc/имя-контейнера/config и в котором, в частности, написано:

[root@serv usr]# cat /var/lib/lxc/busytest/config ... lxc.network.type = veth lxc.network.flags = up lxc.network.link = virbr0 lxc.rootfs = /usr/lib/lxc/busytest/rootfs
Итак, надо создать бридж virbr0. К этому бриджу должен быть привязан интерфейс на хосте, позволяющий выход в локальную сеть или интернеты, если контейнер должен иметь к ним доступ. Ну или нет, если нет. Настройка бриждей и сети выходит за рамки этой статьи, далее описан простейший случай с интрефейсом eth1 смотрящим в локальную сеть и получающим IP с внешнего DHCP. Создаём простые конфиги для бриджа и интерфейса (не забудьте подставить ваш MAC-адрес) и поднимаем бридж (ну, или перезагружаемся):

[root@serv ~]# cat /etc/sysconfig/network-scripts/ifcfg-eth1 DEVICE=eth1 HWADDR=66:66:66:66:66:66 TYPE=Ethernet BRIDGE=virbr0 ONBOOT=yes [root@serv ~]# cat /etc/sysconfig/network-scripts/ifcfg-virbr0 DEVICE=virbr0 TYPE=Bridge BOOTPROTO=dhcp IPV6INIT=no ONBOOT=yes [root@serv ~]# ifup eth1 [root@serv ~]# ifup virbr0 Determining IP information for virbr0... done. [root@serv ~]# ip addr show virbr0 4: virbr0: mtu 1500 qdisc noqueue state UNKNOWN link/ether 66:66:66:66:66:66 brd ff:ff:ff:ff:ff:ff inet 192.166.66.66/24 brd 192.166.66.255 scope global virbr0
Пробуем опять взлететь:

[root@serv lxc-1.0.0]# lxc-start -n busytest lxc-start: cgroupfs failed to detect cgroup metadata lxc-start: failed initializing cgroup support lxc-start: failed to spawn 'busytest'
Внезапно, опять нифига! Что, вообще-то, логично. LXC-контейнеры хотят cgroups, которых у нас и нет. Необходимо смонтировать файловую систему cgroup. Добавляем строчку про cgroups в /etc/fstab, монтируем их, проверяем:

[root@serv lxc-1.0.0]# mkdir -p /cgroup [root@serv lxc-1.0.0]# cat /etc/fstab ... cgroup /cgroup cgroup defaults 0 0 [root@serv lxc-1.0.0]# mount -t cgroup cgroup /cgroup [root@serv lxc-1.0.0]# mount ... cgroup on /cgroup type cgroup (rw)
Пробуем опять взлететь:

[root@serv ~]# lxc-start -n busytest udhcpc (v1.15.1) started Sending discover... Sending select for 192.166.66.67... Lease of 192.166.66.67 obtained, lease time 1800 Please press Enter to activate this console. # uname -a uname -a Linux busytest 2.6.32-431.el6.x86_64 #1 SMP Fri Nov 66 66:66:66 UTC 2066 x86_64 x86_64 x86_64 GNU/Linux # ip addr show eth0 ip addr show eth0 7: eth0: mtu 1500 qdisc pfifo_fast qlen 1000 link/ether 22:a1:c1:83:7b:17 brd ff:ff:ff:ff:ff:ff inet 192.166.66.67/24 brd 192.166.66.255 scope global eth0 # halt halt The system is going down NOW! Sent SIGTERM to all processes Terminated Sent SIGKILL to all processes Requesting system halt
Внезапно, работает. Теперь попробуем создать контейнер с, например, Ubuntu. Его шаблон не работает на RHEL/CentOS, но чуваки с linuxcontainers.org раздают уже подготовленные rootfs для различных операционных систем. Скачивание обеспечивается шаблоном download (размер rootfs от Ubuntu Precise 64bit - примерно 56 Mb), создадим контейнер с его помощью:

[root@serv lxc-1.0.0]# lxc-create -t download -n ubuntu Setting up the GPG keyring Downloading the image index --- DIST RELEASE ARCH VARIANT BUILD --- centos 6 amd64 default 20140222_02:17 centos 6 i386 default 20140222_02:17 debian jessie amd64 default 20140221_22:43 debian jessie armel default 20140220_22:43 debian jessie armhf default 20140220_22:43 debian jessie i386 default 20140221_22:43 debian sid amd64 default 20140221_22:43 debian sid armel default 20140220_22:43 debian sid armhf default 20140219_22:43 debian sid i386 default 20140221_22:43 debian wheezy amd64 default 20140221_22:43 debian wheezy armel default 20140220_22:43 debian wheezy armhf default 20140220_22:43 debian wheezy i386 default 20140221_22:43 fedora 19 amd64 default 20140222_01:28 fedora 19 i386 default 20140222_01:28 fedora 20 amd64 default 20140222_01:28 fedora 20 armhf default 20140222_01:28 fedora 20 i386 default 20140222_01:28 gentoo current amd64 default 20140128_14:35 gentoo current armhf default 20140128_14:35 gentoo current i386 default 20140128_14:35 oracle 6.5 amd64 default 20140222_11:41 oracle 6.5 i386 default 20140222_11:41 plamo 5.x amd64 default 20140221_21:37 plamo 5.x i386 default 20140221_21:37 ubuntu lucid amd64 default 20140222_03:50 ubuntu lucid i386 default 20140222_03:50 ubuntu precise amd64 default 20140222_03:50 ubuntu precise armel default 20140222_03:50 ubuntu precise armhf default 20140222_03:50 ubuntu precise i386 default 20140222_03:50 ubuntu quantal amd64 default 20140222_03:50 ubuntu quantal armel default 20140222_03:50 ubuntu quantal armhf default 20140222_03:50 ubuntu quantal i386 default 20140222_03:50 ubuntu saucy amd64 default 20140222_03:50 ubuntu saucy armhf default 20140222_03:50 ubuntu saucy i386 default 20140222_03:50 ubuntu trusty amd64 default 20140222_03:50 ubuntu trusty armhf default 20140222_03:50 ubuntu trusty i386 default 20140222_03:50 --- Distribution: ubuntu Release: precise Architecture: amd64 Downloading the image index Downloading the rootfs Downloading the metadata The image cache is now ready Unpacking the rootfs --- You just created an Ubuntu container (release=precise, arch=amd64). The default username/password is: ubuntu / ubuntu To gain root privileges, please use sudo.
Запускаем контейнер:

[root@serv ~]# lxc-start -n ubuntu ...много всего... <4>init: failsafe main process (128) killed by TERM signal <4>init: setvtrgb main process (381) terminated with status 1 Ubuntu 12.04.4 LTS ubuntu console ubuntu login: ubuntu Password: Welcome to Ubuntu 12.04.4 LTS (GNU/Linux 2.6.32-431.el6.x86_64 x86_64) ubuntu@ubuntu:~$ ip addr show eth0 11: eth0: mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether d6:64:e3:b6:4e:43 brd ff:ff:ff:ff:ff:ff inet 192.166.66.68/24 brd 192.166.66.255 scope global eth0
Контейнер запущен, к нему можно покдлючится по SSH с хоста или из локальной сети. Обычно контейнер запускают в фоне:

lxc-start -n имя-контейнера -d
К консоли контейнера можно присоединится (ctrl-a + q для отсоединения):

lxc-console -n имя-контейнера
Можно запустить шелл напрямую в контейнере, минуя логин:

lxc-attach -n имя-контейнера
Можно узнать некоторую информацию о контейнере, включая его IP адрес:

lxc-info -n имя-контейнера
Можно остановить контейнер как из самого контейнера (shutdown -h, halt) или корректно остановить контейнера из хоста:

lxc-stop -n имя-контейнера
Если контейнер завис, можно грубо убить контейнера из хоста (убивается init-процесс контейнера):

lxc-stop -n имя-контейнера -k
Можно получить список всех созданных (запущеных и остановленых) контейнеров в системе:

lxc-ls
Ну, как-то так. Вообще, LXC контейнеры - обширная тема и явно не помещается в одну статью. Вот тут некоторый товарищ опубликовал перевод цикла статей по LXC одного из главных мантейнеров, локальная копия также сохранена на всякий случай.

Пыщь! Оригинал поста размещен в блоге Ад, ненависть и локалхост. Комментить? Набигай. Подкат? ОИНЧ.
Previous post Next post
Up