Это старая версия документа.


В теме описано использование vagrant с провайдером VirtualBox.
Подробное содержание доступно справа.

1. Установка vagrant + VirtualBox

Устанавливать будем с официального сайта, скачав подходящие deb-пакеты. При этом нужно учесть, что последняя версия vagrant(1.8.4) НЕ поддерживает последнюю версию VirtualBox(5.1.0).

ссылка на х64 версию VirtualBox для 14.04

Ссылка на х64 версию vagrant

Скачиваем и устанавливаем vagrant:

mkdir ~/vagrant
cd ~/vagrant
wget https://releases.hashicorp.com/vagrant/1.8.4/vagrant_1.8.4_x86_64.deb
sudo dpkg -i vagrant_1.8.4_x86_64.deb
rm -f vagrant_1.8.4_x86_64.deb

Скачиваем и устанавливаем VirtualBox:

cd ~/vagrant
wget http://download.virtualbox.org/virtualbox/5.0.24/virtualbox-5.0_5.0.24-108355~Ubuntu~trusty_amd64.deb
sudo dpkg -i virtualbox-5.0_5.0.24-108355~Ubuntu~trusty_amd64.deb
rm -f virtualbox-5.0_5.0.24-108355~Ubuntu~trusty_amd64.deb

Может понадобиться пакет linux-headers:

sudo apt-get install linux-headers-$(uname -r)

После всех манипуляций выше должны в системе присутствовать:

  • vagrant 1.8.4
  • VirtualBox 5.0
  • linux-headers

Всё готово для использования.

2. Создаём машину по-умолчанию

Для того, чтоб создать виртуальную машину со стандартными настройками вполне достаточно выполнить две команды:

vagrant init

эта команда в текущей директории создат Vagrantfile (можете посмотреть его в vim любимом текстовом редакторе), который будет считывать следующей командой:

vagrant up

Эта команда скачает базовый образ из репозитория vagrant и на его основе создаст виртуальную машину для VirtualBox.

