Всех приветствую,

Сегодня хотелось бы поделиться информацией, о том как можно упростить немного жизни при развертывании линуксовых виртуалок в VMware с помошью политик кастомизации.

Конкретно про мой кейс. У меня есть шаблон виртуальной машины, ранее в этом шаблоне были произведенны настройки безопасности системы и разметка диска. Установлен стандартный пакет программ (vim, tmux, etc..) и агенты мониторинга/сбора логов. При создании новой виртуальной машины из этого шаблона, далее приходиться в ручном порядке настраивать сетку, hostname и добавлять/регистрировать puppet-агент. Затем происходит магия, и puppet сам донастраивал машину под нашу инфру.

В общем я принялся искать решение для автоматизации этих промежуточных задач, перед добавлением сервера в puppet. По итогу нашел прикольную штуку в vmware - Customization Specification, это нативная фича которая позволяет кастомизировать шаблон виртуальной машины, предопределяя какие-то базовые настройки (Сеть, DNS, NTP и прочее) для будущей vm.

Приступаем к демонстрации, сначала подготовим тестовый шаблон, с котором будет взаимодействовать далее. Для этого я создал новую виртуалку.

На свеже установленной машине временно задаем ip-адрес и dns и гейт, это нужно сделать для обновления всей системы и установки vmware tools.

Настраиваем сетку:

# Для просмотра имени интерфейса, у меня 1 интерфейс - ens32
$ nmcli con show 

# Настройка ip
$ nmcli con mod ens32 ipv4.address 10.8.1.17/24

# Настройка гейта
$ nmcli con mod ens32 ipv4.gateway 10.8.1.1

# Настройка dns
$ nmcli con mod ens32 ipv4.dns 10.8.1.1

# Отключаем DHCP, ставим статику
$ nmcli con mod ens32 ipv4.method manual 

# Поднимаем интерфейс
$ nmcli con up ens32

Агрумент con это сокращение от connection. А mod сокрашение от modify.

Если же в вашей инфре используется dhcp, то можете скипнуть этап настройки сети и приступить к установке пакетов.

Для работы кастомизации нужно установить VMware tools версии выше 10.1.0, под Linux из стандартных репозиториев без проблем ставится opensource аналог - Open VM Tools. Также нужен cloud-init.

Ставим пакеты:

$ yum install open-vm-tools cloud-init -y

Дополнительных настроек для vmware tools не требуется. Единственный момент который стоит выполнить, это включение опции enable-custom-scripts для toolbox. Эта фича дает нам возможность запускать какие-либо shell-скрипты при деплое виртуалки, скрипты настраиваются в спецификации (покажу далее).

Чтобы разрешить выполнение кастомных скриптов, в виртуальной машине нужно выполнить эту команду:

# Команда для просмотра текущего состояния
$ vmware-toolbox-cmd config get deployPkg enable-custom-scripts

# Включение enable-custom-scripts
$ vmware-toolbox-cmd config set deployPkg enable-custom-scripts true

Сразу же поставим puppet-агента, импортируем репозиторий и ставим пакет:

$ yum install -y https://yum.puppetlabs.com/puppet8-release-el-8.noarch.rpm
$ yum install -y puppet-agent

Будем считать что шаблон для наших будущих виртуалок мы приготовили. Удаляем ранее установленные сетевые настройки, и выключаем vm:

$ nmcli con show
$ nmcli con delete ens32 && init 0

Далее идем во vSphere-клиент и конвертируем виртуалку в шаблон: vmware-puppet-temp.png

Перед созданием спецификации, напишем небольшой скриптец, который будет создавать конфиг для puppet-агента и регать агента.

Собственно сам сниппет:

#!/bin/bash

PUPPET_SERVER="puppetmaster.domain.localhost"
PUPPET_CLIENT=$(hostname --fqdn)
PUPPET_ENV="prod"

# Create puppet-agent config
cat << EOF > /etc/puppetlabs/puppet/puppet.conf
[main]
server = $PUPPET_SERVER
certname = $PUPPET_CLIENT
environment = $PUPPET_ENV
EOF

# Register puppet-agent
/opt/puppetlabs/bin/puppet resource service puppet ensure=running enable=true

В блоке с переменными определяются основные настройки для агента - адрес сервера, имя клиентского сертификата и окружение. Значения этих переменных будут использованы в конфиге puppet.conf. В завершении команда, которая просто запускаем агента.

Все зависимые таски выполнены, теперь можно создать спефицикацию, для этого проваливаемся в раздел: vmware-puppet-spec1.png

