Захотелось странного.
Во-первых, взгромоздить кучу виртуальных машин прямо на свой ноутбук.
А во-вторых, раскурить одну виртуализацию внутри другой.
Речь пойдет про использование контейнеров LXC, причем внутри другой виртуальной машины.
Прежде всего, для экспериментов с различными инструментами:
При этом хочется иметь доступ к этой лаборатории всегда, вне зависимости от доступности интернета. Ну почему бы где-нибудь в дороге не раскурить какой-нибудь Hadoop? :-)
Думаю, эта заметка будет полезна как тем, у кого на десктопе Windows или Mac OS X, так и тем, у кого Linux (часть про LXC).
Запустить на среднем ноутбуке 10-20 виртуальных машин, которые
– могут ходить в интернет (через NAT)
– видят друг друга и хост-компьютер (то есть, наш ноут)
– доступны с хост-компьютера (то есть по ssh можно зайти на любую из этих виртуальных машин)
Собственно, на этом можно было бы поставить точку.
Ниже приведена просто пошаговая шпаргалка (использовался Ubuntu), как все это настроить быстро.
Здесь особо и описывать нечего.
После установки системы — не забыть поставить Guest Additions.
У виртуальной машины должно быть два сетевых интерфейса:
Важно! Нужно разрешить «Promiscuous mode» («Неразборчивый режим») на Host-only интерфейсе. Это позволит контейнерам видеть хост-машину и друг друга.
В гостевой системе нужно сконфигурировать bridge-интерфейсы. Они нам потребуются для работы сети в контейнерах. Для этого нужно установить пакет bridge-utils (
Должно получиться что-то похожее:
IP-адрес на br0 (eth0) пусть назначается самим VirtualBox-ом по DHCP, нам этот адрес и знать-то не нужно. А на br1 (eth1) назначим IP-адрес руками — так удобнее, потом на него по ssh будем ходить с хост-машины.
Перезапускаем виртуальную машину чтобы убедиться, что оба интерфейса внутри виртуальной машины поднимаются, сама виртуальная машина доступна по адресу 192.168.56.2 (через Host-only интерфейс) и внутри неё доступен интернет (через NAT-интерфейс).
Для работы LXC-контейнеров нужна служебная файловая система cgroup. Точка монтирования не важна - можно смонтировать куда угодно.
Добавляем строчку в /etc/fstab:
и монтируем
Пакет lxc содержит утилиты для управления и скрипты для создания контейнеров. Пакет debootstrap — это утилита, которая скачивает нужные пакеты и разворачивает минимальную базовую систему (ubuntu или debian). Кроме того, есть пакет febootstrap — он скачивает и разворачивает Fedora.
В каталоге /usr/lib/lxc/templates/ есть файлы вида
Создаем контейнер (c Ubuntu 11.04)
Наш контейнер появится в каталоге /var/lib/lxc/node01/.
Во создаваемом окружении у пользователя root пароль "root". Не забудьте поменять!
В конфигурационном файле контейнера не хватает параметров сети – их нужно добавить руками. Потом можно будет использовать шаблонный конфиг или просто клонировать контейнер.
Открываем файл
и добавляем такие строчки (ставим нужные нам MAC- и IP-адреса):
Здесь
Рекомендую устанавливать MAC-адрес и IP-адрес вручную. Это делать не обязательно, но удобно. Например, когда нужно послушать сетевой трафик. Я во всех номерах ставлю одинаковую последнюю цифру (node01 – 10.0.2.101 – ac:de:48:00:00:01).
Обратите внимание, файл конфигурации интерфейсов /etc/network/interfaces внутри контейнера не нужно трогать. Интерфейсы достаточно настроить снаружи.
Добавляем что-нибудь осмысленное в /etc/resolv.conf, чтобы заработал DNS:
Запускаем контейнер
Заходим (root/root) и проверяем, что сеть доступна во все стороны.
Для клонирования контейнеров достаточно скопировать его целиком
и поправить конфигурационные файлы (пути, MAC- и IP-адреса):
В пакет lxc входит скрипт /etc/init.d/lxc, который запускает определенные контейнеры при старте системы. В файле /etc/default/lxc нужно перечислить, какие контейнеры запускать. Этот скрипт ожидает, что конфигурационные файлы контейнеров лежат в /etc/lxc и имеют расширение *.conf.
Я просто наделал симлинков:
Во-первых, взгромоздить кучу виртуальных машин прямо на свой ноутбук.
А во-вторых, раскурить одну виртуализацию внутри другой.
Речь пойдет про использование контейнеров LXC, причем внутри другой виртуальной машины.
WTF! На кой это нужно?
Прежде всего, для экспериментов с различными инструментами:
- Распределенные базы данных, файловые системы, параллельные вычисления и т.д.
- Системы управления инфраструктурой (типа Chef, Puppet, Fabric и т.п.)
- Тестирование и сборка в разных окружениях
- Ваш вариант (пишите в комментариях)
При этом хочется иметь доступ к этой лаборатории всегда, вне зависимости от доступности интернета. Ну почему бы где-нибудь в дороге не раскурить какой-нибудь Hadoop? :-)
Думаю, эта заметка будет полезна как тем, у кого на десктопе Windows или Mac OS X, так и тем, у кого Linux (часть про LXC).
Задача
Запустить на среднем ноутбуке 10-20 виртуальных машин, которые
– могут ходить в интернет (через NAT)
– видят друг друга и хост-компьютер (то есть, наш ноут)
– доступны с хост-компьютера (то есть по ssh можно зайти на любую из этих виртуальных машин)
Решение
- На компьютере (с Windows или Mac OS X) запустить VirtualBox
- Установить на нем Linux
- Внутри Linux-а наделать кучу LXC-контейнеров с независимыми Linux-ами
Собственно, на этом можно было бы поставить точку.
Ниже приведена просто пошаговая шпаргалка (использовался Ubuntu), как все это настроить быстро.
1. Устанавливаем VirtualBox и систему на виртуальную машину
Здесь особо и описывать нечего.
После установки системы — не забыть поставить Guest Additions.
2. Настраиваем сетевые интерфейсы в VirtualBox
У виртуальной машины должно быть два сетевых интерфейса:
- Тип подключения NAT (он создается по умолчанию). Через него наши виртуалки смогут ходить в интернет (например, чтобы скачивать пакеты).
- Тип подключения Host-only networking (по-русски это называется «Виртуальный адаптер хоста»).
Важно! Нужно разрешить «Promiscuous mode» («Неразборчивый режим») на Host-only интерфейсе. Это позволит контейнерам видеть хост-машину и друг друга.
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 |
Перезапускаем виртуальную машину чтобы убедиться, что оба интерфейса внутри виртуальной машины поднимаются, сама виртуальная машина доступна по адресу 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).