Pull to refresh

Кластер, который всегда с собой

Reading time 5 min
Views 39K
lxcЗахотелось странного.
Во-первых, взгромоздить кучу виртуальных машин прямо на свой ноутбук.
А во-вторых, раскурить одну виртуализацию внутри другой.

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



WTF! На кой это нужно?


Прежде всего, для экспериментов с различными инструментами:
  • Распределенные базы данных, файловые системы, параллельные вычисления и т.д.
  • Системы управления инфраструктурой (типа Chef, Puppet, Fabric и т.п.)
  • Тестирование и сборка в разных окружениях
  • Ваш вариант (пишите в комментариях)

При этом хочется иметь доступ к этой лаборатории всегда, вне зависимости от доступности интернета. Ну почему бы где-нибудь в дороге не раскурить какой-нибудь Hadoop? :-)

Думаю, эта заметка будет полезна как тем, у кого на десктопе Windows или Mac OS X, так и тем, у кого Linux (часть про LXC).


Задача


Запустить на среднем ноутбуке 10-20 виртуальных машин, которые
    – могут ходить в интернет (через NAT)
    – видят друг друга и хост-компьютер (то есть, наш ноут)
    – доступны с хост-компьютера (то есть по ssh можно зайти на любую из этих виртуальных машин)


Решение


  1. На компьютере (с Windows или Mac OS X) запустить VirtualBox
  2. Установить на нем Linux
  3. Внутри Linux-а наделать кучу LXC-контейнеров с независимыми Linux-ами

Собственно, на этом можно было бы поставить точку.
Ниже приведена просто пошаговая шпаргалка (использовался Ubuntu), как все это настроить быстро.



1. Устанавливаем VirtualBox и систему на виртуальную машину


Здесь особо и описывать нечего.
После установки системы — не забыть поставить Guest Additions.


2. Настраиваем сетевые интерфейсы в VirtualBox


У виртуальной машины должно быть два сетевых интерфейса:
  • Тип подключения NAT (он создается по умолчанию). Через него наши виртуалки смогут ходить в интернет (например, чтобы скачивать пакеты).
  • Тип подключения Host-only networking (по-русски это называется «Виртуальный адаптер хоста»).
Для того чтобы добавить Host-only интерфейс сначала идем в общие настройки Virtualbox и добавляем Host-only адаптер на хостовой машине. Затем в конфигурации виртуальной машины добавляем второй интерфейс.

Важно! Нужно разрешить «Promiscuous mode» («Неразборчивый режим») на Host-only интерфейсе. Это позволит контейнерам видеть хост-машину и друг друга.

Virtual box - Promiscuous mode


3. Настраиваем сетевые интерфейсы


