Оглавление:
В теме описано использование vagrant с провайдером VirtualBox.
Подробное содержание доступно справа.
Установка vagrant + VirtualBox
Устанавливать будем с официального сайта, скачав подходящие deb-пакеты.
ссылка на х64 версию VirtualBox для 14.04
Скачиваем и устанавливаем 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
Всё готово для использования.
Создаём машину по-умолчанию
Для того, чтоб создать виртуальную машину со стандартными настройками вполне достаточно выполнить две команды:
vagrant init
эта команда в текущей директории создат Vagrantfile (можете посмотреть его в
vim любимом текстовом редакторе), который будет считывать следующей командой:
vagrant up
Эта команда скачает базовый образ из репозитория vagrant и на его основе создаст виртуальную машину для VirtualBox.
- Маленькие прелести vagrant:
- Автоматическое подмонтирование корневой директории (с Vagrantfile`ом) в гостя;
- Автоматический проброс порта для ssh (хост — 2222, гость — 22);
- Создание ssh-ключей;
- чтоб подключиться к машине, достаточно выполнить
vagrant ssh
И всё, мы внутри гостя.
Создаём собственный 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
тут
vagrant, VBox и сеть
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"
и адрес назначится автоматически.
больше информации о приватных сетях
тут
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"
больше информации о публичных сетях
тут
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"
Синхронизация каталогов
«Из коробки» vagrant синхронизирует каталог хоста с Vagrantfile в директорию /vagrant виртуальной машины.
Для того, чтоб указать дополнительный каталоги для синхронизации, нужно добавить следующую строку в Vagrantfile:
config.vm.synced_folder "src/", "/var/www/html"
Первым указывается путь на хосте, вторым — гостевой путь.
Если на хостовой машине указывать относительный путь, то корневым будет каталог с Vagrantfile.
Если абсолютный путь, то он абсолютный 🙂
Путь на гостевой машине должен быть только абсолютный.
Если директорий не существует, они будут созданы рекурсивно.
Дополнительные опции:
- disabled — если указать True, то синхронизация будет отключена. Удобно, если нам не нужна «изкоробочная» синхронизация.
- mount_options — дополнительные параметры, которые будут переданы команде mount при монтировании
- type — полезная опция, которая позволяет выбрать тип синхронизации. Доступны следующие варианты:
- NFS
- rsync
- SMB
- VirtualBox
-
Если эта поция не указана, то vagrant выберет сам подходящую.
Я рекомендую для Linux-гостей использовать rsync — этот тип не требует дополнений гостевых систем, автоматически установить rsync на всех гостей.
Также, доступны дополнительные плюшки, такие как vagrant rsync и vagrant rsync-auto ( о них ниже)
- id — имя, которое будет показываться при команде mount в гостевой
машине. Имеет смысл использовать, если у вас несколько расшареных каталогов
Рассмотрим подробнее вариант rsync
Первое — этот тип работает только в одну сторону
Каталоги, которые синхронизированы через rsync синхронизируются автоматически только один раз — при инициализации машины (vagrant upvagrant reload).
Принудительно синхронизировать можно двумя путями:
- vagrant rsync
- vagrant rsync-auto
Отличия можно понять по названиям:
первый вариант запускается один раз (синхронизировал и всё).
области синхронизации, то вам необходимо перед vagrant rsync сделать vagrant
reload.
Второй же работает в режиме демона и отслеживает изменения на хосте. Это удобно, так как один каталог можно шарить на несколько машин сразу, передавая изменения на всех гостей.
остановите vagrant rsync-auto, внесите изменения, и потом перезапустите.
Для rsync есть куча опций, которые обычно не нужны. На мой взгляд, одна из самых
полезных — rsync_exclude. (аналог gitignore)
Опция позволяет исключить из списка синхронизации, которые не нужны.
Это нужно, когда у вас есть директория, в которой содержится 1005 файлов. И вам
нужно синхронизировать 1000, а 5 — не нужно.
Гораздо проще исключить 5 файлов, чем добавлять 1000.
Использование команд 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
Эта команда перезагрузки — сначала выключает машину, потом поднимает.
Удобно, если надо применить изменения в конфигурации
Более подробно о других команда можно узнать на официальном сайте
Конфигурирование нескольких машин
В одном Vagrantfile может быть столько машин, сколько нам нужно.
Задать их можно двумя способами:
- Используя цикл
- Отдельно задавая каждую машину
Очевидно, что циклом удобно поднимать машины, которые буду отличаться только
названием, хостнеймом и, возможно, ip адресом (параметры, которые можно
итерировать).
Другие параметры системы, такие как память, процессор, синхронизированные
каталоги задать нельзя.
Это могут быть ноды кластера, ноды для балансировщика или если вам нужно поднять
пару десятков одинаковых машин для тестировщиков или разработчиков.
При конфигурировании каждой мащины отдельно мы имеем гораздо больше
возможностей, но и писать придётся больше.
Использование цикла
$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, а именно задаёт:
- консольный режим (без интерфейса)
- 256 Мб памяти
- 1 виртуальный процессор
- отменяем проверку на гостевые дополнения. Так как мы используем серверную
версию дистрибутива, а проверка замедляет запуск виртуальной мащины, то это вполне логично.
Дальше уже знакомая строчка — не проверять обновления образа.
Теперь мы создаём цикл, который будет создавать машины, меняя название машины,
хостнейм и 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 |
Работать с таким файлом можно двумя способами:
в этом случае будут подняты все машины, конфиги которых присутствуют.
vagrant up
А в этом случае будет поднята только та машина, которая указан.
vagrant up node2
Можно еще и так — задать сразу несколько машин.
vagrant up node2 node3
Описываем каждую машину отдельно
Вот пример Vagrantfile, в котором создаются 4 разных машины:
# -*- 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
Теперь разберём:
прописываем глобальный конфиг для всех машин:
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
Всё почти так же, как при описании одной машины.
В результате команды
vagrant up
у нас получится 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:
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
Теперь подумаем, что проект, над которым работает один разработчик, в
современных реалиях, маловероятен. Тогда нам необходимо несколько машин для
разработчиков. Решение вопроса ниже.
Используем цикл и отдельное описание машин
Предположим, что у нас есть небольшой проект, в котором 5 разработчиков, один сервер непрерывной интеграции, две машины с базами данных(репликация иили
кластер). Добавим две ноды, на которые разворачивается приложение. И добавим машину, на которой будет крутиться балансировщик нагрузки (HAProxy, Nginx,
httpd), он будет балансировать между нодами с приложениями.
Итого 11 машин. Vagrantfile для всей инфраструктуры выглядит следующим образом:
# -*- 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
По традиции, сводная таблица поднятых машин после выполнения
vagrant up
Имя машины | 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. Если вы хотите запустить подготовку машин
принудительно, то необхожимо это явно указать. Например:
vagrant resume --provision %machine_name
vagrant provision %machine_name
Рассмотрим самый простой вариант — shell.
Provisioning with shell
В этом подразделе рассмотрим пост-конфигурацию машин с помощью shell.
Парочка примеров, естественно будет под Linux, хотя и PowerShell тоже годится.
Чтоб vagrant исполнил код после загрузки необходимо добавить пару строк в
Vagrantfile.
Выполнение одной команды
Если необходимо выполнить одну команду (например, удалить какой-то стандартный
файл), то удобнее всего использовать следующую форму записи:
Vagrant.configure("2") do |config| config.vm.provision "shell", inline: "echo Hello, World" end
Эта строка задаёт тип провизора (подготовщика). Мы указали shell.
config.vm.provision "shell",
строкой
inline: "echo Hello, World"
Мы задаём непосредственно команду. Всё, что идёт после двоеточия, будет
выполнено в интерпретаторе по-умолчанию.
Есть несколько полезных команд, которые могут использоваться вместе с shell.
args — аргументы, которые будут переданы при выполнении команды или скрипта.
Могут быть заданы как обычной строкой, так и массивом.
Пример ниже показывает использование:
Vagrant.configure("2") do |config| config.vm.provision "shell" do |s| s.inline = "echo $1" s.args = "'hello, world!'" end end
Обратите внимание на одинарные кавычки вокруг hello, world!
они обязательны.
Результатом будет вывод:
hello, world!
Можно задать список аргументов массивом — это удобно тем, что можно не
заморачиваться с кавычками и задать несколько аргументов:
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
privileged — определяет, от какого юзера запускать команду. По-умолчанию
установленно True, что запустит скритп от root. Если команда должна запускаться
от стандартного юзера (vagrant), то установите значения False.
Выполнение скрипта. Пишем скрипт на shell в Vagrantfile
Если вам нужно выполнить не одну строку, а целый скрипт, то удобнее это сделать
немного по-другому — как сказано в официальной документации — «добавим совсем
немного Ruby и получим отличный способ объеденить bash и Vagrantfile.»
$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
Тут мы создаём переменную script, в переменную пихаем нужные нам команды.
Далее вызываем наш текст командой:
config.vm.provision "shell", inline: $script
Всё предельно просто.
Выполнение скрипта. Используем внешний файл
Не трудно представить, что у большинства есть любимые, оттестированные годами
скрипты, которые привыкли выполнять сразу же, после установки голой системы.
В данном случае очень подойдёт умение vagrant выполнять внещние скрипты.
Делается это следующим образом:
Vagrant.configure("2") do |config| config.vm.provision "shell", path: "script.sh" end
При этом, корень относится в директории с Vagrantfile, если он путь
относительно.
Без проблем можно использовать и абсолютные пути (нормально работают и вещи
вроде ~)
Есть очень полезная возможность — можно в path указать даже URL, по которому
доступен скрипт.
Если же у вас скрипт необходимо запустить из определённой директории внутри
гостевой машины, vagrant позволяет делать и это.
Необходимо лищь указать необходимую директорию командой upload_path.
Provisioning with Ansible
рассматривается взаимодействие vagrant и Ansible!
Если вы не знакомы с Ansible, то рекомендую, для начала прочесть вот эту статью.
При необходимости создать полноценное окружение разработчика, или если нужно
развернуть СУБД и БД из дампа, то более целесообразно использовать более мощные
инструменты.
Одним из таких инструментов является Ansible.
Чтобы применить Ansible через vagrant необходимо сделать следующее:
- на хостовой машине должен быть установлен Ansible
- прописать в Vagrantfile 1) примерно следующее:
Vagrant.configure("2") do |config| # # Run Ansible from the Vagrant Host # config.vm.provision "ansible" do |ansible| ansible.playbook = "playbook.yml" end end
При этом, Playbook.yml должен находиться в одном каталоге с Vagrantfile.
После того, как машина будет поднята, vagrant запустит Ansible.
Так как сам по себе Ansible не требует никакого агента на целевой машине (ноде),
то всё, что нужно сделать — указать верные данные в инвентори-файле.
Если используется публичная сеть, то указываем ip ноды, если используется
приватная сеть, то необходимо указать ip локалхоста (обычно 127.0.0.1) и порт.
Для Ansible имеется достаточно много опций, узнать их можно на
странице
официальной документации vagrant
Помимо того, что можно запускать Ansible с хоста, его можно также запускать и в
самой гостевой мащине. Называется это 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:
Vagrant.configure("2") do |config| config.vm.provision "ansible_local" do |ansible| ansible.playbook = "playbook.yml" end end
Подробнее о хуке, а именно о том, как использовать Ansible local для создания полноценной инфраструктуры. С помощью одного Vagrantfile можно создать ноды, которые будут разворачиваться Ansible, который установлен в виртуальной машине.
Всё, что нужно сделать вам — написать Vagrantfile, роли для Ansible с inventory
и немного подправить конфигурацию Ansible.
Разберём всё подробнее.
Vagrantfile:
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
Создаём две машины — node1 и node2. Это будут машины, которые мы будем
конфигурировать с помощью Ansible, который установим на третью машину —
controller.
vagrant сам установит на нужную машину Ansible. Что нам нужно — так это сделать
нормальный инвентори файл, в котором будут указаны ip адреса наших нод.
Вот пример для этого файла:
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
И этот файлик положим в директорию с Vagrantfile, в корень.
Последний штрих — нам необходимо создать свой файл Ansible.cfg. В нём мы укажем,
некоторые опции для ssh-коннекта, а именно — подключаться ко всем хостам без
подтверждения
[defaults] host_key_checking = no [ssh_connection] ssh_args = -o ControlMaster=auto -o ControlPersist=60s -o UserKnownHostsFile=/dev/null -o IdentitiesOnly=yes
Всё, можно делать vagrant up и смотреть, как создаётся окружение.
Provisioning with Puppet
рассматривается взаимодействие vagrant и Puppet!
Для тех, кто привык использовать Puppet, есть возможность использовать этот
инструмент с vagrant.
Для этого нам нужна следующая структура Vagrantfile:
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
Основное изменение, которое отличает vagrant и Puppet, от vagrant и Ansible —
vagrant не может сам установить Puppet в гостя, поэтому строкой
config.vm.box="puppetlabs/centos-7.2-64-puppet"
Мы сказали, что в качестве основы для гостя необходимо использовать специальный,
официальный дистрибутив от команды Puppet, в котором уже будет присутствовать
агент.
* FIXME
В этом разделе листинги взяты с официального сайта vagrant
http://help.ubuntu.ru/wiki/vagrant
- Автоматическое монтирование fstab и systemd - 24.02.2021
- Как в Linux подключить новый диск, разметить и отформатировать разделы - 24.02.2021
- Как сменить режим работы PHP - 24.02.2021