Vagrant Сравнение версий

Различия

Здесь показаны различия между двумя версиями данной страницы.

Ссылка на это сравнение

Предыдущая версия справа и слева Предыдущая версия
Следующая версия
Предыдущая версия
wiki:vagrant [2016/07/20 01:45]
[7. Конфигурирование нескольких машин]
wiki:vagrant [2016/08/26 22:44] (текущий)
[Provisioning with Puppet]
Строка 4: Строка 4:
 Подробное содержание доступно справа. Подробное содержание доступно справа.
  
-====1. Установка vagrant + VirtualBox====+====Установка vagrant + VirtualBox=====
 Устанавливать будем с официального сайта, скачав подходящие deb-пакеты. Устанавливать будем с официального сайта, скачав подходящие deb-пакеты.
-При этом нужно учесть,​ что последняя версия vagrant(1.8.4) **НЕ** поддерживает последнюю версию VirtualBox(5.1.0). 
  
 [[http://​download.virtualbox.org/​virtualbox/​5.0.24/​virtualbox-5.0_5.0.24-108355~Ubuntu~trusty_amd64.deb|ссылка на х64 версию VirtualBox для 14.04]] [[http://​download.virtualbox.org/​virtualbox/​5.0.24/​virtualbox-5.0_5.0.24-108355~Ubuntu~trusty_amd64.deb|ссылка на х64 версию VirtualBox для 14.04]]
Строка 43: Строка 42:
 Всё готово для использования. Всё готово для использования.
  
-====2. Создаём машину по-умолчанию====+====Создаём машину по-умолчанию=====
 Для того, чтоб создать виртуальную машину со стандартными настройками вполне достаточно выполнить две команды:​ Для того, чтоб создать виртуальную машину со стандартными настройками вполне достаточно выполнить две команды:​
  
 <​code>​ <​code>​
-vagrant init</​code>​+vagrant init 
 +</​code>​
 эта команда в текущей директории создат Vagrantfile (можете посмотреть его в эта команда в текущей директории создат Vagrantfile (можете посмотреть его в
 <​del>​vim</​del>​ любимом текстовом редакторе),​ который будет считывать следующей командой:​ <​del>​vim</​del>​ любимом текстовом редакторе),​ который будет считывать следующей командой:​
 <​code>​ <​code>​
-vagrant up</​code>​+vagrant up 
 +</​code>​
 Эта команда скачает базовый образ из репозитория vagrant и на его основе создаст виртуальную машину для VirtualBox. Эта команда скачает базовый образ из репозитория vagrant и на его основе создаст виртуальную машину для VirtualBox.
  
Строка 60: Строка 61:
   *чтоб подключиться к машине,​ достаточно выполнить   *чтоб подключиться к машине,​ достаточно выполнить
 <​code>​ <​code>​
-vagrant ssh</​code>​+vagrant ssh 
 +</​code>​
 И всё, мы внутри гостя. И всё, мы внутри гостя.
  
-====3. Создание ​собственного ​Vagrantfile====+====Создаём собственный Vagrantfile=====
 Создание собственного файла позволяет очень гибко настроить саму машину и систему. Создание собственного файла позволяет очень гибко настроить саму машину и систему.
 То есть, указать количество памяти,​ процессор,​ другие опции провайдера (в данном случае VirtualBox) и можно указать,​ что делать в самой системе - установка приложений,​ конфигурация,​ копирование файлов. То есть, указать количество памяти,​ процессор,​ другие опции провайдера (в данном случае VirtualBox) и можно указать,​ что делать в самой системе - установка приложений,​ конфигурация,​ копирование файлов.
  
 Самый быстрый способ создать уникальный Vagrantfile - создать пример(темплейт) командой Самый быстрый способ создать уникальный Vagrantfile - создать пример(темплейт) командой
-<​code>​vagrant init</​code>​+<​code>​ 
 +vagrant init 
 +</​code>​
 и далее редактировать сгенерированный файл. и далее редактировать сгенерированный файл.
  
Строка 96: Строка 100:
 Далее, строка Далее, строка
 <​code>​ <​code>​
-Vagrant.configure(2) do |config|</​code>​+Vagrant.configure(2) do |config| 
 +</​code>​
 начинает цикл, подставляя вместо "​Vagrant.configure"​ => "​config"​ начинает цикл, подставляя вместо "​Vagrant.configure"​ => "​config"​
  
 следующая:​ следующая:​
-<​code> ​  +<​code>​ 
-config.vm.box = "​ubuntu/​trusty64"</​code>​+config.vm.box = "​ubuntu/​trusty64"​ 
 +</​code>​
 указываем название образа. Название образа можно выбрать указываем название образа. Название образа можно выбрать
 [[https://​atlas.hashicorp.com/​boxes/​search|отсюда (официальный репозиторий)]] или создать самому (немного сложнее). [[https://​atlas.hashicorp.com/​boxes/​search|отсюда (официальный репозиторий)]] или создать самому (немного сложнее).
Строка 113: Строка 119:
  
 Тут всё понятно - задаём hostname: Тут всё понятно - задаём hostname:
-<​code>​  +<​code>​ 
- ​config.vm.hostname = "​testing" ​ </​code>​+config.vm.hostname = "​testing" ​ </​code>​
  
 Следующими строками мы задаем публичный (то есть, наша виртуалка доступна по этому адресу внутри сети) адрес. Если не указать его явно, то нам его подарит DHCP. Следующими строками мы задаем публичный (то есть, наша виртуалка доступна по этому адресу внутри сети) адрес. Если не указать его явно, то нам его подарит DHCP.
  
 Строка:​ Строка:​
-<​code> ​+<​code>​
  ​config.vm.define "​testing"</​code>​  ​config.vm.define "​testing"</​code>​
 задаёт имя машины для vagrant и VBox. задаёт имя машины для vagrant и VBox.
Строка 131: Строка 137:
      ​vb.gui = false      ​vb.gui = false
      ​vb.memory = "​1024"​      ​vb.memory = "​1024"​
-  end</​code>​+  end 
 +</​code>​
  
 Более развёрнутая информация о Vagrantfile Более развёрнутая информация о Vagrantfile
 [[https://​www.vagrantup.com/​docs/​vagrantfile/​|тут]] [[https://​www.vagrantup.com/​docs/​vagrantfile/​|тут]]
  
-====4. vagrant, VBox и сеть====+====vagrant, VBox и сеть=====
  
-===4.1 Private network.===+===Private network====
 С частной сетью понятно - мы делаем собственную сеть LAN, которая будет состоять из виртуальных машин. С частной сетью понятно - мы делаем собственную сеть LAN, которая будет состоять из виртуальных машин.
 Для доступа к такой сети из хоста нужна пробрасывать порт через Vagrantfile (или через Vbox, но через vagrant удобнее). Для доступа к такой сети из хоста нужна пробрасывать порт через Vagrantfile (или через Vbox, но через vagrant удобнее).
Строка 150: Строка 157:
 config.vm.network "​private_network",​ ip xxx.xxx.xxx.xxx</​code>​ config.vm.network "​private_network",​ ip xxx.xxx.xxx.xxx</​code>​
 IP можно не указывать,​ можно сделать так: IP можно не указывать,​ можно сделать так:
-<​code>​config.vm.network "​private_network",​ type: "​dhcp"</​code>​+<​code>​config.vm.network "​private_network",​ type: "​dhcp"​ 
 +</​code>​
 и адрес назначится автоматически. и адрес назначится автоматически.
  
-больше информации ​и приватных сетях+больше информации ​о приватных сетях
 [[https://​www.vagrantup.com/​docs/​networking/​private_network.html|тут]] [[https://​www.vagrantup.com/​docs/​networking/​private_network.html|тут]]
  
-===4.2 Public network===+===Public network====
 Публичная сеть позволяет добавить машину в вашу подсеть так, как будто появилась дополнительная железная машина. Публичная сеть позволяет добавить машину в вашу подсеть так, как будто появилась дополнительная железная машина.
 С публичной сетью нет необходимости пробрасывать порты - всё доступно по адресу виртуалки. Для всех машин в этой же подсети. С публичной сетью нет необходимости пробрасывать порты - всё доступно по адресу виртуалки. Для всех машин в этой же подсети.
Строка 167: Строка 175:
  
 <​code>​ <​code>​
-config.vm.network "​public_network",​ ip: "​192.168.1.100"</​code>​+config.vm.network "​public_network",​ ip: "​192.168.1.100"​ 
 +</​code>​
  
 Если не задать адрес, то он будет задан dhcp-сервером в реальной подсети. Если не задать адрес, то он будет задан dhcp-сервером в реальной подсети.
Строка 175: Строка 184:
  
 <​code>​ <​code>​
-config.vm.network "​public_network",​ bridge: "​eth1"​ </​code>​+config.vm.network "​public_network",​ bridge: "​eth1" ​ 
 +</​code>​
  
 больше информации о публичных сетях больше информации о публичных сетях
 [[https://​www.vagrantup.com/​docs/​networking/​public_network.html|тут]] [[https://​www.vagrantup.com/​docs/​networking/​public_network.html|тут]]
-===4.3 Port Forwarding===+ 
 +==== Port Forwarding====
 Как уже упоминалось выше, vagrant сам пробрасывает 22 порт гостя на 2222 порт Как уже упоминалось выше, vagrant сам пробрасывает 22 порт гостя на 2222 порт
 хоста для первой машины. ​ хоста для первой машины. ​
Строка 195: Строка 206:
  
 Для того, чтоб принудительно открыть порты, используется следующий синтаксис:​ Для того, чтоб принудительно открыть порты, используется следующий синтаксис:​
-<​code>​ config.vm.network ​ "​forwarded_port",​ guest: 80, host: 9999, auto_correct:​ true+<​code>​ 
 +config.vm.network ​ "​forwarded_port",​ guest: 80, host: 9999, auto_correct:​ true
 </​code>​ </​code>​
  
Строка 209: Строка 221:
 Если вы не хотите пробрасывать порт на WAN -интерфейс,​ то можете конкретно Если вы не хотите пробрасывать порт на WAN -интерфейс,​ то можете конкретно
 указать,​ на какой ip адрес привязать пробощеный порт: указать,​ на какой ip адрес привязать пробощеный порт:
-<​code>​  +<​code>​ 
-config.vm.network ​ "​forwarded_port",​ guest: 8080, host: 9898, host_ip: 127.0.0.1 </​code> ​ +config.vm.network ​ "​forwarded_port",​ guest: 8080, host: 9898, host_ip: 127.0.0.1 ​ 
 +</​code>​
  
 Если нам требуется пробросить несколько портов,​ то просто задаём две строки в Если нам требуется пробросить несколько портов,​ то просто задаём две строки в
 Vagrantfile:​ Vagrantfile:​
  
-<​code>​config.vm.network ​ "​forwarded_port",​ guest: 80, host: 9999+<​code>​ 
 +config.vm.network ​ "​forwarded_port",​ guest: 80, host: 9999
 config.vm.network ​ "​forwarded_port",​ guest: 8080, host: 9898 config.vm.network ​ "​forwarded_port",​ guest: 8080, host: 9898
 </​code>​ </​code>​
Строка 228: Строка 242:
 это нужно явно указать:​ это нужно явно указать:​
  
-<​code>​config.vm.network "​forwarded_port",​ guest: 35555, host: 12003, protocol: "​udp"​ </​code> ​ +<​code>​ 
-FIXME дописать раздел о каталогах и управлении машинами.+config.vm.network "​forwarded_port",​ guest: 35555, host: 12003, protocol: "​udp" ​ 
 +</​code>​
  
-====5. Синхронизация каталогов==== +====Синхронизация каталогов===== 
-"Из коробки"​ vagrant синхронизирует каталог хоста с Vagrantfile в директорию /vagrant +"Из коробки"​ vagrant синхронизирует каталог хоста с Vagrantfile в директорию /vagrant виртуальной машины.
-виртуальной машины.+
  
-Для того, чтоб указать дополнительный каталоги для синхронизации,​ нужно добавить +Для того, чтоб указать дополнительный каталоги для синхронизации,​ нужно добавить следующую строку в Vagrantfile:​ 
-следующую строку в Vagrantfile:​ +<​code>​ 
-<​code> ​   config.vm.synced_folder "​src/",​ "/​var/​www/​html"​ </​code>​+config.vm.synced_folder "​src/",​ "/​var/​www/​html" ​ 
 +</​code>​
  
 Первым указывается путь на хосте, вторым - гостевой путь. Первым указывается путь на хосте, вторым - гостевой путь.
-Если на хостовой машине указывать относительный путь, то корневым будет каталог +Если на хостовой машине указывать относительный путь, то корневым будет каталог с Vagrantfile.
-с Vagrantfile.+
  
 Если абсолютный путь, то он абсолютный :) Если абсолютный путь, то он абсолютный :)
  
-Путь на гостевой машине должен быть *только* абсолютный.+Путь на гостевой машине должен быть ​**только** абсолютный.
 Если директорий не существует,​ они будут созданы рекурсивно. Если директорий не существует,​ они будут созданы рекурсивно.
  
 Дополнительные опции: Дополнительные опции:
-  * **disabled** - если указать True, то синхронизация будет отключена. Удобно,​ если +  * **disabled** - если указать True, то синхронизация будет отключена. Удобно,​ если нам не нужна "​изкоробочная"​ синхронизация. 
-нам не нужна "​изкоробочная"​ синхронизация. +  * **mount_options** - дополнительные параметры,​ которые будут переданы команде mount при монтировании
-  * **mount_options** - дополнительные параметры,​ которые будут переданы команде +
-    ​mount при монтировании+
   *  **type** - полезная опция, которая позволяет выбрать тип синхронизации. Доступны следующие варианты:​   *  **type** - полезная опция, которая позволяет выбрать тип синхронизации. Доступны следующие варианты:​
     * NFS     * NFS
Строка 262: Строка 274:
 <note important>​ тип NFS доступен только для Linux-host!</​note>​ <note important>​ тип NFS доступен только для Linux-host!</​note>​
  
-Если эта поция не указана,​ то vagrant выберет сам ​самую ​подходящую.+Если эта поция не указана,​ то vagrant выберет сам подходящую.
  
-Я рекомендую для Linux-гостей использовать rsync - этот тип //не// требует +Я рекомендую для Linux-гостей использовать rsync - этот тип //не// требует дополнений гостевых систем,​ автоматически установить rsync на всех гостей. 
-дополнений гостевых систем,​ автоматически установить rsync на всех гостей. +Также, доступны дополнительные плюшки,​ такие как vagrant rsync и vagrant rsync-auto ( о них ниже)
-Также, доступны дополнительные плюшки,​ такие как vagrant rsync и vagrant +
-rsync-auto ( о них ниже)+
   * **id** - имя, которое будет показываться при команде mount в гостевой   * **id** - имя, которое будет показываться при команде mount в гостевой
     машине. Имеет смысл использовать,​ если у вас несколько расшареных каталогов     машине. Имеет смысл использовать,​ если у вас несколько расшареных каталогов
Строка 274: Строка 284:
 ==Рассмотрим подробнее вариант rsync== ==Рассмотрим подробнее вариант rsync==
 Первое - этот тип **работает** только **в одну сторону** Первое - этот тип **работает** только **в одну сторону**
-Каталоги,​ которые синхронизированы через rsync синхронизируются автоматически +Каталоги,​ которые синхронизированы через rsync синхронизируются автоматически только один раз - при инициализации машины (vagrant up\vagrant reload).
-только один раз - при инициализации машины (vagrant up\vagrant reload).+
 Принудительно синхронизировать можно двумя путями:​ Принудительно синхронизировать можно двумя путями:​
   - vagrant rsync   - vagrant rsync
Строка 286: Строка 295:
 reload. </​note>​ reload. </​note>​
  
-Второй же работает в режиме демона и отслеживает изменения на хосте. +Второй же работает в режиме демона и отслеживает изменения на хосте. Это удобно,​ так как один каталог можно шарить на несколько машин сразу, передавая изменения на всех гостей.
-Это удобно,​ так как один каталог можно шарить на несколько машин сразу, +
-передавая изменения на всех гостей.+
  
 <note important>​Если вы хотите сделать изменения в Vagrantfile,​ для начали <note important>​Если вы хотите сделать изменения в Vagrantfile,​ для начали
Строка 300: Строка 307:
 Гораздо проще исключить 5 файлов,​ чем добавлять 1000. Гораздо проще исключить 5 файлов,​ чем добавлять 1000.
  
-====6. Использование команд vagrant====+====Использование команд vagrant=====
  
 <note important>​Все команды,​ которые описаны тут, должны выполняться в том каталоге,​ в котором <note important>​Все команды,​ которые описаны тут, должны выполняться в том каталоге,​ в котором
Строка 321: Строка 328:
  
 Для того, чтоб удалить машину без подтверждения,​ используйте ключ -f Для того, чтоб удалить машину без подтверждения,​ используйте ключ -f
-<​code>​vagrant destroy -f </​code>​+<​code>​ 
 +vagrant destroy -f  
 +</​code>​
  
 <note warning>​Всегда сначала уничтожайте машину,​ а только потом удаляйте её из <note warning>​Всегда сначала уничтожайте машину,​ а только потом удаляйте её из
Строка 351: Строка 360:
 машин, вместе с состоянием и с дирекорией,​ в которой размещён Vagrantfile. машин, вместе с состоянием и с дирекорией,​ в которой размещён Vagrantfile.
 Пример использования:​ Пример использования:​
- <​code>​ivan@Punka:​~$ vagrant global-status+ <​code>​ 
 +ivan@Punka:​~$ vagrant global-status
 id       ​name ​  ​provider ​  ​state ​  ​directory ​                                   id       ​name ​  ​provider ​  ​state ​  ​directory ​                                  
 ------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Строка 370: Строка 380:
 показывает список проброшенных портов. показывает список проброшенных портов.
 Пример:​ Пример:​
-<​code>​vagrant port+<​code>​ 
 +vagrant port
  22 (guest) => 2222 (host)  22 (guest) => 2222 (host)
  80 (guest) => 9999 (host)  80 (guest) => 9999 (host)
-</​code> ​ +</​code>​
  
 **vagrant reload** **vagrant reload**
Строка 381: Строка 392:
 Более подробно о других команда можно узнать [[https://​www.vagrantup.com/​docs/​cli/​|на официальном сайте]] Более подробно о других команда можно узнать [[https://​www.vagrantup.com/​docs/​cli/​|на официальном сайте]]
  
-====7. Конфигурирование нескольких машин====+====Конфигурирование нескольких машин=====
  
-В одном Vagrantfile может быть столько мащин, сколько нам нужно.+В одном Vagrantfile может быть столько машин, сколько нам нужно.
 Задать их можно двумя способами:​ Задать их можно двумя способами:​
   * Используя цикл   * Используя цикл
-  * Отдельно задавая каждую мащину+  * Отдельно задавая каждую машину
  
 Очевидно,​ что циклом удобно поднимать машины,​ которые буду отличаться только Очевидно,​ что циклом удобно поднимать машины,​ которые буду отличаться только
Строка 399: Строка 410:
 возможностей,​ но и писать придётся больше. возможностей,​ но и писать придётся больше.
  
-Ниже два листинга, ​один с циклом,​ другой - с отдельной конфигурацией каждой +==== Использование цикла====
-виртуалки. Потом мы разберём эти листинги и поймём,​ как с ними работать.+
  
-<note>FIXME добавить листинги,​ описание листингов,​ добавить перекрёстных ссылок на другие статьи в местной вики, вики, оф сайты. +<code> 
-Написать раздел о конфигурировании машин с помощью разных провизоров.+$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  
 +</​code>​ 
 + 
 +Первая строчки - мы создали переменную mach_quant и присвоили ей значение 3. 
 +Эта переменная и будет указывать на количество машин, которые vagrant будет 
 +поднимать
 + 
 +Первый цикл конфигурирует провайдер VirtualBox, а именно задаёт:​ 
 +  - консольный режим (без интерфейса) 
 +  - 256 Мб памяти 
 +  - 1 виртуальный процессор 
 +  - отменяем проверку на гостевые дополнения. Так как мы используем серверную 
 +    версию дистрибутиваа проверка замедляет запуск виртуальной мащины,​ то это вполне логично. 
 + 
 +Дальше [[#3. Создание ​собственного Vagrantfile|уже знакомая]] строчка - не проверять обновления образа. 
 + 
 +Теперь мы создаём цикл, который будет создавать машины, меняя название машины,​ 
 +хостнейм ​и 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>​ 
 + 
 +А в этом случае будет поднята только та машинакоторая указан. 
 +<​code>​ 
 +vagrant up node2 
 +</​code>​ 
 + 
 +Можно еще и так - задать сразу несколько машин. 
 +<​code>​ 
 +vagrant up node2 node3 
 +</​code>​ 
 + 
 +====Описываем каждую машину отдельно==== 
 + 
 +Вот пример Vagrantfile,​ в котором создаются 4 разных машины:​ 
 + 
 +<​code>​ 
 +# -*- mode: ruby -*- 
 +# vi: set ft=ruby : 
 + 
 +Vagrant.configure(2) do |config| 
 +  config.vm.box = "​ubuntu/​trusty64"​ 
 +  config.vm.box_check_update = false 
 + 
 + 
 +  config.vm.define "​dev"​ do |dev| 
 +      dev.vm.network ​ "​public_network",​ ip: "​192.168.1.160"​ 
 +      dev.vm.hostname = "​dev" ​  
 +      dev.vm.provider "​virtualbox"​ do |vb| 
 +         ​vb.memory = "​4096"​ 
 +      end 
 +  end 
 + 
 +   
 + ​config.vm.define "​db"​ do |db| 
 +     ​db.vm.network "​public_network",​ ip: "​192.168.1.161"​ 
 +     ​db.vm.hostname = "​db" ​  
 +     ​db.vm.provider "​virtualbox"​ do |vb| 
 +         ​vb.memory = "​1024"​ 
 +     end 
 + end 
 + 
 + 
 + ​config.vm.define "​ci"​ do |ci| 
 +     ​ci.vm.network "​public_network",​ ip: "​192.168.1.162"​ 
 +     ​ci.vm.hostname = "​ci" ​  
 +     ​ci.vm.provider "​virtualbox"​ do |vb| 
 +         ​vb.memory = "​2048"​ 
 +     end 
 + end 
 + 
 + ​config.vm.define "​lamp_node"​ do |lamp| 
 +     ​lamp.vm.network "​public_network",​ ip: "​192.168.1.163"​ 
 +     ​lamp.vm.hostname = "​lamp_node" ​  
 +     ​lamp.vm.provider "​virtualbox"​ do |vb| 
 +         ​vb.memory = "​512"​ 
 +     end 
 + end 
 + 
 +end 
 +</​code>​ 
 + 
 +Теперь разберём: 
 + 
 +прописываем глобальный конфиг для ​всех машин: 
 +<​code>​ 
 +config.vm.box = "​ubuntu/​trusty64"​ 
 +config.vm.box_check_update = false 
 +</​code>​ 
 + 
 +Далее создаём машины:​ 
 + 
 +<​code>​ 
 +  config.vm.define "​dev"​ do |dev| 
 +      dev.vm.network ​ "​public_network",​ ip: "​192.168.1.160"​ 
 +      dev.vm.hostname = "​dev" ​  
 +      dev.vm.provider "​virtualbox"​ do |vb| 
 +         ​vb.memory = "​4096"​ 
 +      end 
 +  end 
 +</​code>​ 
 +Всё почти так же, как при описании одной машины. 
 + 
 +В результате команды 
 + 
 +<​code>​ 
 +vagrant up  
 +</​code>​ 
 + 
 +у нас ​получится 4 машины:​ 
 + 
 +^ Имя машины ​   ^ ip адрес          ^ Хостнейм ​     ^ Память ^ 
 +|  dev    |     ​192.168.1.160 ​        | dev |         ​4096 ​ | 
 +|  db     ​| ​    ​192.168.1.161 ​        | db |          1024  | 
 +|  ci     ​| ​    ​192.168.1.162 ​        | ci |          2048  | 
 +|lamp_node| ​    ​192.168.1.163 ​        ​|lamp_node| ​    ​512 ​  | 
 + 
 +Все машины с Ubuntu внутри, без графического интерфейса, обновления отключены. 
 + 
 +Как можно понять по названиям,​ машины имеют разные назначения:​ 
 +dev - машина для разработчиков 
 +ci - машина для Сontinuous Integration server (Jenkins, TeamCity, etc) 
 +db - база данных 
 +lamp_node - машина для разворачивания LAMP-приложения. 
 + 
 +Для каждой отдельной машины можно переопределить глобальные конфигурации,​ 
 +например,​ переопределим образ в одной из машин с Ubuntu на CentOS: 
 +<​code>​ 
 +  config.vm.define "​dev"​ do |dev| 
 +      dev.vm.box = "​centos/​centos7"​ 
 +      dev.vm.network ​ "​public_network",​ ip: "​192.168.1.160"​ 
 +      dev.vm.hostname = "​dev" ​  
 +      dev.vm.provider "​virtualbox"​ do |vb| 
 +         ​vb.memory = "​4096"​ 
 +      end 
 +  end 
 +</​code>​ 
 + 
 +Теперь подумаем,​ что проект,​ над которым работает один разработчик,​ в 
 +современных реалиях,​ маловероятен. Тогда нам необходимо несколько машин для 
 +разработчиков. Решение вопроса ниже. 
 + 
 +====Используем цикл и отдельное описание машин==== 
 + 
 +Предположим,​ что у нас есть небольшой проект,​ в котором 5 разработчиков,​ один сервер непрерывной интеграции,​ две машины с базами данных(репликация и\или 
 +кластер). Добавим две ноды, на которые разворачивается приложение. И добавим машину,​ на которой будет крутиться балансировщик нагрузки (HAProxy, Nginx, 
 +httpd), он будет балансировать между нодами с приложениями. 
 +Итого 11 машин. Vagrantfile для всей инфраструктуры выглядит следующим образом:​ 
 + 
 + 
 +<​code>​ 
 +# -*- mode: ruby -*- 
 +# vi: set ft=ruby : 
 + 
 +#задаём переменные с количеством машин 
 + 
 +$dev_mach = 5 
 +$db_mach = 2 
 +$lamp_mach = 2 
 + 
 +Vagrant.configure(2) do |config| 
 +  config.vm.box = "​ubuntu/​trusty64"​ 
 +  config.vm.box_check_update = false 
 + 
 +#​Cоздаём машины для разработчиков,​ количество задали в переменных
 +#Пул ip адресов перенесли, чтоб не пересекались с другими машинами. 
 + 
 +   ​(1..$dev_mach).each do |i| 
 +        config.vm.define "​dev#​i"​ do |dev| 
 +         ​dev.vm.network ​ "​public_network",​ ip: "​192.168.1.#​{10+i}"​ 
 +         ​dev.vm.hostname = "​dev#​i" ​  
 +         ​dev.vm.provider "​virtualbox"​ do |vb| 
 +                vb.memory = "​4096"​ 
 +         end 
 +        end 
 +   end 
 + 
 + 
 +#​Создаём машины для баз данных. 
 + 
 +   ​(1..$db_mach).each do |i| 
 +        config.vm.define "​db#​i"​ do |db| 
 +         ​db.vm.network "​public_network",​ ip: "​192.168.1.#​{50+i}"​ 
 +         ​db.vm.hostname = "​db#​i" ​  
 +         ​db.vm.provider "​virtualbox"​ do |vb| 
 +                vb.memory = "​1024"​ 
 +         end 
 +        end 
 +   end 
 +оздамём машину для сервера непрерывной интеграции. 
 + 
 + ​config.vm.define "​ci"​ do |ci| 
 +     ​ci.vm.network "​public_network",​ ip: "​192.168.1.60"​ 
 +     ​ci.vm.hostname = "​ci" ​  
 +     ​ci.vm.provider "​virtualbox"​ do |vb| 
 +         ​vb.memory = "​2048"​ 
 +     end 
 + end 
 +#​Создаём машины для разворачивания приложения 
 + 
 +    (1..lamp_mach).each do |i| 
 +         ​config.vm.define "​lamp#​i"​ do |lamp| 
 +          lamp.vm.network "​public_network",​ ip: "​192.168.1.#​{150+i}"​ 
 +          lamp.vm.hostname = "​lamp_node#​i" ​  
 +          lamp.vm.provider "​virtualbox"​ do |vb| 
 +           ​vb.memory = "​512"​ 
 +          end 
 +         end 
 +     end 
 +#​Создаём машину для шлюза. 
 + 
 + ​config.vm.define "​gate"​ do |gate| 
 +     ​gate.vm.network "​public_network",​ ip: "​192.168.1.2"​ 
 +     ​gate.vm.hostname = "​gate" ​  
 +     ​gate.vm.provider "​virtualbox"​ do |vb| 
 +         ​vb.memory = "​2048"​ 
 +     end 
 + end 
 + 
 + 
 +end 
 +</​code>​ 
 + 
 +По традиции,​ сводная таблица поднятых машин после выполнения 
 +<​code>​ 
 +vagrant up 
 +</​code>​ 
 + 
 +^ Имя машины ​   ^ ip адрес ​         ^ Хостнейм ​     ^ Память ^ 
 +|  dev1    |     ​192.168.1.11 ​        ​| ​ dev1  |     ​4096 ​ | 
 +|  dev2    |     ​192.168.1.12 ​        ​| ​ dev2  |     ::: ​  | 
 +|  dev3    |     ​192.168.1.13 ​        ​| ​ dev3  |     ::: ​  | 
 +|  dev4    |     ​192.168.1.14 ​        ​| ​ dev4  |     ::: ​  | 
 +|  dev5    |     ​192.168.1.15 ​        ​| ​ dev5  |     ::: ​  | 
 +|  db1     ​| ​    ​192.168.1.51 ​        ​| ​ db1  |     ​1024 ​ | 
 +|  db2     ​| ​    ​192.168.1.52 ​        ​| ​ db2  |     ::: ​  | 
 +|  ci      |     ​192.168.1.60 ​        ​| ​ ci  |     ​2048 ​ | 
 +|lamp_node1| ​    ​192.168.1.151 ​       |lamp_node1| ​  ​512 ​  | 
 +|lamp_node2| ​    ​192.168.1.152 ​       |lamp_node2| ​  ::: ​  | 
 +|  gate    |     ​192.168.1.2 ​         |  gate  |     ​2048 ​ | 
 +  
 +Учитывая,​ что данный пример собран на основе предыдущих разделов,​ пояснять не буду - комментарии в коде дают всё необходимое. 
 + 
 +=====Vagrant provision===== 
 + 
 + 
 + 
 +Итак, у нас есть десяток машин. Некоторые из них одинаковы - ноды с приложением 
 +и машины со средой для разработки. В данном случае имеет смысл использовать 
 +подготовку машин. vagrant позволяет использовать несколько решений:​ 
 +  * **Puppet** 
 +  * **Ansible** 
 +  * **Salt** 
 +  * **Shell** 
 +  * **Chef** 
 +  * **Docker** 
 + 
 +При чём некоторые из них, например,​ Chef, Puppet, Salt имеют несколько вариантов 
 +использования (мастер-агент,​ без мастера, запуск локально). 
 + 
 +Автоматически provision запускается только в двух случаях:​ 
 + 
 +vagrant up и vagrant reload. Если вы хотите запустить подготовку машин 
 +принудительно,​ то необхожимо это явно указать. Например:​ 
 + 
 +<​code>​ 
 +vagrant resume --provision %machine_name 
 +</​code>​ 
 + 
 +<​code>​ 
 +vagrant provision %machine_name 
 +</​code>​ 
 + 
 +Рассмотрим самый простой вариант - shell. 
 + 
 +====Provisioning with shell==== 
 + 
 +В этом подразделе рассмотрим пост-конфигурацию машин с помощью shell. 
 +Парочка примеровестественно будет под Linux, хотя ​и PowerShell тоже годится. 
 + 
 +Чтоб vagrant исполнил код после загрузки необходимо добавить пару строк в 
 +Vagrantfile. 
 + 
 +===Выполнение одной команды=== 
 + 
 +Если необходимо выполнить одну команду (напримерудалить какой-то стандартный 
 +файл), то удобнее всего использовать следующую форму записи:​ 
 + 
 +<​code>​ 
 +Vagrant.configure("​2"​) do |config| 
 +  config.vm.provision "​shell",​ 
 +    inline: "echo Hello, World"​ 
 +end 
 +</​code>​ 
 + 
 +Эта строка задаёт тип провизора (подготовщика). Мы указали shell. 
 + 
 +<​code>​ 
 +config.vm.provision "​shell",​ 
 +</​code>​  
 + 
 +строкой 
 + 
 + 
 +<​code>​ 
 +inline: "echo Hello, World"​ 
 +</​code>​  
 + 
 +Мы задаём непосредственно команду. Всё, что идёт после двоеточия,​ будет 
 +выполнено в интерпретаторе по-умолчанию. 
 + 
 +Есть несколько полезных команд,​ которые могут использоваться вместе с shell. 
 + 
 +**args** - аргументы,​ которые будут переданы при выполнении команды или скрипта. 
 +Могут быть заданы как обычной строкой,​ так и массивом. 
 + 
 +Пример ниже показывает использование:​ 
 + 
 +<​code>​ 
 +Vagrant.configure("​2"​) do |config| 
 +  config.vm.provision "​shell"​ do |s| 
 +    s.inline = "echo $1" 
 +    s.args ​  = "'​hello,​ world!'"​ 
 +  end 
 +end 
 +</​code>​  
 + 
 +Обратите внимание на одинарные кавычки вокруг hello, world! 
 + 
 +они обязательны. 
 + 
 +Результатом будет вывод:​ 
 +hello, world!\\ 
 + 
 +Можно задать список аргументов массивом - это удобно тем, что можно не 
 +заморачиваться с кавычками и задать несколько аргументов:​ 
 + 
 +<​code>​ 
 +Vagrant.configure("​2"​) do |config| 
 +  config.vm.provision "​shell"​ do |s| 
 +    s.inline = "echo $1; touch $2" 
 +    s.args ​  = ["​hello,​ world!",​ "​new_file.txt"​] 
 +  end 
 +end 
 +</​code>​ 
 + 
 +**privileged** - определяет,​ от какого юзера запускать команду. По-умолчанию 
 +установленно True, что запустит скритп от root. Если команда должна запускаться 
 +от стандартного юзера (vagrant), то установите значения False. 
 + 
 + 
 +===Выполнение скрипта. Пишем скрипт на shell в Vagrantfile=== 
 + 
 +Если вам нужно выполнить не одну строку,​ а целый скрипт,​ то удобнее это сделать 
 +немного по-другому - как сказано в официальной документации - "​добавим совсем 
 +немного Ruby и получим отличный способ объеденить bash и Vagrantfile."​ 
 + 
 +<​code>​ 
 +$script = <<​END 
 +echo "I am provisioning..."​ 
 +touch 1.txt 
 +echo "​I'​m a text from Vagrantfile!"​ > 1.txt 
 +echo "File was created, you can test it now!"​ 
 +END 
 + 
 +Vagrant.configure("​2"​) do |config| 
 +  config.vm.provision "​shell",​ inline: $script 
 +end 
 +</​code>​ 
 + 
 +Тут мы создаём переменную script, в переменную пихаем нужные нам команды. 
 +Далее вызываем наш текст командой:​ 
 + 
 +<​code>​ 
 +  config.vm.provision "​shell",​ inline: $script 
 +</​code>​ 
 + 
 +Всё предельно просто.  
 + 
 +===Выполнение скрипта. Используем внешний файл=== 
 + 
 +Не трудно представить, что у большинства есть любимые,​ оттестированные годами 
 +скрипты, которые привыкли выполнять ​сразу же, после установки голой системы. 
 + 
 +В данном случае очень подойдёт умение vagrant выполнять внещние скрипты. 
 +Делается это следующим образом: 
 +<​code>​ 
 +Vagrant.configure("​2"​) do |config| 
 +  config.vm.provision "​shell",​ path: "​script.sh"​ 
 +end 
 +</​code>​ 
 + 
 +При этом, корень относится в директории с Vagrantfile,​ если он путь 
 +относительно. 
 + 
 +Без проблем можно использовать и абсолютные пути (нормально работают и вещи 
 +вроде ~) 
 + 
 +Есть очень полезная возможность - можно в path указать даже URL, по которому 
 +доступен скрипт. 
 + 
 +Если же у вас скрипт необходимо запустить из определённой директории внутри 
 +гостевой машины,​ vagrant позволяет делать и это. 
 +Необходимо лищь указать необходимую директорию командой **upload_path.** 
 + 
 +====Provisioning with Ansible==== 
 + 
 +<note important>​ Тут не будет рассматриваться работа непосредстваенно Ansible, 
 +рассматривается взаимодействие vagrant и Ansible! </​note>​ 
 + 
 +Если вы не знакомы с Ansible, то рекомендую,​ для начала прочесть [[Ansible 
 +|вот эту]] статью. 
 + 
 +При необходимости создать полноценное окружение разработчика,​ или если нужно 
 +развернуть СУБД и БД из дампа, то более целесообразно использовать более мощные 
 +инструменты. 
 +Одним из таких инструментов является Ansible. 
 + 
 +Чтобы применить Ansible через vagrant необходимо сделать следующее:​ 
 +  * на хостовой машине должен быть установлен Ansible 
 +  * прописать в Vagrantfile ((В этом разделе листинги взяты с официального сайта vagrant)) примерно следующее: 
 +<​code>​ 
 +Vagrant.configure("​2"​) do |config| 
 + 
 +  # 
 +  # Run Ansible from the Vagrant Host 
 +  # 
 +  config.vm.provision "​ansible"​ do |ansible| 
 +    ansible.playbook = "​playbook.yml"​ 
 +  end 
 + 
 +end 
 +</​code>​ 
 + 
 +При этом, Playbook.yml должен находиться в одном каталоге с Vagrantfile. 
 +После того, как машина будет поднята,​ vagrant запустит Ansible. 
 + 
 + 
 +Так как сам по себе Ansible не требует никакого агента на целевой машине (ноде),​ 
 +то всё, что нужно сделать - указать верные данные в инвентори-файле. 
 +Если используется публичная сеть, то указываем ip ноды, если используется 
 +приватная сеть, то необходимо указать ip локалхоста (обычно 127.0.0.1) и порт. 
 + 
 +Для Ansible имеется достаточно много опций, узнать их можно на 
 +[[https://​www.vagrantup.com/​docs/​provisioning/​ansible_common.htmlё|странице 
 +официальной документации vagrant]] 
 + 
 +Помимо того, что можно запускать Ansible с хоста, его можно также запускать и в 
 +самой гостевой мащине. Называется это [[https://​www.vagrantup.com/​docs/​provisioning/​ansible_local.html|Ansible local]]. 
 + 
 +Преимущество в том, что нет необходимости устанавливать Ansible на хост. Вы 
 +можете просто загрузить роль с вашего репозитория или с Ansible galaxy и она 
 +выполнится. 
 + 
 +Недостатки - на каждую машину необходимо устанавливать Ansible (есть хук, о нём ниже), отсутствие централизованного управления. То есть, если в дальнейшем будет необходимость управлять машинами посредством Ansible, то этот метод не для вас. 
 + 
 + 
 +По-умолчанию,​ vagrant попробует сам установить Ansible на гостувую машину,​ для этот предусмтрено несколько опций:​ 
 + 
 +**install_mode** - по-факту,​ это выбор репозитория,​ откуда будет устанавливаться 
 +Ansible. Если оставить значение __default__,​ то будет выбран:​ 
 + 
 +  -ppa:​ansible/​ansible - для гостя Ubuntu + family 
 +  -EPEL - RedHat-family 
 +  -main repo - Debian, OpenSuse, FreeBSD, Arch, etc. 
 + 
 +Есть другое значение - pip. Тогда установка будет производиться посредтсвом pip. 
 +vagrant сначала установит pip на гостя, а затем установит Ansible. 
 + 
 +Этот вариант предпочтительней,​ так как это гарантирует,​ что версия будет свежая 
 +и одинаковая для всех нод. 
 + 
 +Часть Vagrantfile,​ которая отвечает ​ за Ansible local практически ничем не 
 +отличается от обычного Ansible: 
 + 
 +<​code>​ 
 +Vagrant.configure("​2"​) do |config| 
 +  config.vm.provision "​ansible_local"​ do |ansible| 
 +    ansible.playbook = "​playbook.yml"​ 
 +  end 
 +end 
 +</​code>​ 
 + 
 + 
 +Подробнее о хуке, а именно о том, как использовать Ansible local для создания полноценной инфраструктуры. С помощью ​одного Vagrantfile можно создать ноды, которые будут ​разворачиваться Ansible, который установлен в виртуальной машине. 
 + 
 +Всё, что нужно сделать вам - написать Vagrantfile,​ роли для Ansible с inventory 
 +и немного подправить конфигурацию Ansible. 
 + 
 +Разберём всё подробнее. 
 + 
 +Vagrantfile:​ 
 + 
 +<​code>​ 
 +Vagrant.configure("​2"​) do |config| 
 + 
 +  config.vm.box = "​ubuntu/​trusty64"​ 
 + 
 +  config.vm.define "​node1"​ do |machine| 
 +    machine.vm.network "​private_network",​ ip: "​172.17.177.21"​ 
 +  end 
 + 
 +  config.vm.define "​node2"​ do |machine| 
 +    machine.vm.network "​private_network",​ ip: "​172.17.177.22"​ 
 +  end 
 + 
 +  config.vm.define '​controller'​ do |machine| 
 +    machine.vm.network "​private_network",​ ip: "​172.17.177.11"​ 
 + 
 +    machine.vm.provision :​ansible_local do |ansible| 
 +      ansible.playbook ​      = "​example.yml"​ 
 +      ansible.verbose ​       = true 
 +      ansible.install ​       = true 
 +      ansible.limit ​         = "​all"​ 
 +      ansible.inventory_path = "​inventory"​ 
 +    end 
 +  end 
 + 
 +end 
 + 
 +</​code>​  
 + 
 +Создаём две машины - node1 и node2. Это будут машины,​ которые мы будем 
 +конфигурировать с помощью Ansible, который установим на третью машину - 
 +controller. 
 + 
 +vagrant сам установит на нужную машину Ansible. Что нам нужно - так это сделать 
 +нормальный инвентори файл, в котором будут указаны ip адреса наших нод. 
 + 
 +Вот ​пример для этого файла:​ 
 + 
 + 
 +<​code>​ 
 +controller ansible_connection=local 
 +node1      ansible_ssh_host=172.17.177.21 ansible_ssh_private_key_file=/​vagrant/​.vagrant/​machines/​node1/​virtualbox/​private_key 
 +node2      ansible_ssh_host=172.17.177.22 ansible_ssh_private_key_file=/​vagrant/​.vagrant/​machines/​node2/​virtualbox/​private_key 
 +</​code>​  
 + 
 +И этот файлик положим ​в директорию с Vagrantfile,​ в корень. 
 + 
 +Последний штрих - нам необходимо создать свой файл Ansible.cfg. В нём мы укажем,​ 
 +некоторые опции для ssh-коннекта,​ а именно - подключаться ко всем хостам без 
 +подтверждения 
 + 
 +<​code>​ 
 +[defaults] 
 +host_key_checking = no 
 + 
 +[ssh_connection] 
 +ssh_args = -o ControlMaster=auto -o ControlPersist=60s -o UserKnownHostsFile=/​dev/​null -o IdentitiesOnly=yes 
 + 
 +</​code>​ 
 + 
 +Всё, можно делать vagrant up и смотреть,​ как создаётся окружение. 
 + 
 +====Provisioning with Puppet==== 
 + 
 +<note important>​ Тут не будет рассматриваться работа непосредстваенно Puppet, 
 +рассматривается взаимодействие vagrant и Puppet! </​note>​ 
 + 
 +Для тех, кто привык использовать [[https://​puppet.com/​|Puppet]],​ есть возможность использовать этот 
 +инструмент с vagrant. 
 + 
 +Для этого нам нужна следующая структура Vagrantfile:​ 
 +<​code>​ 
 + ​config.vm.provider "​virtualbox"​ do |vb| 
 +     ​vb.gui = false 
 +     ​vb.memory=256 
 +     ​vb.cpus=1 
 +     ​vb.check_guest_additions=false 
 + ​config.vm.box="​puppetlabs/​centos-7.2-64-puppet"​ 
 +end 
 + ​config.vm.define "​node1"​ do |n1| 
 +   ​n1.vm.network "​private_network",​ ip: "​192.168.0.101"​ 
 +   ​n1.vm.network "​forwarded_port",​ guest: 80, host: 8081 
 +   ​n1.vm.hostname ="​node1"​ 
 + end 
 +</​code>​ 
 +Основное изменение,​ которое отличает vagrant и Puppet, от vagrant и Ansible - 
 +vagrant **не** может сам установить Puppet в гостя, поэтому строкой 
 +<​code>​ 
 +config.vm.box="​puppetlabs/​centos-7.2-64-puppet"​ 
 +</​code>​ 
 +Мы сказали,​ что в качестве основы для гостя необходимо использовать специальный,​ 
 +официальный дистрибутив от команды Puppet, в котором уже будет присутствовать 
 +агент. 
 +<​note>​ 
 +докер, паппет.
 </​note>​ </​note>​
  
-  ​* [[FIXME]]+ * [[FIXME]]
 {{tag>​vagrant}} {{tag>​vagrant}}