Полный ответ на этот вопрос лежит в подходе IaC, что заслуживает отдельной статьи. В рамках же данного материала будет продемонстрирован пример создания шаблона ВМ через packer. Наличие такого образа позволяет заранее установить внутрь всё необходимое единожды, тем самым сократить время развертывания целевой системы.
Hashicorp разработала packer для возможности создания универсального образа операционной системы (golden image), в который заранее упаковывается всё необходимое. На основе этого образа далее уже развёртываются виртуальные машины с нужным набором софта. В терминологии packer так называемый builder выполняет непосредственно сборку, а с помощью плагинов билдера указывается целевая платформа: в основном это облачные провайдеры типа AWS, Yandex, но есть и локальные QEMU, Proxmox и даже Docker или Ansible. Все дальнейшие инструкции будут применимы к плагину Proxmox.
Packer подключается к облаку или локальному гипервизору, создаёт ВМ с указанными параметрами и выполняет установку ОС на основе файла автоматической установки (например, для rpm-based используется kickstart, для deb-based – Subiquity в случае с Ubuntu). А после установки формирует эталонный шаблон из которого клонируются ВМ.
Казалось бы, packer позволил автоматизировать ручной этап. Но при этом добавил новых ручных действий, которые придётся выполнить. Например, какой IP-адрес, хостнейм или ssh-key назначать ВМ, создаваемой из шаблона? Ведь при создании каждой новой ВМ придётся это как-то вручную указывать и менять “эталонный” образ… Или же другой случай: после установки ОС необходимо каждый раз накатывать какой-то типовой софт через ansible, что тоже отнимает время на ручные действия. Тут в игру вступает cloud-init – разработка от компании Canonical.
С помощью cloud-init можно выполнить инициализацию ОС до её финальной загрузки. Такое часто можно встретить в облаках. После создания ВМ из подготовленного шаблона с помощью packer запускается cloud-init, который считывает конфигурационный файл и выполняет указанные там действия. Это может быть как создание нужных юзеров, ключей, установка софта или запуск плейбуков и т.д.
<blockquote>Все действия выполнены на Proxmox 7 и Ubuntu 22.04, в которой используется установщик Subiquity.</blockquote> 1. Packer.
Конфигурационные файлы могут быть в формате HCL или JSON. В рамках данной статьи будет использоваться HCL. В секции source описывается ВМ с нужными параметрами. Тут есть важный параметр boot_command: в нём указывается, как запустить операционную систему. Причём в boot_command указаны комбинации, эмулирующие нажатие физических клавиш, как если бы это делалось вручную в консоли гипервизора. В данном случае packer переключается в консоль grub, указывает ядро для загрузки и добавляет параметры, которые необходимо выкачать по http. Веб-сервером выступает сам packer – установщик ОС подключается к машине, с которой packer был запущен. С помощью этих параметров, полученных через http, будет произведена автоустановка Ubuntu.
<blockquote>Про wsl и сеть. Если packer запущен в WSL, то в идеале он должен получать адрес из той же подсети, в которой создаются VM в Proxmox, чтобы они могли подключиться к веб-серверу Packer. В противном случае будет возникать ошибка на этапе “Reached target Host and Network Name Lookups” или на этапе загрузки AppArmor. Ещё подойдет как вариант portproxy
.</blockquote>
2. cloud-init.
Для работы cloud-init потребуется два YAML файла: user-data
и meta-data
. В user-data указываются необходимые модули, с помощью которых можно выполнить те или иные действия – создать файлы, пользователей и т.д. Примеры различных конфигов user-data можно посмотреть в документации.
Для автоматической установки Ubuntu используется также конфигурация cloud-init:
cloud-init
по пути /target/var/lib/cloud/seed/nocloud-net/user-data
.user-data
включена в autoinstall, то subiquity соединит содержимое user-data с файлом, который был создан ранее по пути/target/var/lib/cloud/seed/nocloud-net/user-data
То есть проще говоря, конфиг для автоустановки Ubuntu такой же, как и для cloud-init, но в начале файла используется специфичная конструкция autoinstall
для инсталлятора subiquity, а далее уже используются нативные модули cloud-init.
Чтобы безмолвно не выкладывать весь конфиг целиком, стоит разобрать некоторые моменты.
. ├── README.md └── ubuntu-server-jammy ├── http │ ├── meta-data │ └── user-data ├── ubuntu-server-jammy.pkr.hcl └── variables.pkr.hcl
Теперь что касается самого конфигурационного файла ubuntu-server-jammy.pkr.hcl. Для его понимания стоит изучить HCL, тем кто работал с terraform будет проще, т.к. там по сути тоже самое. Основные моменты, на которые стоит обратить внимание:
default = env(«PROXMOX_API_URL»)
iso_file = «local:iso/ubuntu-22.04.1-live-server-amd64.iso»
. Можно также скачать через пакер, указав адрес дистрибутива, но логичнее подготовить образ заранее, чтобы ускорить процесс сборки.ubuntu-22.04
лучше выставить в 2 Гбssh_disable_agent_forwarding
, то подключение к серверу будет осуществлено под локальным пользователем с пробросом агента. В данном же случае в качестве примера указан более простой случай, когда используется простой логин\пароль вида ubuntu\ubuntuТакже стоит пробежаться по файлу cloud-init, на основе которого выполняется автоматическая установка ОС:
И самый главный момент – создание пользователей. Здесь уже будут создаваться юзеры и пароли как для packer (с помощью которого он будет выполнять shell-команды из своего конфига), а также конечный пользователь для подключения по SSH после клонирования и запуска ВМ. Здесь важно указать хеш пароля (создав командой mkpasswd –method=SHA-512 –rounds=4096 например). Также можно указать публичный ключ, что будет намного удобнее. Примеры можно посмотреть тут.
Для сборки и установки шаблона необходимо:
export PROXMOX_API_TOKEN_ID='root@pam!packer' export PROXMOX_API_TOKEN_SECRET="7bf07389-db62-4985-aef3-58640dff3beb" export PROXMOX_API_URL="https://192.168.3.100:8006/api2/json"
packer build ubuntu-server-jammy.pkr.hcl
После того, как шаблон появится в гипервизоре, для быстрого создания новой ВМ необходимо выполнить клонирование:
После указать имя ВМ:
Теперь важно указать корректные значения для новой ВМ. Для этого надо скорректировать в разделе cloud-init IP-адрес, маску и шлюз + остальные параметры при необходимости и перегенировать образ уже клонированной ВМ, после чего выполнить запуск:
Подключиться к запущенной ВМ можно по указанному выше IP-адресу (если он задан статически) и с логином\паролем или ssh-ключом, который указан в файле user-data