22.05.2011

Настройка и использование виртуального контейнера LXC в Squeeze

Виртуальные контейнеры эта такая очень полезная для повседневной жизни штука. Технология сия позволяет создать "полностью" изолированное linux-based окружение без потери производительности на виртуализацию и прочие накладные расходы. Для чего? А вот понадобилось, например проверить работу новой версии софтины и не убить основную рабочую конфигурацию - копируй контейнер и работай с копией. Хочется масштабируемость предусмотреть, ресурсы одного физического сервера попилить разными долями для разных задач, или обеспечить высокодоступный сервис - пожалуйста, все есть. Конечно, есть всякие полноценные виртуальные окружения - KVM, Xen, ВМТварь и, даже, прости Господи, Гипер-В. Но теплый ламповый "chroot на стероидах" как-то ближе для внутреннего использования.



LXC призван заменить собой вполне рабочее решение OpenVZ, и пока несколько не дотягивает по изолированности до последнего, однако решение достаточно обкатанное для использования в промышленных масштабах и признано наиболее перспективным.

В Debian Squeezee создания виртуальных контейнеров проходит в три этапа:
  1. Подготовка системы-хоста
  2. Создание контейнера из шаблона
  3. Настройка контейнера и дальнейшее использование.

Подготовка системы-хоста

1. Установка пакетов
aptitude install lxc bridge-utils debootstrap


2. Настроим cgroup
mkdir -p /cgroup
echo "cgroup /cgroup cgroup defaults 0 0" >> /etc/fstab
mount -a

3. Если нам нужно иметь доступ к сети из виртуалок, необходимо изменить конфигурацию сети. Пропишем основной интерфейс в /etc/network/interfaces следующим образом, заменив встретившиеся eth0 на br0:
auto br0
iface br0 inet dhcp
    bridge_ports eth0
    bridge_fd 0
    bridge_maxwait 0

и перезагрузим сеть
invoke-rc.d networking restart

Создание контейнера из шаблона

Это было бы самым простым действием, если бы не одно "но" - по-умолчанию версия lxc в дистрибутиве sqeeze умеет создавать контейнеры только с lenny! Исправить сие не только можно, но и нужно! Для этого необходимо

1. Взять следующий дифф-патч и сохранить его на сервере в файле lxc-debian-squeeze.diff (сделан на основе последней версии lxc из репозитория)

--- lxc-debian  2011-05-22 02:22:36.000000000 +0400
+++ lxc-debian-squeeze  2011-05-22 02:22:26.000000000 +0400
@@ -25,6 +25,14 @@
     rootfs=$1
     hostname=$2

+    # squeeze only has /dev/tty and /dev/tty0 by default,
+    # therefore creating missing device nodes for tty1-4.
+    for tty in $(seq 1 4); do
+       if [ ! -e $rootfs/dev/tty$tty ]; then
+           mknod $rootfs/dev/tty$tty c 4 $tty
+       fi
+    done
+
     # configure the inittab
     cat <<EOF > $rootfs/etc/inittab
 id:3:initdefault:
@@ -65,14 +73,15 @@

     # reconfigure some services
     if [ -z "$LANG" ]; then
-       chroot $rootfs locale-gen en_US.UTF-8
+       chroot $rootfs locale-gen en_US.UTF-8 UTF-8
        chroot $rootfs update-locale LANG=en_US.UTF-8
     else
-       chroot $rootfs locale-gen $LANG
+       chroot $rootfs locale-gen $LANG $(echo $LANG | cut -d. -f2)
        chroot $rootfs update-locale LANG=$LANG
     fi

     # remove pointless services in a container
+    chroot $rootfs /usr/sbin/update-rc.d -f checkroot.sh remove
     chroot $rootfs /usr/sbin/update-rc.d -f umountfs remove
     chroot $rootfs /usr/sbin/update-rc.d -f hwclock.sh remove
     chroot $rootfs /usr/sbin/update-rc.d -f hwclockfirst.sh remove
@@ -90,7 +99,7 @@
 locales,\
 libui-dialog-perl,\
 dialog,\
-dhcp-client,\
+dhcp3-client,\
 netbase,\
 net-tools,\
 iproute,\
@@ -100,23 +109,23 @@
     arch=$2

     # check the mini debian was not already downloaded
