В предыдыщей части мы рассмотрели, для чего нужна автоматизация разворачивания ВМ Windows и как подготовить хостовую систему. Сегодня я хотел бы заострить внимание на технической реализации самой массивной части процесса, а именно — подготовке базового бокса для Vagrant.После того, как установлен весь необходимый софт, пришло самое время подготовить образцовый бокс — шаблон, из которого будут разворачиваться машины.Бокс представляет из себя обычный tar-архив, содержащий в себе файл диска VHD и метаданные: настройки виртуалки и служебную информацию. Таким образом, необходимо начать подготовку образа с создания у себя новой ВМ, обновления её, настройки и сжатия с целью экономии места и ускорения деплоя. Я не буду подробно останавливаться на том, как создать новую виртуальную машину в Hyper-V Manager, как ставить систему и накатывать обновления. Заострю лишь внимание на нюансах:
так и командную строку, что нам ближе по душе и к тому же позволяет указать дополнительные параметры:
Теперь, чтобы Vagrant его скопировал себе и увидел — нужно добавить его при помощи команды add прямо из нашего каталога с файлом:
В следующей части я покажу, как поднимать ВМ из бокса и проводить её автоматическую настройку при помощи провижионинга.
- Создавайте машину первого поколения (Gen1). Связано это с тем, что актуальная версия Vagrant (1.7.2) некорректно устанавливает параметры жёсткого диска (у Gen2 нет опции “IDE”, она заменена на “VHD”), поэтому я советую пока не связываться с Gen2. Впрочем, если очень нужно — можно поправить файл plugins/providers/hyperv/scripts/import_vm.ps1.
- Используйте только один файл жёсткого диска, иначе бокс не сможет подняться (об этом см. ниже).
- Не устанавливайте лишнее ПО (включая компоненты Windows) в бокс. Это утяжеляет его и увеличивает шанс, что через некоторое время там будет устаревшая версия. Правильнее это делать позже, в стадии провижионинга.
- Для корректной работы Boxstarter необходимо отключить ограничения Powershell:
Set-ExecutionPolicy -ExecutionPolicy Unrestricted
- По умолчанию Vagrant обращается к машине через SSH (что требовало установки последнего на машину), однако в последних версиях он научился работать по родному для Windows протоколу WinRM. Всё, что нужно — настроить WinRM:
winrm set winrm/config/client/auth '@{Basic=«true»}'
winrm set winrm/config/service/auth '@{Basic=«true»}'
winrm set winrm/config/service '@{AllowUnencrypted=«true»} - Я обычно отключаю (ставлю ручной режим запуска) ненужных служб (Print Spooler тот же), а также убираю индексацию диска и автоматическое еженедельное дефрагментирование: у нас оптимизация Storage Tier проводится самим гипервизором.
- Уменьшить размер файла подкачки, сделать этот размер фиксированным;
- Очистить все логи:
wevtutil el | Foreach-Object {wevtutil cl "$_"}
- Удалить ненужные компоненты Windows Update:
Dism.exe /online /Cleanup-Image /StartComponentCleanup /ResetBase
Dism.exe /online /Cleanup-Image /SPSuperseded - Удалить установщики компонент Windows. Запустив команду Get-WindowsFeature можно увидеть, что часть компонентов имеют Install State = Available. Обычно это значит, что эти компоненты можно установить, причём для этого достаточно кеша, который хранится прямо на локальном диске. Поэтому имеет смысл удалить этот кеш, выполнив команды:
Get-WindowsFeature |
? { $_.InstallState -eq 'Available' } |
Uninstall-WindowsFeature -Remove - В случае, если какой-то из компонентов может пригодиться впоследствии — имеет смысл его оставить, иначе при последующей установке придётся указывать путь к wim-файлу (параметр -Source). Впрочем, тут нет ничего страшного: этот файл есть в ISO файле, с которого ставилась система, и его можно использовать как локально, так и с сетевого ресурса. К тому же, часть компонентов спокойно ставится из Интернета — Powershell сам скачает необходимые файлы.
- При желании можно установить Disk Cleanup — программу, которая автоматизированно очищает систему от временных файлов. Однако для этого необходимо добавлять роль Desktop-Experience, при удалении которой возникают проблемы с sysprep. Так что варианта тут два: либо оставлять эту фичу, которая сама подъедает место и утяжеляет реестр, (т.к. тянет за собой кучу обязательного, но лишнего барахла типа Ink and Handwriting), либо отказаться от sysprep, что ставит крест над использованием поднятой машины в домене.
- После всех перечисленных операций размер динамического VHD файла останется прежним. Чтобы его сжать — необходимо сначала провести дефрагментацию, чтобы переместить все файлы в начало диска:
Optimize-Volume -DriveLetter C -Defrag
- После дефрагментации желательно обнулить всё свободное место при помощи команды sdelete, входящей в состав SysInternals:
sdelete -z c:
Это позволит эффективнее сжать её впоследствии.
Хождение по Sysprep’у
В самом общем случае подготовка виртуалки к клонированию при помощи sysprep — процедура довольно банальная. Для этого можно воспользоваться как GUIC:\Windows\System32\Sysprep\sysprep
так и командную строку, что нам ближе по душе и к тому же позволяет указать дополнительные параметры:
C:\Windows\System32\Sysprep\sysprep /generalize /oobe /mode:vm /shutdownПосле этого программа выполнит все необходимые операции и потушит машину. При последующем включении система будет находиться в вышеупомянутом OOBE (Out-of-Box Experience) — состоянии, в котором находится свежеприобретённый ноутбук при первом включении: будет проведена инвентаризация железа, запрошен пароль локального администратора, лицензионный ключ, имя компьютера и так далее. Всё бы ничего, но вводить всё это приходится вручную, с клавиатуры. К счастью, всё это легко автоматизируется. Для этого нужно подготовить файл ответов, unattend.xml и положить его рядом с запускаемым файлом sysprep.exe (в папку C:\Windows\System32\Sysprep), либо указав путь к нему в качестве параметра командной строки — это позволит разместить файл на внешнем диске, чтобы его не оказалось на итоговом боксе. Подробно останавливаться на этом не буду, хочу лишь сказать, что для этого понадобится установочный образ Windows (точнее файл install.wim из него) и Windows Assessment and Deployment Kit (ADK) (ставить нужно только пункт Deployment Tools, который включает в себя Windows System Image Manager). Ссылки на дистрибутив, инструкции и примеры использования будут в соответствующем разделе в следующей, заключительной части статьи.
Важные нюансы:
- Если вы ставили, а потом удаляли компонент Desktop-Experience, то Sysprep будет вываливаться с ошибкой. Как я и упоминал выше — варианта два: либо оставлять этот компонент установленным, либо обходиться без него. Подробности есть у Мэта Рока (автора Boxstarter) в блоге.
- При подготовке бокса часто возникает необходимость доработать что-либо, для этого бокс поднимается в состоянии OOBE, проходят все настройки в соответствии с файлом ответов, потом делаются необходимые изменения и система снова прогоняется Sysprep. Хочу обратить внимание, что так получится сделать всего два раза (т.е. три прогона sysprep). Это связано с особенностями лицензирования Microsoft. В принципе, это обходится хитрым редактированием реестра, однако это можно делать только для временных или тестовых машин, а не в продакшене, поэтому я советую просто хранить образ для дальнейшей работы отдельно, при необходимости делая его копии и подготавливая новую версию независимо. Таким образом каждая виртуальная машина за весь период её жизни будет “отсиспреплена” всего единожды.
- Лучше не устанавливать имя компьютера — тогда оно будет случайно сгенерировано, что позволит избежать путаницы и конфликтов, когда поднимается несколько машин одновременно. К тому же, его можно легко установить самим вагрантом на этапе провижионинга при подъёме.
- Установите сложный и безопасный пароль для локального администратора. В будущем его, конечно, лучше сменить (или вообще заблокировать). Эта учётная запись понадобится при поднятии машины на этапе провижионинга (provisioning stage): именно под ней Vagrant будет устанавливать софт, обновлять систему и делать все необходимые настройки.
- Имя машины в самом гипервизоре (как она называется в Hyper-V Manager) лучше сменить на что-то короткое и простое — именно так будет называться машина из развёрнутого бокса. Была неловкая ситуация, когда коллеги поднимали у себя мой пробный бокс и в результате у них появлялась машина вида “Winda 2k12 r2 x64 syspreped with bloody winrm settings version 111 test 222 yo”.
Упаковка бокса
После того, как Sysprep потушил машину, самое время упаковывать виртуалку в файл бокса. Вообще у Vagrant есть встроенный функционал для этого (команда provision), однако по состоянию на нынешний момент в Hyper-V она не работает. Так что паковать бокс мы будем руками — бояться тут нечего, делается это довольно просто:- У машины проверяется конфигурация оборудования: количество ядер процессора, объём памяти, приоритет загрузки. Именно эти параметры будут на вновь развёрнутых машинах (хотя ничего не мешает поменять их потом, конечно).
- Удаляются все снимки (снапшоты) жёсткого диска.
- Готовая выключенная машина экспортируется в отдельную папку на диске. Это необходимо, чтобы разместить рядом файл жёсткого диска и всю мета-информацию.
- В папке с виртуальной машиной удаляется папка для файлов снапшотов — вагрантовский провайдер Hyper-V всё равно его не использует.
- Там же создаётся текстовый файл metadata.json. Как минимум, там должен быть определён хотя бы один провайдер (Hyper-V в нашем случае). Пример файла для нашего случая:
{
«name»:«Windows2012R2»,
«description»:«Windows 2012 R2 box sysprepped with ununtended provisioning»,
«provider»: «hyperv»
} - Теперь осталось только сделать из содержимого каталога файл .box. Для этого используется tar (можно использовать бесплатный 7-Zip или bsdtar из репозитария: версия, которая идёт с Vagrant 1.7.2, не подойдёт). Внимание: в архиве должно быть только содержание папки, куда экспортировалась машина, без вышестоящей папки, иначе бокс не распознается. Т.е. внутри, прямо в корне должны быть каталоги “Virtual Hard drives” и “Virtual Machines”, а также файл metadata.json. Получившийся файл потом можно сжать при помощи gzip (снова можно использовать 7-Zip, главное делать это отдельной итерацией, уже над файлом .tar) или LZMA (который даёт лучшее сжатие, но сэкономленное на копировании время потом потратится на более длительное, по сравнению с gzip, разархивирование) и поменять его расширение на box. Та-да! Бокс готов!
Теперь, чтобы Vagrant его скопировал себе и увидел — нужно добавить его при помощи команды add прямо из нашего каталога с файлом:
vagrant box add --provider hyperv --name Win2012R2x64 Win2012R2.boxЕсли всё прошло нормально — бокс станет доступным (вагрант скопирует его себе в %VAGRANT_HOME% и распакует) и его можно увидеть в выводе команды vagrant box list. Чтобы он был доступен и для коллег — можно выложить его на общий сетевой диск (тогда команда для добавления бокса будет вида vagrant box add --name Win2012R2x64 D:\Path\To\Win2012R2x64 \\fileserver.domain.local\boxes\win2012r2.box) или веб-сервер: локальный (vagrant box add --name Win2012R2x64 http://devops.local/boxes/win2012r2.box) или внешний. Например, на http://www.vagrantbox.es/ или Hashicorp Atlas.
В следующей части я покажу, как поднимать ВМ из бокса и проводить её автоматическую настройку при помощи провижионинга.