В предыдущих статьях мы немного познакомились с Vagrantfile и боксами, теперь поговорим о такой штуке, как версионность. Также, как системы управления версиями (к примеру, git, svn), vagrant имеет версионность создаваемых боксов. Vagrant имеет целое облачное хранилище боксов — atlas.hashicorp.com где храниться уйма боксов с различными ОС (при создании ВМ vagrant сначала проверить есть ли нужный бокс локально, а потом полезет искать на atlas сайт, если не найдет). К примеру, мы создали свой Ubuntu 14.04 бокс. Прошло 2 месяца, и мы видим, что много пакетов и заплаток безопасности нужно обновить. Чтобы не делать эти обновления каждый раз, когда создается новая ВМ из этого бокса, мы обновляемся и создаем новый бокс. Теперь новый бокс нужно добавить в систему, но в данном случаи нам придется менять название, так как уже есть старый с таким же именем. Проблема. Теперь нужно удалять старый, либо называть новый по-другому.
Чтобы избежать данной проблемы – нужно использовать версионность. Свои боксы можно заливать на atlas, то я предпочитаю сделать свой маленький хостинг custom-ных боксов. Принцип следующий: подымается отдельный сервер, на котором будут доступны все созданные боксы всех версий. Сервере виртуальных машин будет использовать в роли репозитория боксов уже не atlas.hashicorp.com, а наш URL, прописанный в Vagrantfile.
Не знаю, как это все прозвучало для читателя, но после примера все станет на свои места.
Будем настраивать следующею схему (рис. 1).
В данном примере будет использоваться локальный Windows 10 сервер в роли сервера виртуальных машин (VMs server) и удаленный Ubuntu в роли Веб-сервера с Vagrant боксами.
1 Создание первоначального бокса
У меня уже есть виртуальная машина «Ubuntu 16.04 Template» (рис. 2) подготовленная к созданию бокса (как подготовить, можно посмотреть в этой статье http://sysadm.pp.ua/linux/sistemy-virtualizacii/vagrant-box-creation.html).
Создаем новый контейнер.
PS D:\Work\Vagrant\custom_boxes> vagrant package --base 'Ubuntu 16.04 Template' --output Ubuntu16.04_1.0.0.box ==> Ubuntu 16.04 Template: Exporting VM... ==> Ubuntu 16.04 Template: Compressing package to: D:/Work/Vagrant/custom_boxes/Ubuntu16.04_1.0.0.box
Теперь у нас есть образ первоначального бокса Ubuntu 16.04 версии 1.0.0.
Добавляем созданный бокс в список доступных.
PS D:\Work\Vagrant\custom_boxes> vagrant box add .\Ubuntu16.04_1.0.0.box --name "Ubuntu 16.04" ==> box: Box file was not detected as metadata. Adding it directly... ==> box: Adding box 'Ubuntu 16.04' (v0) for provider: box: Unpacking necessary files from: file://D:/Work/Vagrant/custom_boxes/Ubuntu16.04_1.0.0.box box: Progress: 100% (Rate: 37.2M/s, Estimated time remaining: --:--:--) ==> box: Successfully added box 'Ubuntu 16.04' (v0) for 'virtualbox'! PS D:\Work\Vagrant\custom_boxes> vagrant box list Ubuntu 16.04 (virtualbox, 0)
Как видим, у нас есть бокс ‘Ubuntu 16.04’. Теперь создаем виртуальную машину на его основе.
PS D:\Work\Vagrant\custom_boxes> cd ..\ubuntu16_04\ PS D:\Work\Vagrant\ubuntu16_04> vagrant init PS D:\Work\Vagrant\ubuntu16_04> cat Vagrantfile … Vagrant.configure("2") do |config| config.vm.box = "Ubuntu 16.04" end … PS D:\Work\Vagrant\ubuntu16_04> vagrant up
После этого, у нас запуститься образ Ubuntu 16.04.
Это стандартный способ создания виртуальной машины с бокса. На данном этапе, можно удалить ВМ с боксом (так как нам нужен только запакованный контейнер) и перейти к настройке репозитория.
PS D:\Work\Vagrant\ubuntu16_04> vagrant destroy PS D:\Work\Vagrant\ubuntu16_04> vagrant box remove 'Ubuntu 16.04' Removing box 'Ubuntu 16.04' (v0) with provider 'virtualbox'...
2 Настройка Vagrant box репозитория
Теперь можно настроить Веб-сервер, на котором будут хостится vagrant боксы. Переходим на ‘Vagrant boxes server’, устанавливаем веб-сервер apache и настраиваем виртуальный хост.
root@vghost:~# apt-get install apache2 -y root@vghost:~# cat /etc/apache2/sites-enabled/000-default.conf … <VirtualHost *:80> ServerName my-vagrant-repo.home.ua ServerAdmin webmaster@localhost DocumentRoot /var/www/html/vagrant_boxes ErrorLog ${APACHE_LOG_DIR}/my-vagrant-repo.home.ua_error.log CustomLog ${APACHE_LOG_DIR}/my-vagrant-repo.home.ua_access.log combined </VirtualHost> … root@vghost:~# service apache2 restart
Теперь добавляем каталог. Каталог являет собой JSON файлик в котором прописаны все версии определенного бокса в специфичном формате. Первым у нас будет ранее созданный Ubuntu 16.04. Заливаем образ на сервер и берем md5 сумму.
root@vghost:~# md5sum /var/www/html/vagrant_boxes/ubuntu_16.04/Ubuntu16.04_1.0.0.box 72f0b69b12bdac1307efee3537ea31aa vagrant_boxes/ubuntu_16.04/Ubuntu16.04_1.0.0.box
Теперь создаем json файлик и описываем наш первый бокс.
root@vghost:~# cat /var/www/html/vagrant_boxes/ubuntu_16.04/ubuntu_16.04.json { "name": "Ubuntu 16.04", "description": "Ubuntu 16.04 LTS 64-bit box", "versions": [{ "_comment": "Initial Ubuntu 16.04 box", "version": "1.0.0", "providers": [{ "name": "virtualbox", "url": "http://my-vagrant-repo.home.ua/ubuntu_16.04/Ubuntu16.04_1.0.0.box", "checksum_type": "md5", "checksum": "72f0b69b12bdac1307efee3537ea31aa" }] }] }
Как видим, здесь описано имя бокса, его версия и информация о провайдере (в данном случае это virtualbox) с прямой ссылкой на образ скомплектованного бокса. Ссылка также может быть в виде пути к файлу.
… "url": "file:///var/www/html/vagrant_boxes/ubuntu_16.04/Ubuntu16.04_1.0.0.box" …
Теперь каталог готов и состоит из одной версии Ubuntu 16.04.
3 Тестирование Vagrant репозитория
Теперь нам нужно скачать и добавить новый бокс. Это будет седлано автоматически, при создании новой виртуальной машины, только нужно прописать URL нашей репы. Домен я придумал, так что нужно прописать в hosts нужный резолв или добавить в DNS.
PS D:\Work\Vagrant\ubuntu16_04> cat C:\Windows\System32\drivers\etc\hosts 192.168.5.50 my-vagrant-repo.home.ua
Обновляем Vagrantfile.
PS D:\Work\Vagrant\ubuntu16_04> cat Vagrantfile Vagrant.configure("2") do |config| config.vm.box = "Ubuntu 16.04" config.vm.box_url = "http://my-vagrant-repo.home.ua/ubuntu_16.04/ubuntu_16.04.json" config.vm.provider "virtualbox" do |vb| vb.name = 'My Ubuntu 16.04' end end
Имя новой виртуалки будет «My Ubuntu 16.04».
Запускаем ВМ.
PS D:\Work\Vagrant\ubuntu16_04> vagrant up Bringing machine 'default' up with 'virtualbox' provider... ==> default: Box 'Ubuntu 16.04' could not be found. Attempting to find and install... default: Box Provider: virtualbox default: Box Version: >= 0 ==> default: Loading metadata for box 'http://my-vagrant-repo.home.ua/ubuntu_16.04/ubuntu_16.04.json' default: URL: http://my-vagrant-repo.home.ua/ubuntu_16.04/ubuntu_16.04.json ==> default: Adding box 'Ubuntu 16.04' (v1.0.0) for provider: virtualbox default: Downloading: http://my-vagrant-repo.home.ua/ubuntu_16.04/Ubuntu16.04_1.0.0.box default: Progress: 100% (Rate: 15.5M/s, Estimated time remaining: --:--:--) default: Calculating and comparing box checksum... ==> default: Successfully added box 'Ubuntu 16.04' (v1.0.0) for 'virtualbox'! ==> default: Importing base box 'Ubuntu 16.04'... ==> default: Matching MAC address for NAT networking... ==> default: Checking if box 'Ubuntu 16.04' is up to date... ==> default: Setting the name of the VM: My Ubuntu 16.04 ==> default: Clearing any previously set network interfaces... ==> default: Preparing network interfaces based on configuration... default: Adapter 1: nat ==> default: Forwarding ports... default: 22 (guest) => 2222 (host) (adapter 1) ==> default: Booting VM... ==> default: Waiting for machine to boot. This may take a few minutes... default: SSH address: 127.0.0.1:2222 default: SSH username: vagrant …
Как видим, система не нашла бокса с заданным именем локально и решила скачать его по заданному URL. Бокс скачался и добавился в список.
PS D:\Work\Vagrant\ubuntu16_04> vagrant box list Ubuntu 16.04 (virtualbox, 1.0.0)
Видим, что у нас теперь есть версия бокса 1.0.0. Теперь можно создать новую версию.
Логинимся на поднятую ВМ (рис. 3)
Рисунок 3 – Вид новосозданной ОС при логине (mofd)
Как видим, мы можем обновить 3 пакета. Обновляем пакеты и информацию по версии бокса.
root@ubuntu16:~# apt-get upgrade root@ubuntu16:~# echo '1.0.1' > /etc/box-version
Теперь у нас есть подготовленная к новой версии бокса ВМ.
4 Обновление версии Vagrant бокса
Теперь пакуем новый бокс из обновленной ОС и заливаем на сервер.
PS D:\Work\Vagrant\ubuntu16_04> cd ..\custom_boxes\ PS D:\Work\Vagrant\custom_boxes> vagrant package --base 'My Ubuntu 16.04' --output Ubuntu16.04_1.0.1.box ==> My Ubuntu 16.04: Attempting graceful shutdown of VM... My Ubuntu 16.04: Guest communication could not be established! This is usually because My Ubuntu 16.04: SSH is not running, the authentication information was changed, My Ubuntu 16.04: or some other networking issue. Vagrant will force halt, if My Ubuntu 16.04: capable. ==> My Ubuntu 16.04: Forcing shutdown of VM... ==> My Ubuntu 16.04: Clearing any previously set forwarded ports... ==> My Ubuntu 16.04: Exporting VM... ==> My Ubuntu 16.04: Compressing package to: D:/Work/Vagrant/custom_boxes/Ubuntu16.04_1.0.1.box
Бокс я залил в ту же папку, что и первый. Теперь нужно взять md5 сумму и поправить json.
root@vghost:~# md5sum /var/www/html/vagrant_boxes/ubuntu_16.04/Ubuntu16.04_1.0.1.box 44c24bc062dc5d07ca16d245ae6dce73 Ubuntu16.04_1.0.1.box root@vghost:~# cat /var/www/html/vagrant_boxes/ubuntu_16.04/ubuntu_16.04.json { "name": "Ubuntu 16.04", "description": "Ubuntu 16.04 LTS 64-bit box", "versions": [{ "_comment": "Initial Ubuntu 16.04 box", "version": "1.0.0", "providers": [{ "name": "virtualbox", "url": "http://my-vagrant-repo.home.ua/ubuntu_16.04/Ubuntu16.04_1.0.0.box", "checksum_type": "md5", "checksum": "72f0b69b12bdac1307efee3537ea31aa" }] }, { "_comment": "Latest package updated Ubuntu 16.04 box", "version": "1.0.1", "providers": [{ "name": "virtualbox", "url": "http://my-vagrant-repo.home.ua/ubuntu_16.04/Ubuntu16.04_1.0.1.box", "checksum_type": "md5", "checksum": "44c24bc062dc5d07ca16d245ae6dce73" }] }] }
Теперь идем обратно к ранее созданной ВМ и проверяем появилась ли новая версия.
PS D:\Work\Vagrant\ubuntu16_04> vagrant up Bringing machine 'default' up with 'virtualbox' provider... ==> default: Checking if box 'Ubuntu 16.04' is up to date... ==> default: A newer version of the box 'Ubuntu 16.04' is available! You currently ==> default: have version '1.0.0'. The latest is version '1.0.1'. Run ==> default: `vagrant box update` to update. …
Как видим, у нас есть новая версия бокса, кто бы мог подумать, давайте обновим его.
PS D:\Work\Vagrant\ubuntu16_04> vagrant box update ==> default: Checking for updates to 'Ubuntu 16.04' default: Latest installed version: 1.0.0 default: Version constraints: default: Provider: virtualbox ==> default: Updating 'Ubuntu 16.04' with provider 'virtualbox' from version ==> default: '1.0.0' to '1.0.1'... ==> default: Loading metadata for box 'http://my-vagrant-repo.home.ua/ubuntu_16.04/ubuntu_16.04.json' ==> default: Adding box 'Ubuntu 16.04' (v1.0.1) for provider: virtualbox default: Downloading: http://my-vagrant-repo.home.ua/ubuntu_16.04/Ubuntu16.04_1.0.1.box default: Progress: 100% (Rate: 14.3M/s, Estimated time remaining: --:--:--) default: Calculating and comparing box checksum... ==> default: Successfully added box 'Ubuntu 16.04' (v1.0.1) for 'virtualbox'!
Проверяем какие у нас есть теперь версии.
PS D:\Work\Vagrant\ubuntu16_04> vagrant box list Ubuntu 16.04 (virtualbox, 1.0.0) Ubuntu 16.04 (virtualbox, 1.0.1)
Теперь, если мы удалим ранее созданную ВМ и подымим ее заново, то ничего не поменяется, Vagrant заюзает старый бокс, так как он не в курсе, чего именно вы ожидаете. Чтобы использовать новый, нам нужно либо удалить старый, либо добавить нужную версию в конфигурационный файл. Давайте поправим Vagrantfile и запустим новую ВМ.
PS D:\Work\Vagrant\ubuntu16_04> vagrant destroy default: Are you sure you want to destroy the 'default' VM? [y/N] y ==> default: Forcing shutdown of VM... ==> default: Destroying VM and associated drives... PS D:\Work\Vagrant\ubuntu16_04> cat Vagrantfile Vagrant.configure("2") do |config| config.vm.box = "Ubuntu 16.04" config.vm.box_url = "http://my-vagrant-repo.home.ua/ubuntu_16.04/ubuntu_16.04.json" config.vm.box_version = "1.0.1" config.vm.provider "virtualbox" do |vb| vb.name = 'My Ubuntu 16.04' end end PS D:\Work\Vagrant\ubuntu16_04> vagrant up Bringing machine 'default' up with 'virtualbox' provider... ==> default: Importing base box 'Ubuntu 16.04'... ==> default: Matching MAC address for NAT networking... ==> default: Checking if box 'Ubuntu 16.04' is up to date... ==> default: Setting the name of the VM: My Ubuntu 16.04 ==> default: Clearing any previously set network interfaces... ==> default: Preparing network interfaces based on configuration... default: Adapter 1: nat ==> default: Forwarding ports... default: 22 (guest) => 2222 (host) (adapter 1) ==> default: Booting VM...
Логинимся в новую ВМ (рис. 4)
Рисунок 4 – Вид логин скрина новой ВМ
Как видите, у нас теперь есть версионность. Если старые сборки боксов точно не нужны, просто удалите их.
PS D:\Work\Vagrant\ubuntu16_04> vagrant box remove 'Ubuntu 16.04' --box-version '1.0.0' Removing box 'Ubuntu 16.04' (v1.0.0) with provider 'virtualbox'... PS D:\Work\Vagrant\ubuntu16_04> vagrant box list Ubuntu 16.04 (virtualbox, 1.0.1)
Если у вас будет несколько репозиториев, рано или поздно, нужно будет узнать откуда данный Vagrant box был скачан/добавлен. Раньше это можно было посмотреть используя опцию «-i» при запросе списка боксов, но теперь она не работает, так что нужно смотреть самим вручную в папке «~/.vagrant.d/boxes». Вот пример.
# Windows PS C:\Users\Asus> cat '.\.vagrant.d\boxes\Ubuntu 16.04\metadata_url' ... http://my-vagrant-repo.home.ua/ubuntu_16.04/ubuntu_16.04.json ... # Linux user@Hypervisor:~$ cat .vagrant.d/boxes/Ubuntu\ 16.04/metadata_url ... http://my-vagrant-repo.home.ua/ubuntu_16.04/ubuntu_16.04.json ...
Базу и основной принцип версионности Vagrant был описан, так что удачи в экспериментах.
Огромное спасибо! Доступно и приятно читать.