Использовать Vagrant для создания Consul кластера на линуксовых машинах было, конечно, здорово. Но как быть с виндовыми машинами? Всё-таки больше половины разработчиков разрабатывают в Windows. Так что смотреть, как кто-то создаёт пачки линуксовых VM, — прикольно, но бесполезно.
Но есть хорошие новости: Vagrant поддерживает и Windows. Давно поддерживает. Конфигурация детища Майкрософт практически ничем не отличается от конфигурации пингвинов, но есть, как и во всём, связанным с Windows, некоторые нюансы.
Нюансы
Лицензирование
Мне, как выходцу из самой пиратской страны мира (Arrgh!), это тяжело понять, но Windows стоит денег. Поэтому нельзя вот просто взять и запустить случайно найденный образ с Windows где-нибудь в продакшен. Можно, конечно, найти пробную версию для экспериментов, но для более постоянного использования нужно готовить деньги.
Программное подключение к виртуальной машине
Подключиться через vagrant ssh
к виндовой машине можно, но только если там был заранее установлен SSH сервер. С другой стороны, специально для Windows есть vagrant powershell.
Правда, работать он будет только если ось хоста тоже Windows. PowerShell хоть и пытается быть кросс-платформенным, но та его часть, которая отвечает за удалённые подключения, всё ещё не портирована.
Удивительно, но vagrant rdp
— удалённое подключение рабочего стола — пока что самый кросс-платформенный (Linux, Mac) способ зайти в гостевую Windows.
Производительность
Если только создатель Vagrant-бокса с Windows не указал в настройках, что виртуальной машине нужно вдвое больше процессоров и памяти, чем для стандартного Linux хоста, это придётся сделать самостоятельно в Vagrantfile.
Провиженинг Конфигурация
Файлы конфигурации нужно писать в PowerShell, ура! Хотя большую часть своей карьеры PowerShell я люто ненавидел, в последнее время с ним пришлось много работать. И то ли я разобрался в нём больше, то ли стокгольмский синдром случился, но PowerShell, в принципе, теперь ничего такой.
Второй момент, Vagrant общается с Windows через WinRM. Все виндовые Vagrant-боксы, что мне попадались, шли уже настроенными, но если вам сильно не повезёт, то открывать WinRM порты и настраивать активный протокол в Vagrant (config.vm.communicator = "winrm"
) придётся тоже самостоятельно.
План на сегодня
С прошлого раза у нас остался кластер из трёх хостов с Consul агентами на них. Что, если добавить туда ещё и Windows-хост? Должно быть весело.
Шаг 0. Создаём пустую Windows VM
На HashiCorp нашёлся Vagrant-бокс mwrock/Windows2016 с пробной версией Windows сервера внутри. Бокс регулярно обновляется, его автор публикует и другие, так что есть хорошая вероятность, что бокс удалят нескоро.
Мы начнём с конфигурации отдельного Windows хоста с консулом, а потом вмержим его в остальной кластер.
Точно так же как и с Linux, vagrant init mwrock/windows2016 --minimal
сделает дефолтный Vagrantfile:
1 2 3 |
Vagrant.configure("2") do |config| config.vm.box = "mwrock/windows2016" end |
vagrant up
же скачает 5 гигов винды на локальную машину и через несколько минут колдовства запустит свеженький Windows Server 2016:
Логин пароль от машины — «vagrant» и «vagrant». Через vagrant rdp
тоже можно зайти, но в зависимости от установленного клиента и операционки, может потребоваться сделать пару дополнительных телодвижений. На маке после vagrant rdp
мне пришлось сделать аж двойной клик:
Шаг 1. Задаём имя хоста и IP адрес
Этот шаг выглядит точно так же, как и для Linux машин. Всего лишь пара строк в Vagrantfile:
1 2 3 4 5 6 |
Vagrant.configure("2") do |config| config.vm.box = "mwrock/windows2016" config.vm.hostname = "host-win" winClientIP = "192.168.99.103" config.vm.network "private_network", ip: winClientIP end |
Потом выполняем vagrant reload
чтобы применить изменения и заходим в виртуалку убедиться, что они-таки применились:
Шаг 2. Скачиваем и «устанавливаем» Consul
Скрипты с конфигурацией для Windows декларируются в Vagrant практически точно так же, как и в Linux. Только вместо .sh
файлов линуксового shell нужно передавать .ps1
виндового PowerShell:
1 2 3 |
#... config.vm.provision "shell", path: "provision.ps1" #... |
Хотя синтаксически внутренности скриптов настройки консул-агентов для Linux и Windows будут отличаться, логически там всё те же 2 основные задачи: скачать и распаковать. Я добавил ещё несколько шагов, вроде проверить, существует ли папка, удалить архив после распаковки, создать директорию для данных консула (потом понадобится) и вывести его версию (просто так), но это всё опционально. Критически важные только три строчки:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
$consulDir = "C:\Consul" $consulExePath = "$consulDir\consul.exe" $consulZipPath = "c:\tmp\consul.zip" $version = "0.8.1" if (-not (Test-Path $consulDir)) { # Use newest TLS1.2 protocol version for HTTPS connections [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 # Download consul Invoke-WebRequest -OutFile $consulZipPath -Uri https://releases.hashicorp.com/consul/$($version)/consul_$($version)_windows_amd64.zip # Unzip Expand-Archive -Path $consulZipPath -DestinationPath $consulDir # Cleanup Remove-Item $consulZipPath # Create Consul data dir New-Item -Type Directory -Path "$consulDir\data" # Print Consul version number to confirm it was downloaded correctly & $consulExePath version } else { Write-Host "Consul is already installed" } |
Мне также пришлось явно задать, какую версию TLS протокола использовать для HTTPS запросов. Проблема в том, что весь мир давно использует TLS 1.2 для шифрования, а Invoke-WebRequest
в PowerShell — нет. Вот такая виндовая неожиданность.
Попробуем теперь применить файл настроек и проверим, что он сработал:
1 2 3 4 5 |
$ vagrant provision # ==> default: Running provisioner: shell... # ... # ==> default: Consul v0.8.1 # ... |
Ну, номер версии он вывел, так что всё гуд.
Шаг 3. Настраиваем и запускаем Consul агент
Совсем чуть-чуть изменив JSON для конфигурации Consul из линуксового кластера, его теперь можно использовать в виндовом. По сути, там просто слэши поменять:
1 2 3 4 5 6 7 8 9 10 11 12 |
winClientIP = "192.168.99.103" serverIP = "192.168.99.100" # Consul server IP from last article clientInit = %( { "advertise_addr": "#{winClientIP}", "retry_join": ["#{serverIp}"], "data_dir": "C:\\\\Consul\\\\data" } ) config.vm.provision "shell", inline: "Set-Content -Value '#{clientInit}' -Path C:\\Consul\\init.json" |
Запускаем агента:
1 2 3 |
#... config.vm.provision "shell", inline: "C:\\Consul\\consul.exe agent -config-dir=C:\\Consul" #... |
Строка выше запустит консула в качестве основного процесса, который никогда не завершится, и поэтому vagrant provision
тоже будет вечным. Прямо сейчас это не проблема, но в будущем консула можно запустить через PowerShell’овский Start-Process
, и тогда процесс станет фоновым и даст vagrant provision
завершиться:
1 2 3 |
#... config.vm.provision "shell", inline: "Start-Process consul.exe -WorkingDirectory C:\\Consul -ArgumentList 'agent', '-config-dir=C:\\Consul'" #... |
Теперь запускаем vagrant provision
ещё раз, и наслаждаемся паникой Consul агента, который никак не может найти себе кластер:
1 2 3 4 5 |
$ vagrant provision #... # ==> default: ==> Consul agent running! #... # ==> default: 2017/05/02 03:46:05 [WARN] manager: No servers available |
Эту панику можно исправить либо параллельно запустив наш линуксовый кластер, либо пройдя шаг 4.
Шаг 4. Не обязательный. Мержим Vagrantfile в Linux кластер
У нас есть Vagrantfile с кластером с прошлого раза, и есть Vagrantfile с Windows. Надо бы смержить их в один. Так уж случилось, что я это уже сделал и положил в winhost ветку на на гитхабе. Ничего сложного или достаточно интересного для того, чтобы описывать тут, не было. Обычный copy-paste.
Но вот какой получился результат. Теперь у нас есть Vagrantfile, который можно запустить одной командой, и какими-то мистическими путями он полностью автоматически создаст кластер из четырёх машин с разными операционными системами, которые будут работать вместе в качестве единого Consul кластера. Представьте, если бы это пришлось делать руками. Хотя бы установку Windows.
В этом-то и прелесть автоматизации: vagrant up
, пару минут и Бум!
Заключение
В общем, автоматизировать создание и настройку виртуальных машин с Windows действительно можно. Vagrant с этим справляется, и сам процесс практически ничем не отличается от работы с Linux хостами. Да, будут некоторые трудности, вроде лицензирования Windows, но если, например, создавать хосты в AWS или GCE (либо жить в Беларуси), то там обо всём уже позаботились и лицензия включена в стоимость часа машины.