В гостевой системе нужно сконфигурировать bridge-интерфейсы. Они нам потребуются для работы сети в контейнерах. Для этого нужно установить пакет bridge-utils (# apt-get install bridge-utils) и внести изменения в файл /etc/network/interfaces (см. man bridge-utils-interfaces).
Должно получиться что-то похожее:
Было Стало
auto eth0
iface eth0 inet dhcp
auto br0
iface br0 inet dhcp
    bridge_ports eth0
    bridge_fd 0

auto br1
iface br1 inet static
    address 192.168.56.2
    netmask 255.255.255.0
    bridge_ports eth1
    bridge_fd 0
IP-адрес на br0 (eth0) пусть назначается самим VirtualBox-ом по DHCP, нам этот адрес и знать-то не нужно. А на br1 (eth1) назначим IP-адрес руками — так удобнее, потом на него по ssh будем ходить с хост-машины.

Перезапускаем виртуальную машину чтобы убедиться, что оба интерфейса внутри виртуальной машины поднимаются, сама виртуальная машина доступна по адресу 192.168.56.2 (через Host-only интерфейс) и внутри неё доступен интернет (через NAT-интерфейс).


4. Монтируем файловую систему cgroup


Для работы LXC-контейнеров нужна служебная файловая система cgroup. Точка монтирования не важна - можно смонтировать куда угодно.

Добавляем строчку в /etc/fstab:
cgroup  /var/local/cgroup  cgroup  defaults  0  0

и монтируем
mkdir /var/local/cgroup
mount cgroup
В Ubuntu 11.10 (oneiric) cgroup руками монтировать не нужно. Пакет lxc зависит от пакета cgroup-lite, который монтирует cgroup в /sys/fs/cgroup/

5. Устанавливаем пакеты для работы с LXC


apt-get install lxc
apt-get install debootstrap

Пакет lxc содержит утилиты для управления и скрипты для создания контейнеров. Пакет debootstrap — это утилита, которая скачивает нужные пакеты и разворачивает минимальную базовую систему (ubuntu или debian). Кроме того, есть пакет febootstrap — он скачивает и разворачивает Fedora.
Самый быстрый способ изучить lxc: набрать lxc- и нажать два раза "Tab"

6. Создаем первый LXC-контейнер


В каталоге /usr/lib/lxc/templates/ есть файлы вида lxc-debian, lxc-natty, lxc-oneiric, lxc-fedora и т.п. Это так называемые «шаблоны». На самом деле это скрипты, которые создают соответствующее рабочее окружение.

Создаем контейнер (c Ubuntu 11.04)
lxc-create -n node01 -t natty

Наш контейнер появится в каталоге /var/lib/lxc/node01/.
Во создаваемом окружении у пользователя root пароль "root". Не забудьте поменять!
В Ubuntu 11.10 (oneiric) пакет lxc посвежее: шаблону "ubuntu" можно передать параметры, в том числе желаемую версию дистрибутива. Чтобы узнать, какие параметры принимает шаблон, выполните lxc-create --template ubuntu --help

7. Настраиваем сеть в контейнере


7.1. Сетевые интерфейсы


В конфигурационном файле контейнера не хватает параметров сети – их нужно добавить руками. Потом можно будет использовать шаблонный конфиг или просто клонировать контейнер.

Открываем файл
vi /var/lib/lxc/node01/config

и добавляем такие строчки (ставим нужные нам MAC- и IP-адреса):
lxc.network.type = veth
lxc.network.flags = up
lxc.network.link = br0        <- это реальный интерфейс
lxc.network.name = eth0       <- это интерфейс внутри контейнера
lxc.network.hwaddr = ac:de:48:00:00:01
lxc.network.ipv4 = 10.0.2.101/24

lxc.network.type = veth
lxc.network.flags = up
lxc.network.link = br1
lxc.network.name = eth1
lxc.network.hwaddr = ac:de:48:00:ff:01
lxc.network.ipv4 = 192.168.56.101/24

Здесь 10.0.2.101/24 – это сеть, которая обычно используется для NAT-интерфейсов в VirtualBox. Через этот интерфейс контейнер будет выходить в интернет.
192.168.56.101/24 – это наша Host-Only сеть. Через этот интерфейс контейнер будет общаться с локальной сетью и другими контейнерами.

Рекомендую устанавливать MAC-адрес и IP-адрес вручную. Это делать не обязательно, но удобно. Например, когда нужно послушать сетевой трафик. Я во всех номерах ставлю одинаковую последнюю цифру (node01 – 10.0.2.101 – ac:de:48:00:00:01).

Обратите внимание, файл конфигурации интерфейсов /etc/network/interfaces внутри контейнера не нужно трогать. Интерфейсы достаточно настроить снаружи.


7.2. DNS в контейнере


Добавляем что-нибудь осмысленное в /etc/resolv.conf, чтобы заработал DNS:
echo "nameserver 8.8.8.8" > /var/lib/lxc/node01/rootfs/etc/resolv.conf
Для локального разрешения адресов можно обойтись /etc/hosts. Файл /etc/hosts можно сделать общим для всех контейнеров, если смонтировать его с опцией bind.


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


Запускаем контейнер
lxc-start --logfile /tmp/lxc-node01.log --logpriority DEBUG --name node01

Заходим (root/root) и проверяем, что сеть доступна во все стороны.
Чтобы запустить контейнер в фоновом режиме надо добавить ключ "--daemon"

9. Клонируем контейнеры


Для клонирования контейнеров достаточно скопировать его целиком
cp -a node01 node02

и поправить конфигурационные файлы (пути, MAC- и IP-адреса):
vi node02/config
vi node02/fstab
vi node02/rootfs/etc/hostname
Начиная с версии lxc 0.7.5 появилась утилита lxc-clone. Она корректно правит пути и hostname, но IP-адреса все равно нужно отредактировать руками

10. Автозапуск контейнеров


В пакет lxc входит скрипт /etc/init.d/lxc, который запускает определенные контейнеры при старте системы. В файле /etc/default/lxc нужно перечислить, какие контейнеры запускать. Этот скрипт ожидает, что конфигурационные файлы контейнеров лежат в /etc/lxc и имеют расширение *.conf.
Я просто наделал симлинков:
/var/lib/lxc/nodeXX/config -> /etc/lxc/nodeXX.conf


11. Как еще можно облагородить эту кухню


  • Написать скрипты, которые автоматизируют рутину по созданию контейнеров (шаблонный конфиг, установка IP-адресов, создание пользователей, настройка ssh по ключам и т.п.)
  • Установить прокси apt-cacher-ng, чтобы не качать одни и те же пакеты по нескольку раз
  • Смонтировать каталоги и файлы (с помощью опции bind), так чтобы некоторые файлы были общими
  • Поставить контейнеры под управление libvirt (Я не пробовал. Возможно, это тема для отдельной заметки)
  • Попробовать aufs для запуска “наложенных” (overlay) контейнеров, когда неизменяемые файлы могут быть общими для всех контейнеров (а также утилиту lxc-start-ephemeral).
Tags:
Hubs:
+121
Comments 58
Comments Comments 58

Articles