Маленькие прелести vagrant:
  • Автоматическое подмонтирование корневой директории (с Vagrantfile`ом) в гостя;
  • Автоматический проброс порта для ssh (хост - 2222, гость - 22);
  • Создание ssh-ключей;
  • чтоб подключиться к машине, достаточно выполнить
vagrant ssh

И всё, мы внутри гостя.

3. Создание собственного Vagrantfile

Создание собственного файла позволяет очень гибко настроить саму машину и систему. То есть, указать количество памяти, процессор, другие опции провайдера (в данном случае VirtualBox) и можно указать, что делать в самой системе - установка приложений, конфигурация, копирование файлов.

Самый быстрый способ создать уникальный Vagrantfile - создать пример(темплейт) командой

vagrant init

и далее редактировать сгенерированный файл.

Вот небольшой пример Vagrantfile с одной машиной, которая содержит образ Ubuntu 14.04.

# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.configure(2) do |config|
  config.vm.box = "ubuntu/trusty64"
  config.vm.box_check_update = false
  config.vm.hostname = "testing"  
  config.vm.network "public_network", ip: "192.168.1.100"
  config.vm.define "testing"
  config.vm.provider "virtualbox" do |vb|
     vb.gui = false
     vb.memory = "1024"
  end
end

Он написан на языке Ruby. Знать язык не обязательно для работы, всё просто.

Первые две строки служебные - указываем режим работы с Vagrantfile. (указывать не обязательно, но при генерации добавляются сами)

Далее, строка

Vagrant.configure(2) do |config|

начинает цикл, подставляя вместо «Vagrant.configure» ⇒ «config»

следующая:

  
config.vm.box = "ubuntu/trusty64"

указываем название образа. Название образа можно выбрать отсюда (официальный репозиторий) или создать самому (немного сложнее).

Едем дальше:

config.vm.box_check_update = false

По-умолчания, vagrant перед каждым запуском образа проверяет репозиторий на наличие обновлений. Это занимает какое-то время и не особо нам нужно, так как используем LTS версию.

Тут всё понятно - задаём hostname:

 
 config.vm.hostname = "testing"  

Следующими строками мы задаем публичный (то есть, наша виртуалка доступна по этому адресу внутри сети) адрес. Если не указать его явно, то нам его подарит DHCP.

Строка:

 
 config.vm.define "testing"

задаёт имя машины для vagrant и VBox. Это не обязательно, но лучше это сделать, потому что удобнее обращаться к машинам по именам (см. п. 6)

И, наконец, мы говорим нашему провайдеру, что нам не нужен графический интерфейс (для VirtualBox по-умолачнию идёт значение False) и что памяти мы готовы выделить не больше 1 Гб:

  config.vm.provider "virtualbox" do |vb|
     vb.gui = false
     vb.memory = "1024"
  end

Более развёрнутая информация о Vagrantfile тут

4. vagrant, VBox и сеть

4.1 Private network

С частной сетью понятно - мы делаем собственную сеть LAN, которая будет состоять из виртуальных машин. Для доступа к такой сети из хоста нужна пробрасывать порт через Vagrantfile (или через Vbox, но через vagrant удобнее). А для доступа из реальной сети, то есть, например из другой физической машины, мы должны будем стучаться на IP хоста.

Это удобно, если создавать виртуалку для «поиграться» или если планируется использовать виртуалку внутри сети и за NAT (например, она получит адрес от DHCP другой виртуалки, которая будет выполнять роль шлюза).

сконфигурировать можно в Vagrantfile следующим способом:

config.vm.network "private_network", ip xxx.xxx.xxx.xxx

IP можно не указывать, можно сделать так:

config.vm.network "private_network", type: "dhcp"

и адрес назначится автоматически.

больше информации и приватных сетях тут

4.2 Public network

Публичная сеть позволяет добавить машину в вашу подсеть так, как будто появилась дополнительная железная машина. С публичной сетью нет необходимости пробрасывать порты - всё доступно по адресу виртуалки. Для всех машин в этой же подсети.

Тут надо быть осторожным, если вы не администратор сети. Так как в подсеть включится новая машина со своим адресом и именем, это может создать некоторые проблемы с DNS и\или DHCP на основном шлюзе.

Создать публичную сеть можно так:

config.vm.network "public_network", ip: "192.168.1.100"

Если не задать адрес, то он будет задан dhcp-сервером в реальной подсети. По факту, публичная сеть использует bridge-соединение с WAN-адаптером хоста. Если у вас два физических адаптера (две сетевых карты, например проводная и беспроводная), то vagrant спросит, какую из них использовать. В случае, если у вас два адаптера, то вы можете указать его:

config.vm.network "public_network", bridge: "eth1" 

больше информации о публичных сетях тут

===4.3 Port Forwarding===

Как уже упоминалось выше, vagrant сам пробрасывает 22 порт гостя на 2222 порт хоста для первой машины. Для следующих машин это будет 2200, 2300 - называется эта штука auto_correct Простыми словами - если у вас где-то есть конфликт портов(пробросили на уже занятый порт), то vagrant это дело увидит и сам исправит, радостно сообщив о сделанном в консоли.

Автоматически эта опция включена только для 22 порта, для портов, которые вы задаёте вручну, нужно указать эту опцию как

auto_correct: true

Где? возле каждого порта, который вы указали (пример ниже)

Для того, чтоб принудительно открыть порты, используется следующий синтаксис:

 config.vm.network  "forwarded_port", guest: 80, host: 9999, auto_correct: true

в этом примере мы перенаправили стандартный 80 порт для веб-серверов (http) с гостя на 9999 порт хоста. Теперь, если у нас в виртуальной машине есть какой-либо веб-сервер (nginx, apache), то мы сможем попасть на него с хоста двумя способами:

Это возможно благодаря тому, что по-умолчанию vagrant привязывает проброшеный порт на все доступные в хостовой системе интерфейсы. Если вы не хотите пробрасывать порт на WAN -интерфейс, то можете конкретно указать, на какой ip адрес привязать пробощеный порт:

 
config.vm.network  "forwarded_port", guest: 8080, host: 9898, host_ip: 127.0.0.1 

Если нам требуется пробросить несколько портов, то просто задаём две строки в Vagrantfile:

config.vm.network  "forwarded_port", guest: 80, host: 9999
config.vm.network  "forwarded_port", guest: 8080, host: 9898

И второй порт тоже будет доступен на хосте.

Никогда не назначайте проброс портов на стандартные! (например, 22 на 22) Иначе можно огрести неплохих проблем на хостовой машине!

По-умолчанию проброс идёт ТСР протокола, для того, чтоб проборосить UDP порт, это нужно явно указать:

config.vm.network "forwarded_port", guest: 35555, host: 12003, protocol: "udp" 

5. Синхронизация каталогов

«Из коробки» vagrant синхронизирует каталог хоста с Vagrantfile в директорию /vagrant виртуальной машины.

Для того, чтоб указать дополнительный каталоги для синхронизации, нужно добавить следующую строку в Vagrantfile:

    config.vm.synced_folder "src/", "/var/www/html" 

Первым указывается путь на хосте, вторым - гостевой путь. Если на хостовой машине указывать относительный путь, то корневым будет каталог с Vagrantfile.

Если абсолютный путь, то он абсолютный :)

Путь на гостевой машине должен быть *только* абсолютный. Если директорий не существует, они будут созданы рекурсивно.

Дополнительные опции:

  • disabled - если указать True, то синхронизация будет отключена. Удобно, если

нам не нужна «изкоробочная» синхронизация.

  • mount_options - дополнительные параметры, которые будут переданы команде

mount при монтировании

  • type - полезная опция, которая позволяет выбрать тип синхронизации. Доступны следующие варианты:
    • NFS
    • rsync
    • SMB
    • VirtualBox
тип SMB доступен только для Windows-host!
тип NFS доступен только для Linux-host!

Если эта поция не указана, то vagrant выберет сам самую подходящую.

Я рекомендую для Linux-гостей использовать rsync - этот тип не требует дополнений гостевых систем, автоматически установить rsync на всех гостей. Также, доступны дополнительные плюшки, такие как vagrant rsync и vagrant rsync-auto ( о них ниже)

  • id - имя, которое будет показываться при команде mount в гостевой

машине. Имеет смысл использовать, если у вас несколько расшареных каталогов

vagrant не поддерживает синхронизацию симлинков!
Рассмотрим подробнее вариант rsync

Первое - этот тип работает только в одну сторону Каталоги, которые синхронизированы через rsync синхронизируются автоматически только один раз - при инициализации машины (vagrant up\vagrant reload). Принудительно синхронизировать можно двумя путями:

  1. vagrant rsync
  2. vagrant rsync-auto

Отличия можно понять по названиям:
первый вариант запускается один раз (синхронизировал и всё).

Имейте ввиду, что если вы сделали изменения в Vagrantfile в области синхронизации, то вам необходимо перед vagrant rsync сделать vagrant reload.

Второй же работает в режиме демона и отслеживает изменения на хосте. Это удобно, так как один каталог можно шарить на несколько машин сразу, передавая изменения на всех гостей.

Если вы хотите сделать изменения в Vagrantfile, для начали остановите vagrant rsync-auto, внесите изменения, и потом перезапустите.

Для rsync есть куча опций, которые обычно не нужны. На мой взгляд, одна из самых полезных - rsync_exclude. (аналог gitignore) Опция позволяет исключить из списка синхронизации, которые не нужны. Это нужно, когда у вас есть директория, в которой содержится 1005 файлов. И вам нужно синхронизировать 1000, а 5 - не нужно. Гораздо проще исключить 5 файлов, чем добавлять 1000.

6. Использование команд vagrant

Все команды, которые описаны тут, должны выполняться в том каталоге, в котором лежит Vagrantfile.

Пожалуй, самые необходимые команды это vagrant up, vagrant destroy, vagrant suspend, vagrant resume, vagrant ssh.

Теперь по порядку. vagrant up Эта команда смотрит в Vagrantfile и создаёт виртуальную машину согласно описанию. Если в Vagrantfile описано несколько мащин, то вы должны явно указать её имя. В противном случае будут подняты все машины. О мультимашинном Vagrantfile мы поговорим позже.

vagrant destroy Эта команда уничтожает машину полностью, найдя её описание в Vagrantfile. Точно также, как и при создании машины, вы должны указать имя машины, если их несколько.

Для того, чтоб удалить машину без подтверждения, используйте ключ -f

vagrant destroy -f 
Всегда сначала уничтожайте машину, а только потом удаляйте её из Vagrantfile! Иначе вы получите ошибку, что конфигурации такой машины не найдено.

vagrant suspend Эта команда отправляет машину в сон (аналог VirtualBox - сохранить состояние)

Требует наличие дополнительного свободного места, так как сохраняет ОЗУ вируталки.

После этого, машину можно «воскресить» командой:

vagrant resume Как уже сказано выше, эта команда пробуждает машину из сна.

vagrant ssh

Название команды также говорящее. Этой командой очень просто подключиться к машине. Если она одна, то подключение будет сразу. Если машин несколько, то следует явно указать её имя.

Теперь еще парочку дополнительных команд, которые могут оказаться полезными.

vagrant global-status

Команда-исключение. Её можно выполнять в любой директории и она вернёт список машин, вместе с состоянием и с дирекорией, в которой размещён Vagrantfile. Пример использования:

ivan@Punka:~$ vagrant global-status
id       name   provider   state   directory                                   
-------------------------------------------------------------------------------
06bcbfa  dev    virtualbox running /home/ivan/infrastr 
a1a8f2b  ci     virtualbox running /home/ivan/infrastr 
 

Это удобно, если вы забыли(ну, разное бывает), в какой директории запустили vagrant. Эта команда всё покажет и рааскажет.

vagrant halt

shutdown обычный.

vagrant port

показывает список проброшенных портов. Пример:

vagrant port
 22 (guest) => 2222 (host)
 80 (guest) => 9999 (host)

vagrant reload Эта команда перезагрузки - сначала выключает машину, потом поднимает. Удобно, если надо применить изменения в конфигурации

Более подробно о других команда можно узнать на официальном сайте

7 Конфигурирование нескольких машин

В одном Vagrantfile может быть столько мащин, сколько нам нужно. Задать их можно двумя способами:

  • Используя цикл
  • Отдельно задавая каждую мащину

Очевидно, что циклом удобно поднимать машины, которые буду отличаться только названием, хостнеймом и, возможно, ip адресом (параметры, которые можно итерировать). Другие параметры системы, такие как память, процессор, синхронизированные каталоги задать нельзя. Это могут быть ноды кластера, ноды для балансировщика или если вам нужно поднять пару десятков одинаковых машин для тестировщиков или разработчиков.

При конфигурировании каждой мащины отдельно мы имеем гораздо больше возможностей, но и писать придётся больше.

7.1 Использование цикла

$mach_quant = 3

Vagrant.configure("2") do |config|
 
  config.vm.provider "virtualbox" do |vb|
      vb.gui = false
      vb.memory=256
      vb.cpus=1
      vb.check_guest_additions=false
  config.vm.box_check_update=false
  config.vm.box="ubuntu/trusty64"
 end

(1..$mach_quant).each do |i|
    config.vm.define "node#{i}" do |node|
        node.vm.network "public_network", ip: "192.168.1.#{24+i}"
        node.vm.hostname = "node#{i}"
    end
end
  
end 

Первая строчки - мы создали переменную mach_quant и присвоили ей значение 3. Эта переменная и будет указывать на количество машин, которые vagrant будет поднимать.

Первый цикл конфигурирует провайдер VirtualBox, а именно задаёт:

  1. консольный режим (без интерфейса)
  2. 256 Мб памяти
  3. 1 виртуальный процессор
  4. отменяем проверку на гостевые дополнения. Так как мы используем серверную

версию дистрибутива, а проверка замедляет запуск виртуальной мащины, то это вполне логично.

Дальше уже знакомая строчка - не проверять обновления образа.

Теперь мы создаём цикл, который будет создавать машины, меняя название машины, хостнейм и ip адрес.

Идёт итерация от 1 до mach_quant (в данном случае три), номер мащины подставляется в переменную і.

Значение i Имя машины ip адрес Хостнейм
1 node1 192.168.1.25 node1
2 node2 192.168.1.26 node2
3 node3 192.168.1.27 node3

Работать с таким файлом можно двумя способами: в этом случае будут подняты все машины, конфиги которых присутствуют.

<code> vagrant up</code>

А в этом случае будет поднята только та машина, которая указан.

 vagrant up node2

Можно еще и так - задать сразу несколько мащин.

 vagrant up node2 node3
FIXME добавить листинги, описание листингов, добавить перекрёстных ссылок на другие статьи в местной вики, вики, оф сайты. Написать раздел о конфигурировании машин с помощью разных провизоров.