Содержание статьи
Как насчет того, чтобы поднять работу с VirtualBox на новый уровень — создавать виртуальные машины быстро и целыми пачками, организуя их в сеть? Что, если одним конфигурационным файлом и парой команд создавать простую и воспроизводимую структуру серверов, управляя шарингом папок и перенаправлением портов? Уже интересно?
Введение
Главная страница проекта сообщает, что ему уже выразили доверие такие гиганты мира IT, как Mozilla, Nokia или DISQUS. «Бродяга» (а именно так переводится название проекта) создан в лучших традициях эпохи гитхаба:
- Простой и приятный информативный сайт: www.vagrantup.com.
- Исходный код написан на Ruby и выложен на широкое обозрение: github.com.
- За два года существования он успел обрасти большим количеством дополнений и плагинов на любой вкус.
Установка
Несмотря на то что Vagrant — это всего лишь рубишный гем, создатели предлагают сразу несколько способов установки.
Первый — установка соответствующего операционной системе пакета с downloads.vagrantup.com. Там есть нативные инсталлеры под Windows, OS X и распространенные дистрибутивы Linux (Deb/RPM-пакеты, а также общий инсталлер). Второй — установка соответствующего гема:
$ gem install vagrant
После этого в системе появится новая команда — vagrant. И мы уже готовы создать нашу первую виртуалку:
$ vagrant box add precise64 http://files.vagrantup.com/precise64.box
$ mkdir my_project
$ cd my_project
$ vagrant init precise64
$ vagrant up
Ну вот и все, теперь убедимся в ее работе — проверим ее состояние:
$ vagrant status
Current VM states:
default running
И зайдем по SSH, увидев стандартное приветствие убунты:
$ vagrant ssh
Welcome to Ubuntu 12.04 LTS (GNU/Linux 3.2.0-23-generic x86_64)
* Documentation: https://help.ubuntu.com/
Welcome to your Vagrant-built virtual machine.
Last login: Mon Jan 28 13:51:24 2013 from 10.0.2.2
vagrant@precise64:~$
Базовые сборки
Базовые сборки (base box) — это специальным способом подготовленные шаблоны виртуальных машин, из которых потом создаются непосредственно виртуальные среды вагранта. Дело в том, что для ускорения процесса создания виртуалки он копирует существующую базовую сборку и уже ее настраивает в соответствии с конфигурационным Vagrant-файлом. В результате пользователь, с одной стороны, может не беспокоиться о некоторых нюансах конфигурации виртуалки (например, объеме памяти или сетевых контроллерах), с другой стороны — все эти нюансы при необходимости могут быть легко изменены. Также в большой степени экономится время на создании новой машины, что позволяет в любой момент «убить» все ненужное, а потом создать по новой. Базовые сборки в систему добавляются командой:
$ vagrant box add <имя сборки> <url для загрузки>
Сами разработчики вагранта предлагают четыре вида базовых сборок — два последних релиза Ubuntu в 32- и 64-битном исполнении (одну из них мы только что уже установили в системе):
Но на этом список далеко не заканчивается. Существует специальный сайт, где каждый желающий может выложить свою базовую сборку. Он располагается по адресу:www.vagrantbox.es. Там любой может выбрать себе что-нибудь по вкусу. В ассортименте: Debian, Windows Server, FreeBSD, CentOS, Gentoo и другие.
Кроме того, ты легко можешь создать собственную стартовую конфигурацию, но об этом чуть позже.
НОВШЕСТВА VIRTUALBOX 4.2
Кстати, не так давно Oracle выпустили новую версию VirtualBox под номером 4.2. Если ты еще не перешел на актуальную версию, то, вероятно, тебе будет интересно узнать о новшествах.
Группы виртуальных машин
В новом менеджере появилась возможность группировать виртуалки по какому-либо принципу (например, по типу операционной системы, по проекту, в котором они используются, или как-либо еще). Группы позволяют организовать весь зоопарк, который появляется у опытных пользователей виртуалбокса, а также выполнять групповые операции — например, можно разом стартануть несколько машин, выбрав соответствующую команду в группе.
Автостарт? Запуск «безмордовый»
Так называемый Headless launch — то есть запуск виртуалки без открытия соответствующего окна с интерфейсом машины — теперь возможен прямо из менеджера. Если раньше, чтобы запустить виртуальную машину, приходилось отправляться в консоль, набирать там что-то типа:
$ VBoxManage startvm ... --type headless
то теперь достаточно при запуске виртуальной машины из интерфейса VirtualBox зажать . Остановить запущенную в headless режиме виртуалку можно также из менеджера, выполнив соответствующую команду.
Создание виртуалок в два клика
Это, правда, чисто интерфейсное улучшение (то есть ни о каком программном ускорении создания виртуальной машины речи не идет), но все же. Если на первом диалоге при создании новой виртуалки нажать кнопку «Скрыть описание», то появится другой диалог типа «все в одном», в котором можно будет быстро настроить параметры создаваемой машины.
Улучшения сетевых интерфейсов
Теперь VirtualBox позволяет создавать виртуальные машины с 36 сетевыми картами на борту. Также представлен новый функционал регулирования пропускной способности, чтобы ограничить «прожорливость» виртуалки.
Повышение производительности процессоров
Многие современные процессоры поддерживают технологию виртуализации вложенных страниц для блока управления памятью процессора (у Intel она называется Extended Page Tables, а у AMD — Rapid Virtualization Indexing). С версии 4.2 виртуалбокс теперь ее тоже поддерживает. Поэтому владельцы Core i5 или AMD Bulldozer после обновления должны заметить определенный прирост скорости работы виртуальной машины.
Новые гостевые ОС
Список официально поддерживаемых гостевых операционок теперь дополнился следующими наименованиями:
- Mac OS X Mountain Lion
- Windows 8
- Windows Server 2012
- Ubuntu 12.04 (Precise Pangolin)
- Fedora 17
- Oracle Linux 6.3
Так что теперь все современные операционки без проблем должны работать внутри VB.
Vagrant-файл
Важной частью системы является специальный конфигурационный файл, написанный на Ruby. Он называется Vagrantfile и описывает виртуальные машины, необходимые в проекте. Предполагается, что в команде для разработки используется один и тот же Vagrantfile, который распространяется через систему контроля версий между ее членами. Важно заметить, что Vagrant читает конфигурацию последовательно из четырех мест и каждый последующий этап может изменять параметры предыдущего. Итак, точный порядок загрузки такой:
- Сначала загружается Vagrantfile, содержащийся в руби-геме.
- Следом загружается Vagrantfile из директории базовой сборки (если она было собрана с параметром --vagrantfile).
- Потом загружается Vagrantfile из домашнего каталога пользователя (~/.vagrant.d/), позволяя пользователю добавить для него какие-либо параметры.
- И последним загружается Vagrantfile из директории проекта. В большинстве случаев именно в нем находятся все основные настройки проекта, и именно этот файл стоит добавить в систему контроля версий.
Полный список доступных настроек для вагрантфайла содержится в документации. Только что созданная виртуальная среда имеет минимальный конфиг вида:
Vagrant::Config.run do |config|
config.vm.box = "precise64"
end
И пока несколько бестолкова, но ничего, дальше мы добавим ей функционала.
Provisioning
Запуск пустой виртуальной машины (пусть даже и особым образом сконфигурированной) вряд ли может быть сильно полезен, поэтому в вагранте есть так называемые наполнители (provisioners) — различные способы настроить виртуальную машину не снаружи, а изнутри. По сути, это возможность писать различные дополнительные сценарии, которые выполняются после создания виртуальной машины. Поскольку вагрант написан рубистами, то в качестве конфигураторов машины выбраны привычные им средства: Chef Solo, Chef Server, Puppet Standalone, Puppet Server и обыкновенный Shell. Средства Chef и Puppet довольно известны и распространены и часто применяются для деплоя самых разных проектов, так что мы не будем заострять на нах внимание и рассмотрим самый простой вариант — shell-скрипт. Создадим в текущей директории файл с именем install_redis.sh и содержанием:
sudo apt-get -q -y install redis-server
А в Vagrant-файл добавим команды для наполнения:
Vagrant::Config.run do |config|
config.vm.box = "precise64"
config.vm.provision :shell, :path => "install_redis.sh"
end
Теперь переконфигурируем нашу машину командой:
$ vagrant reload
В результате на нашей виртуалке появится свежеустановленный редис.
Сетевые настройки
Конечно, одна из важнейших настроек виртуальной машины — конфигурация сетевых интерфейсов. За сетевые настройки отвечает параметр config.vm.network. Вагрант предлагает два варианта на выбор: работа в сети, ограниченной хост-машиной, и подключение через сетевой мост.
В первом случае мы явно задаем IP машины, а также можем опционально указать маску сети (по умолчанию используется 255.255.255.0). В таком случае конфиг приобретает вид:
Vagrant::Config.run do |config|
config.vm.box = "precise64"
config.vm.provision :shell, :path => "install_redis.sh"
end
Во втором случае машина получает IP по DHCP и становится полноценным членом сети, в которой расположена и хост-машина. Если на хост-машине присутствует несколько сетевых интерфейсов, то мы можем указать, который именно использовать для моста. Для вывода списка имен сетевых интерфейсов воспользуемся командой:
~$ VBoxManage list bridgedifs | grep ^Name
Name:en1: Wi-Fi (AirPort)
Name:en0: Ethernet
Name:p2p0
И, соответственно, конфигурация примет вид:
Vagrant::Config.run do |config|
config.vm.box = "precise64"
config.vm.provision :shell, :path => "install_redis.sh"
config.vm.network :bridged, :bridge => "en1: Wi-Fi (AirPort)"
end
Кроме того, Vagrant позволяет также пробрасывать порты. Вот, например, такой Vagrantfile позволяет пробрасывать с 6379-го порта гостевой машины, на который по умолчанию вешается редис, на 8765-й на хост-машине.
Vagrant::Config.run do |config|
config.vm.box = "precise64"
config.vm.provision :shell, :path => "install_redis.sh"
config.vm.forward_port 6379, 8765
end
Какой вариант лучше — выбор за тобой, но в любом случае наша виртуалка уже вполне может выполнять роль сервера базы данных, на который можно зайти либо с хост-машины, либо с другой виртуалки.
Несколько виртуальных машин
Кстати, в одном Vagrant-файле можно объявить сразу несколько виртуальных машин с различными настройками. Как? Я думаю, следующий пример скажет сам за себя:
Vagrant::Config.run do |config|
config.vm.define :web do |web_config|
web_config.vm.box = "web"
web_config.vm.forward_port 80, 8080
end
config.vm.define :db do |db_config|
db_config.vm.box = "db"
db_config.vm.forward_port 3306, 3306
end
end
Более того, запускать и пересоздавать виртуалки можно по отдельности, добавляя имя машины после соответствующей команды:
$ vagrant up web
$ vagrant reload db
Общие папки
Еще одна интересная особенность VirtualBox — общие папки, дающие возможность легко обмениваться файлами между гостевой и хост-машинами. Разумеется, Vagrant предоставляет удобный способ настройки данной опции. Все, что нужно, — это немного поправить конфигурационный файл:
Vagrant::Config.run do |config|
config.vm.share_folder "data", "/data", "data"
end
Важно заметить также, что папки, использующие протокол NFS (Network File System), показывают лучшую производительность, нежели общие папки виртуалбокса. С другой стороны, NFS не поддерживается на хостах с Windows. Для того чтобы использовать NFS вместо VirtualBox shared folders, необходимо это явно указать в настройках:
Vagrant::Config.run do |config|
config.vm.share_folder("data", "/data", "data", :nfs => true)
end
Снэпшоты и песочница
Поскольку Vagrant предоставляет гибкий API для расширения своего функционала, неудивительно, что существует немалое количество плагинов для Vagrant, решающих самые различные задачи. На случай, если у тебя появятся новые идеи, какие новые возможности можно добавить в вагрант, — в документации есть специальный раздел, содержащий все необходимые настройки и примеры (bit.ly/126iIsM).
Sahara
Плагин представляет собой песочницу для виртуальных машин: если что-то поломалось, можно легко и просто откатить до последнего снэпшота. Плагин является руби-гемом (что вполне ожидаемо) и называется sahara. После его установки в вагранте появляется дополнительная команда — vagrant sandbox. Типичный пример использования выглядит так. Включаем режим песочницы:
$ vagrant sandbox on
Производим определенные действия (работаем с файлами, меняем настройки и прочее):
$ vagrant ssh
Если результат работы нас удовлетворил — сохраняем изменения:
$ vagrant sandbox commit
В противном случае откатываем неугодные правки:
$ vagrant sandbox rollback
И выходим из режима песочницы:
$ vagrant sandbox off
Создание базовых сборок
Несмотря на то что сообщество уже позаботилось о наиболее распространенных образах операционных систем, тебе вполне может понадобиться иметь свою особенную сборку. Из соображений безопасности (а вдруг хакер Вася добавил свою магию в одну из сборок, лежащих в Сети), необходимости каких-то особенных настроек или просто из интереса — неважно, главное, что такая возможность есть. И здесь нам поможет гем veewee, созданный специально для этих целей. Для начала установим его:
$ gem install veewee
Репозиторий veewee содержит большое количество шаблонов. Выберем интересующий нас — пусть это будет последняя версия Ubuntu Server. Теперь создадим новую базовую сборку на основе этого шаблона:
$ veewee vbox define myubuntubox "ubuntu-12.10-server-i386"
В результате у нас появится новое «определение» бейс-бокса. В папке definitions/myubuntubox содержатся файлы, описывающие нашу виртуальную машину:
- definition.rb,
- postinstall.sh,
- preseed.cfg.
Немного поправим конфигурацию виртуалки:
Veewee::Session.declare({
:cpu_count => '1', :memory_size=> '1024',
:disk_size => '10140', :disk_format => 'VDI',
:hostiocache => 'off',
:os_type_id => 'Ubuntu',
:iso_file => "ubuntu-12.10-server-i386.iso",
:iso_src => "http://releases.ubuntu.com/12.10/ubuntu-12.10-server-i386.iso",
:iso_md5 => 'b3d4d4edfc8f291af0b83f8a2ba19a2f',
:iso_download_timeout => "1000",
:boot_wait => "4",
:boot_cmd_sequence => [
'<Esc><Esc><Enter>',
'/install/vmlinuz noapic preseed/url=http://%IP%:%PORT%/preseed.cfg ',
'debian-installer=en_US auto locale=en_US kbd-chooser/method=us ',
'hostname=%NAME% ',
'fb=false debconf/frontend=noninteractive ',
'keyboard-configuration/modelcode=SKIP keyboard-configuration/layout=us keyboard-configuration/variant=us console-setup/ask_detect=false ',
'initrd=/install/initrd.gz -- <Enter>'
],
:kickstart_port => "7122", :kickstart_timeout => "10000", :kickstart_file => "preseed.cfg",
:ssh_login_timeout => "10000", :ssh_user => "vagrant", :ssh_password => "vagrant",
:ssh_key => "", :ssh_host_port => "7222", :ssh_guest_port => "22",
:sudo_cmd => "echo '%p'|sudo -S sh '%f'",
:shutdown_cmd => "shutdown -P now",
:postinstall_files => [ "postinstall.sh"], :postinstall_timeout => "10000"
})
Теперь запустим сборку командой
$ veewee vbox build myubuntubox
Veewee задумается на время, пока будет создавать виртуальную машину, скачивать ISO-образ операционной системы, а также устанавливать и настраивать ее. После того как команда закончит работу, проверим созданную виртуалку командой
$ veewee vbox validate myubuntubox
Если все прошло гладко, можно двигаться дальше. Проэкспортируем созданную виртуальную машину как файл базовой сборки vagrant:
$ vagrant basebox export myubuntubox
Ну вот, собственно, и все. Теперь, чтобы использовать нашу базовую сборку, вызовем уже знакомые команды. Добавим бокс в список:
$ vagrant box add myubuntubox myubuntubox.box
И создадим новую виртуальную машину на основе уже созданной:
$ vagrant init myubuntubox
Вот и все — теперь даже самые рьяные параноики не смогут нас осудить, ведь теперь весь техпроцесс создания виртуальной среды контролируется нами же.
Заключение
Удобная среда разработки позволяет больше сконцентрироваться на решаемой проблеме, а не на вопросах совместимости ПО или различиях операционных систем, и это главная фишка Vagrant. С ним можно избавиться от проблем, когда на машине разработчика все работает, а на продакшене почему-то нет. Разумеется, на данный момент несколько смущает его сильная руби-ориентированность, но будем надеяться, что со временем разработчики решат и эту проблему, расширив, например, список провизоров на Python или Java. И кстати, в настоящее время идет работа по добавлению других систем виртуализации, кроме VirtualBox.
В любом случае, уже сейчас проект представляет большой интерес как для отдельных разработчиков, так и для групп разработки. Удачи и новых познаний!