-    mkdir -p "$cache/partial-$arch"
+    mkdir -p "$cache/partial-squeeze-$arch"
     if [ $? -ne 0 ]; then
-       echo "Failed to create '$cache/partial-$arch' directory"
+       echo "Failed to create '$cache/partial-squeeze-$arch' directory"
        return 1
     fi

     # download a mini debian into a cache
     echo "Downloading debian minimal ..."
     debootstrap --verbose --variant=minbase --arch=$arch \
-       --include $packages \
-       lenny $cache/partial-$arch http://ftp.debian.org/debian
+       --include=$packages \
+       squeeze "$cache/partial-squeeze-$arch" http://ftp.debian.org/debian
     if [ $? -ne 0 ]; then
        echo "Failed to download the rootfs, aborting."
        return 1
     fi

-    mv "$1/partial-$arch" "$1/rootfs-$arch"
+    mv "$1/partial-squeeze-$arch" "$1/rootfs-squeeze-$arch"
     echo "Download complete."

     return 0
@@ -130,7 +139,7 @@

     # make a local copy of the minidebian
     echo -n "Copying rootfs to $rootfs..."
-    cp -a $cache/rootfs-$arch $rootfs || return 1
+    cp -a "$cache/rootfs-squeeze-$arch" $rootfs || return 1
     return 0
 }

@@ -155,8 +164,8 @@
            arch=i386
        fi

-       echo "Checking cache download in $cache/rootfs-$arch ... "
-       if [ ! -e "$cache/rootfs-$arch" ]; then
+       echo "Checking cache download in $cache/rootfs-squeeze-$arch ... "
+       if [ ! -e "$cache/rootfs-squeeze-$arch" ]; then
            download_debian $cache $arch
            if [ $? -ne 0 ]; then
                echo "Failed to download 'debian base'"
                                                                                     

2. Создать скрипт для шаблона следующими командами:
patch /usr/lib/lxc/templates/lxc-debian lxc-debian-squeeze.diff -o /usr/local/sbin/lxc-debian-squeeze
chmod +x /usr/local/sbin/lxc-debian-squeeze

3. Создание контейнейра
/usr/local/sbin/lxc-debian-squeeze -p /var/lib/lxc/new-container

Настройка контейнера и дальнейшее использование

1. Исправим конфиг
vi /var/lib/lxc/vm0/config

добавив следующие строки:

## custom added lines

## Network support
lxc.utsname = vm0
lxc.network.type = veth
lxc.network.flags = up
lxc.network.link = br0
lxc.network.name = eth0
lxc.network.hwaddr = 00:FF:12:34:56:78
lxc.network.ipv4 = 192.168.0.2/24

## CPU limits
# less value - more priority (default 1024)
lxc.cgroup.cpu.shares = 1024
# list of assigned CPU
lxc.cgroup.cpuset.cpus = 0,1

2. Запускаем контейнер и проверяем его статус

lxc-start -n vm0 -d
lxc-info -n vm0

3. Заходим внутрь контейнера

lxc-console -n vm0 

логин/пароль по-умолчанию root/root. Пароль традиционно рекомендуется сменить.

4. Базовая настройка внутри контейнера (опционально)

 
apt-get install aptitude locales sudo wget console-cyrillic lsb-release \ 
openssl openssl-blacklist openssl-blacklist-extra openssh-client \
openssh-blacklist-extra openssh-blacklist htop vim-tiny less most \
iputils-ping 

при этом в окнах указываем

console-setup -> UTF-8
Cyrillic on Console -> Control+Shift, No temporary switch
реконфигурим локаль
dpkg-reconfigure locales

указать там

en_US.UTF-8 UTF-8
ru_RU.UTF-8 UTF-8

Default locale -> en_US.UTF-8

настроим часовой пояс

dpkg-reconfigure tzdata

и сетевой интерфейс внутри контейнера

vi /etc/network/interfaces

Ссылки
Основная статья на Дебьяновском WIKI
http://blog.foaa.de/2010/05/lxc-on-debian-squeeze/
http://jtrancas.wordpress.com/2011/02/10/debian-squeeze-lxc-template/
http://lucentcode.blogspot.com/2011/03/debian-linux-debootstrap.html
http://unixhome.org.ua/blog/debian/177.html