На странице переходим в раздел VM Customization Specifications, и жмем на кнопку создания - New. vmware-puppet-spec2.png

Далее откроется окно с настройкой спецификации. В первом разделе, настраивается имя нашей спеки (можно добавить описание, опционально). Поле ниже нужно выбрать тип гостевой OS, мы выбираем Linux. И жмем на кнопку - Next. vmware-puppet-spec3.png

Следующее окно настраивает имя виртуальной машины, то есть имя сервера. В этом окне нам доступны три поинта:

  • Use the virtual machine name - При выборе этого поинта, имя сервера будет использовано такое же, что и название виртуалки в vSphere клиенте.
  • Enter a name in the Clone/Deploy wizard - Если выбрать этот пункт, то имя сервера будет задаваться в процессе настройки виртуальной машины. Остановлюсь на этом варианте.
  • Enter a name - В этом поинте мы просто указываем имя сервера.

Поле Domain name является обязательным, тут указываем имя нашего домена. vmware-puppet-spec4.png

Раздел далее просто настраивает временную зону: vmware-puppet-spec5.png

Четвертый раздел Customization script, как раз таки позволяет нам, использовать свои shell-скрипты для выполнения каких либо настроек. В поле Script представлен небольшой пример, как должны быть оформлен скриптец. vmware-puppet-spec6.png Пример состоит из условного оператора if, который содержит два условия. В контексте каждого условия мы можем вставить свой код, который будет выполнен на определенном этапе настройки гостевой OC.

Этап precustomization может выполнить сценарии настройки, которые не зависят от сетевого интерфейса или ip-адреса. Контекст Postcustomization выполняется после завершения настройки гостевой OC, когда сетка уже готова к использованию.

С учетом всех требований допилим наш скриптец:

#!/bin/sh

PUPPET_SERVER="puppetmaster.domain.localhost"
PUPPET_CLIENT=$(hostname --fqdn)
PUPPET_ENV="test"

# Create puppet-agent config
cat << EOF > /etc/puppetlabs/puppet/puppet.conf
[main]
server = $PUPPET_SERVER
certname = $PUPPET_CLIENT
environment = $PUPPET_ENV
EOF


if [ x$1 == x"postcustomization" ]; then
        /opt/puppetlabs/bin/puppet resource service puppet ensure=running enable=true
fi

Здесь, команду запуска агента мы просто закинули в условный оператор. Она будет выполнена в конце настройки vm.

Скриптец вставляем в поле и жмем на далее: vmware-puppet-spec7.png

Следующий раздел предопределяет настройки сети. Так как в моей инфре не используется DHCP, поэтому я прожимаю поинт ручной настройки. Затем нужно выбрать интерфейс, по умолчанию он один, и настроить его. vmware-puppet-spec8.png

Провалившись в настройки интерфейса, выбираю пункт Promt the user for an IPv4 address. Это означает, что в процессе деплоя новой vm у меня установщик спросит об сетевых настройках. Соглащаемся и идеем далее: vmware-puppet-spec9.png

Завершающий раздел, это настройка dns. Тут просто указываем адреса наших dns-серверов. vmware-puppet-spec10.png

Наша кастом-спецификация готова, теперь давайте развернем новую vm c ее использованием.

Из ранее созданного шаблона выбираю пункт - New VM from This Template: vmware-puppet-spec10.png

В настройках деплоя указываю имя новой виртуальной машины, и выбираю сервер на который хочу ее приземлить: vmware-puppet-vm2.png

Затем выбираю новый датастор: vmware-puppet-vm3.png

Следующий раздел, ключевой, в нем мы связываем нашу спецификацию с шаблоном: vmware-puppet-vm4.png

Далее нужно выбрать спецификацию, у нас она одна: vmware-puppet-vm5.png

В новом окне задаем имя виртуального сервера, и сетевые настройки: vmware-puppet-vm6.png

Завершаем процесс установки, дожидаясь клонирования нашей vm. После запускаем сервер. По истечении трех минут, можем проверить паппет-сервер.

Выполнив команду, можем увидеть запрос от нашего нового сервера:

[root@puppetserver ~]# puppetserver ca list
Requested Certificates:
    vmapptest.domain.localhost       (SHA256)  6F:EB:FB:35:4A:FA:C9:A2:90:D2:EC:B8:63:74:22:52:EE:5F:D5:63:5D:98:DE:63:81:4E:85:A5:41:B8:71:76

Задача решена, после подписание сертификата агента, puppet завершит настройку, и сервер будет готов в эксплуатации.