Различия
Здесь показаны различия между двумя версиями данной страницы.
| Предыдущая версия справа и слева Предыдущая версия Следующая версия | Предыдущая версия | ||
|
wiki:vagrant [2016/07/24 13:25] [Использование цикла] |
wiki:vagrant [2016/08/26 22:44] (текущий) [Provisioning with Puppet] |
||
|---|---|---|---|
| Строка 6: | Строка 6: | ||
| ===== Установка 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]] | ||
| Строка 47: | Строка 46: | ||
| <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> | ||
| И всё, мы внутри гостя. | И всё, мы внутри гостя. | ||
| - | ===== Создание собственного 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 | ||
| Строка 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|тут]] | ||
| Строка 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|тут]] | ||
| - | ==== 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> |
| + | config.vm.network "forwarded_port", guest: 35555, host: 12003, protocol: "udp" | ||
| + | </code> | ||
| ===== Синхронизация каталогов===== | ===== Синхронизация каталогов===== | ||
| - | "Из коробки" 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 | ||
| Строка 260: | Строка 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 в гостевой | ||
| машине. Имеет смысл использовать, если у вас несколько расшареных каталогов | машине. Имеет смысл использовать, если у вас несколько расшареных каталогов | ||
| Строка 272: | Строка 284: | ||
| ==Рассмотрим подробнее вариант rsync== | ==Рассмотрим подробнее вариант rsync== | ||
| Первое - этот тип **работает** только **в одну сторону** | Первое - этот тип **работает** только **в одну сторону** | ||
| - | Каталоги, которые синхронизированы через rsync синхронизируются автоматически | + | Каталоги, которые синхронизированы через rsync синхронизируются автоматически только один раз - при инициализации машины (vagrant up\vagrant reload). |
| - | только один раз - при инициализации машины (vagrant up\vagrant reload). | + | |
| Принудительно синхронизировать можно двумя путями: | Принудительно синхронизировать можно двумя путями: | ||
| - vagrant rsync | - vagrant rsync | ||
| Строка 284: | Строка 295: | ||
| reload. </note> | reload. </note> | ||
| - | Второй же работает в режиме демона и отслеживает изменения на хосте. | + | Второй же работает в режиме демона и отслеживает изменения на хосте. Это удобно, так как один каталог можно шарить на несколько машин сразу, передавая изменения на всех гостей. |
| - | Это удобно, так как один каталог можно шарить на несколько машин сразу, | + | |
| - | передавая изменения на всех гостей. | + | |
| <note important>Если вы хотите сделать изменения в Vagrantfile, для начали | <note important>Если вы хотите сделать изменения в Vagrantfile, для начали | ||
| Строка 319: | Строка 328: | ||
| Для того, чтоб удалить машину без подтверждения, используйте ключ -f | Для того, чтоб удалить машину без подтверждения, используйте ключ -f | ||
| - | <code>vagrant destroy -f </code> | + | <code> |
| + | vagrant destroy -f | ||
| + | </code> | ||
| <note warning>Всегда сначала уничтожайте машину, а только потом удаляйте её из | <note warning>Всегда сначала уничтожайте машину, а только потом удаляйте её из | ||
| Строка 349: | Строка 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 | ||
| ------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | ||
| Строка 368: | Строка 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: | Строка 394: | ||
| ===== Конфигурирование нескольких машин===== | ===== Конфигурирование нескольких машин===== | ||
| - | В одном Vagrantfile может быть столько мащин, сколько нам нужно. | + | В одном Vagrantfile может быть столько машин, сколько нам нужно. |
| Задать их можно двумя способами: | Задать их можно двумя способами: | ||
| * Используя цикл | * Используя цикл | ||
| - | * Отдельно задавая каждую мащину | + | * Отдельно задавая каждую машину |
| Очевидно, что циклом удобно поднимать машины, которые буду отличаться только | Очевидно, что циклом удобно поднимать машины, которые буду отличаться только | ||
| Строка 421: | Строка 434: | ||
| | | ||
| end | end | ||
| - | </code> | + | </code> |
| Первая строчки - мы создали переменную mach_quant и присвоили ей значение 3. | Первая строчки - мы создали переменную mach_quant и присвоили ей значение 3. | ||
| Строка 448: | Строка 461: | ||
| Работать с таким файлом можно двумя способами: | Работать с таким файлом можно двумя способами: | ||
| в этом случае будут подняты все машины, конфиги которых присутствуют. | в этом случае будут подняты все машины, конфиги которых присутствуют. | ||
| - | <code> vagrant up</code> | + | <code>vagrant up</code> |
| А в этом случае будет поднята только та машина, которая указан. | А в этом случае будет поднята только та машина, которая указан. | ||
| - | <code> vagrant up node2</code> | + | <code> |
| + | vagrant up node2 | ||
| + | </code> | ||
| Можно еще и так - задать сразу несколько машин. | Можно еще и так - задать сразу несколько машин. | ||
| - | <code> vagrant up node2 node3</code> | + | <code> |
| + | vagrant up node2 node3 | ||
| + | </code> | ||
| ====Описываем каждую машину отдельно==== | ====Описываем каждую машину отдельно==== | ||
| Строка 460: | Строка 477: | ||
| Вот пример Vagrantfile, в котором создаются 4 разных машины: | Вот пример Vagrantfile, в котором создаются 4 разных машины: | ||
| - | <code> # -*- mode: ruby -*- | + | <code> |
| + | # -*- mode: ruby -*- | ||
| # vi: set ft=ruby : | # vi: set ft=ruby : | ||
| Строка 503: | Строка 521: | ||
| end | end | ||
| - | </code> | + | </code> |
| Теперь разберём: | Теперь разберём: | ||
| прописываем глобальный конфиг для всех машин: | прописываем глобальный конфиг для всех машин: | ||
| - | <code>config.vm.box = "ubuntu/trusty64" | + | <code> |
| + | config.vm.box = "ubuntu/trusty64" | ||
| config.vm.box_check_update = false | config.vm.box_check_update = false | ||
| - | </code> | + | </code> |
| Далее создаём машины: | Далее создаём машины: | ||
| Строка 527: | Строка 546: | ||
| В результате команды | В результате команды | ||
| - | <code>vagrant up </code> | + | <code> |
| + | vagrant up | ||
| + | </code> | ||
| у нас получится 4 машины: | у нас получится 4 машины: | ||
| - | ^ Имя машины ^ ip адрес ^ Хостнейм ^ Память ^ | + | ^ Имя машины ^ ip адрес ^ Хостнейм ^ Память ^ |
| - | | dev | 192.168.1.160 | dev | 4096 | | + | | dev | 192.168.1.160 | dev | 4096 | |
| - | | db | 192.168.1.161 | db | 1024 | | + | | db | 192.168.1.161 | db | 1024 | |
| - | | ci | 192.168.1.162 | ci | 2048 | | + | | ci | 192.168.1.162 | ci | 2048 | |
| - | |lamp_node| 192.168.1.163 |lamp_node| 512 | | + | |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> | ||
| - | * [[FIXME]] | + | * [[FIXME]] |
| {{tag>vagrant}} | {{tag>vagrant}} | ||