В данной серии статей я планирую рассказать о том, как создавать виртуальные апплайнсы для платформы виртуализации oVirt. Несмотря на использование oVirt в качестве эталонной платформы, приведенные ниже инструкции и рекомендации могут быть легко адаптированы и для других решений вроде Proxmox, Open Nebula, Open Stack или обычного KVM.
В первой части я сосредоточусь на подготовке эталонного образа для будущего апплайнса, а также утилитах и скриптах, которые позволят автоматизировать настройку апплайнса.
Введение
До сих пор виртуальные апплайнсы остаются одним из самых удобных способов доставки и развертывания ПО в виртуальных инфраструктурах. Идейным вдохновителем данной концепции стала компания VMware, которая поставляет большую часть своего ПО в виртуальных апплайнсах. В качестве примера на ум приходит VMware vCenter Server, который присутствует буквально в каждой инфраструктуре vSphere, SDN контроллер NSX Manager, сервер мониторинга Aria Operations и многие другие. Для других платформ такой подход также часто применяется. Например, сервер управления oVirt Engine - аналог vCenter также может поставляться в виде виртуального апплайнса.
Несколько лет назад я уже писал о том, как создавать виртуальные апплайнсы в vSphere. Данная возможность реализована благодаря поддержке OVF (Open Virtualization Format) - специальному формату, который позволяет описывать конфигурацию ВМ, а также дополнительные параметры для настройки гостевой ОС и приложений при развертывании ВМ из шаблона.
Несмотря на то, что формат OVF является открытым и поддерживается во многих Open Source решениях, не все платформы виртуализации предоставляют одинаковые возможности при работе с OVF шаблонами. Например, oVirt в отличие от VMware vSphere не поддерживает работу с расширенными свойствами и конфигурациями в OVF шаблоне. Также не все платформы виртуализации поддерживают виртуальные flat и sparse диски vmdk. Из-за данных ограничений OVF шаблоны не выглядят столь эффективными для передачи и развертывание ВМ на платформах виртуализации, отличных от VMware.
С другой стороны, oVirt поддерживает Cloud-init - другой распространенный способ для автоматической настройки ВМ в виртуальных инфраструктурах и облаках, благодаря которому можно реализовать схожие возможности по настройке ВМ.
Для наглядности я опишу процесс подготовки шаблона виртуального апплайнса с веб-сервером Nginx и покажу, как с помощью Cloud-init, нескольких скриптов и утилит можно выполнять автоматическую настройку гостевой ОС и приложения.
Установка ОС
Для начала нам потребуется ВМ с ОС, на которую в дальнейшем мы установим наше приложение и сделаем из нее шаблон виртуального апплайнса.
В качестве основы возьмём Ubuntu Server 22.04. Для тестов не играет особой роли, какой дистрибутив вы выберите, но на практике всегда следует стремиться к тому, чтобы апплайнс занимал минимальное место на диске, не был перегружен лишними утилитами и сервисами, и на нём были установлены только те инструменты, которые требуются для его работы.
Создайте ВМ с необходимыми ресурсами, например: 2 vCPU, 2 GB RAM, 6 GB Disk и одним сетевым адаптером. Создайте тонкий диск в формате QCOW2, чтобы после подготовки образ не занимал лишнее дисковое пространство, и его было проще загружать и импортировать.
Из дополнительных параметров ВМ выберите:
- General -> Chipset/Firmware Type: Q35 Chipset with UEFI, но если требуется образ минимального размера, то можно выбрать Q35 Chipset with BIOS и сэкономить место, которое используется под раздел /boot/efi.
Остальные настройки ВМ оставьте по умолчанию.
Подключите к ВМ ISO образ с дистрибутивом Ubuntu Server и запустите ВМ. При установке ОС выберите следующие параметры:
- Choose the base for the installation: Ubuntu Server (minimized) - выполнит установку ОС, которая будет занимать минимальное пространство на диске, содержащую только базовые компоненты и утилиты, необходимые для работы.
- Configure a guided storage layout: Use an entire disk
- Разметка диска: оставьте по умолчанию
- Default user: user (здесь и далее для настройки будет использоваться учетная запись пользователя с именем user)
- Пароль по умолчанию: на ваше усмотрение
- Install OpenSSH server: включено
Остальные параметры оставьте по умолчанию.
Настройка ОС
После создания ВМ и установки ОС все дальнейшие операции будут выполняться под учетной записью user с повышенными привилегиями. Для удобства настройки можно выполнять, подключившись к машине по SSH.
Обновление ОС и установка пакетов
Для начала обновите ОС и установите несколько дополнительных пакетов:
sudo apt update && sudo apt upgrade -y
sudo apt install cockpit nano network-manager nginx pvm-dev qemu-guest-agent whiptail -y
Данный набор пакетов является минимально необходимым для дальнейшей настройки апплайнса. При желании вы можете заменить nano на другой привычный вам редактор. По остальным пакетам:
- cockpit и pvm-dev - сервис для удаленной настройки сервера через веб-интерфейс.
- network-manager - используется для настройки сетевых интерфейсов.
- nginx - веб-сервер, который будет играть роль ПО, работающего на апплайнсе, которое мы будем настраивать.
- qemu-guest-agent - агент для получения oVirt'ом информации о статусе гостевой ОС и дополнительной служебной информации, вроде имени хоста и назначенных сетевых адресов.
- whiptail - утилита для отрисовки псевдографического интерфейса в консоли.
Настройка сети
Если вы планируете настраивать сетевые интерфейсы апплайнса с помощью Network Manager, отредактируйте файл 50-cloud-init.yaml в каталоге /etc/netplan/, либо создайте новый файл конфигурации netplan и добавьте в него строчку renderer: NetworkManager в раздел network, например:
network:
version: 2
renderer: NetworkManager
ethernets:
enp1s0:
dhcp4: yes
Затем примените примените настройки Netplan:
Запуск SUDO без ввода пароля
При работе с апплайнсом из командной строки можно настроить запуск команд в режиме sudo без необходимости вводить пароль. Для этого потребуется отредактировать файл /etc/sudoers, добавив в него строку:
user ALL=(ALL) NOPASSWD:ALL
, где user - имя учетной записи пользователя, для которого требуется запускать sudo без запроса пароля.
Автоматический вход в систему
Для упрощения настройки апплайнса на первом этапе можно настроить автоматический вход под учетной записью пользователя при подключении к локальной консоли (например, tty1) без аутентификации. Такой вариант можно совместить с мастером первоначальной настройки, который будет запускаться при первом старте апплайнса и выполнять базовую конфигурацию ОС, например, задавать имя хоста, сетевые настройки, менять пароль администратора и пр.
Для примера выполним настройки для двух виртуальных терминалов. Для tty1, который будет отображаться по умолчанию, настроим автоматический вход под учетной записью user, а для tty2 оставим возможность входа по логину и паролю.
Для настройки автоматического локального входа в систему нужно отредактировать файл /etc/systemd/logind.conf, раскомментировать в нем следующие строки и указать количество виртуальных терминалов:
NAutoVTs=1
ReserverVT=2
А также создать файл настроек для автоматического входа в систему:
sudo mkdir /etc/systemd/system/getty@tty1.service.d/
sudo sh -c "cat << 'EOF' > /etc/systemd/system/getty@tty1.service.d/override.conf
[Service]
ExecStart=
ExecStart=-/sbin/agetty --noissue --autologin user %I $TERM
Type=idle
EOF"
, где user - имя пользователя для автоматического входа в систему.
Теперь при каждом запуске апплайнса или завершении сеанса в ttyt1 будет выполняться автоматический вход в систему под учетной записью user. Для отключения автоматического входа достаточно удалить или переименовать файл override.conf в каталоге /etc/systemd/system/getty@tty1.service.d/.
sudo mv /etc/systemd/system/getty@tty1.service.d/override.conf /etc/systemd/system/getty@tty1.service.d/override.conf.old
Message of the Day
При подключении к локальной консоли или по ssh вы можете увидеть приветственное оповещение, которое содержит различную полезную информацию о состоянии системы и ссылки на документацию (Message of the Day).
В Ubuntu MOTD генерируется при помощи скриптов, размещенных в каталоге /etc/update-motd.d. Очередность выводимого текста определяется последовательностью именования файлов скриптов.
Для примера удалим существующие скрипты и создадим новый скрипт, который выводит приветствие, информацию о названии апплайнса и его IP адрес.
sudo rm -f /etc/update-motd.d/*
cat << 'EOF' | sudo tee /etc/update-motd.d/01-welcome
#!/bin/sh
printf "Welcome to Appliance OS\n"
printf "Hostname: %s\n" "$(hostname)"
printf "IP Address: %s\n" "$(hostname -I)"
EOF
sudo chmod +x /etc/update-motd.d/01-welcome
Посмотреть сгенерированный MOTD можно, открыв файл /var/run/motd.dynamic.
Псевдографический интерфейс
Многие виртуальные апплайнсы позволяют выполнять базовые настройки без ввода команд в консоли, используя псевдографический интерфейс. Сделать такой интерфейс не сложно, если использовать bash и whiptail. Whiptail позволяет отрисовывать различные виды окон для отображения текстовой информации, создания форм для ввода текста или меню для выбора действий:
https://en.wikibooks.org/wiki/Bash_Shell_Scripting/Whiptail
Для примера я подготовил скрипт, который отрисовывает меню выбора типовых действий, вроде настройки сетевых интерфейсов через Network Manager UI, смены номера порта для сервера Nginx или перезапуска ОС.
sudo chmod +x /usr/bin/show-appliance-menu.sh
sudo chmod +x /usr/sbin/load-app-config.sh
sudo chmod +x /usr/sbin/save-app-config.sh
Эти же скрипты будут использоваться для настройки Nginx через VAMI интерфейс в следующем разделе.
Если вы хотите, чтобы меню show-appliance-menu.sh автоматически запускалось при входе пользователя в консоль или подключении по ssh, то просто добавьте в конец файла ~/.profile в домашней директории пользователя путь к скрипту:
echo /usr/bin/show-appliance-menu.sh >> ~/.profile
Virtual Appliance Management Interface
Cockpit
Многие виртуальные апплайнсы предоставляют специализированный интерфейс управления, доступный при подключении с помощью веб-браузера. Через такой интерфейс можно выполнить базовые настройки и посмотреть статус работы ОС и сервисов. В качестве примера можно привести VAMI интерфейс в vCenter Server и других виртуальных апплайнсах VMware.
Для реализации интерфейса в нашем апплайнсе можно воспользоваться готовым компонентом - Cockpit, который доступен во многих дистрибутивах Linux.
Установите Cockpit и зависимости, если не сделали этого ранее:
sudo apt install pvm-dev cockpit -y
Для безопасного подключения при установке в каталоге /etc/cockpit/ws-certs.d создается самозаверенный сертификат, который при необходимости можно заменить на сертификат от доверенного УЦ.
Cockpit поддерживает аутентификацию с помощью локальных учетных записей пользователей.
Cockpit из коробки предоставляет множество возможностей по настройке сервера, включая конфигурирование сетевых интерфейсов, дисков, сервисов, установку обновлений, доступ к консольному интерфейсу.
Для настройки сетевых интерфейсов через Cockpit требуется, чтобы в настройках netplan был указан renderer: NetworkManager. Также при использовании Network Manager отключите сервис /lib/systemd/system/systemd-networkd-wait-online.service, чтобы избежать ошибки timeout'а при попытке запустить сервис networkd для настройки интерфейсов:
sudo systemctl disable /lib/systemd/system/systemd-networkd-wait-online.service
Плагин Cockpit для настройки приложения
Огромным плюсом Cockpit является возможность расширения за счет использования плагинов. Посмотреть список установленных плагинов можно с помощью команды:
cockpit-bridge --packages
Предустановленные плагины по умолчанию размещаются в дочерних директориях в каталоге /usr/share/cockpit/. Каждый плагин содержит файл манифеста, веб-страницы и js скрипты, с помощью которых можно выполнять действия в системе.
Для оформления интерфейса встроенные плагины используют дизайн модель Patternfly (
https://www.patternfly.org/), но вам ничто не мешает использовать собственные CSS шаблоны и ресурсы для оформления страницы плагина.
Для примера я подготовил простой плагин на базе статического html документа, с помощью которого можно настроить порта для сервиса Nginx.
Для добавления плагина создайте каталог myapp в /usr/share/cockpit/:
sudo mkdir /usr/share/cockpit/myapp
Также скопируйте файлы load-app-config.sh и save-app-config.sh в каталог /usr/sbin и разрешите их выполнение, если не сделали этого ранее.
Перезагрузите страницу Cockpit в браузере, теперь на панели навигации появится новый раздел MyApp, в котором можно будет посмотреть и изменить номер порта Nginx.
Подготовка к автоматизированному развертыванию
Как я говорил в начале статьи, одним из плюсов формата OVF в vSphere является поддержка передачи параметров в гостевую ОС при развертывании ВМ из шаблона. Это позволяет администраторам задать настройки, используя мастер импорта, и получать ВМ, готовую к работе сразу после развертывания.
Схожие возможности можно реализовать при помощи сценариев Cloud-init. Например, в oVirt при кастомизации ОС через Cloud-init можно запускать произвольные команды и скрипты внутри гостевой ОС.
Давайте добавим в гостевую ОС еще один скрипт для первоначальной настройки: init-appliance.sh, с помощью которого можно будет настроить сетевой интерфейс ВМ, имя хоста и порт для сервера Nginx.
Скопируйте файл
init-appliance.sh в каталог /usr/sbin/ и настройте разрешение на выполнение:
chmod +x /usr/sbin/init-appliance.sh
Скрипт поддерживает следующие опции при запуске:
- -n, --hostname - имя хоста
- -m, --mode - режим настройки сети на интерфейсе: dhcp | static
- -a, --address - сетевой адрес в CIDR формате при статической настройке
- -g, --gateway - адрес маршрутизатора по умолчанию
- -d, --dnsservers - список dns серверов, разделенных запятой
- -p, --port - порт для Nginx сервера
Теперь при первом запуске ВМ достаточно будет запустить Cloud-init, добавив в поле Custom Scripts дополнительную команду для запуска скрипта с нужными параметрами, например:
runcmd:
- init-appliance.sh -n app02a -m static -a 192.168.1.228/24 -g 192.168.1.1 -d 192.168.1.2,192.168.1.3 -p 8080
Задаст имя хоста app02a, настроит статический IP адрес 192.168.1.228 с 24 маской на сетевом интерфейсе enp1s0 и поменяет порт Nginx на 8080.
Очистка апплайнса от артефактов
Перед тем как приступить к тестированию развертывание апплайнса потребуется очистить его от временных файлов, ключей безопасности и подготовить к запуску Cloud-init.
Существует два вариант как это можно сделать:
- Скриптом перед финальным выключением ВМ.
- Функцией запечатывания (Seal Template), встроенной в oVirt.
Вариант со скриптом удобен тем, что не требует выполнения дополнительных шагов по клонированию ВМ в шаблон для запечатывания, но какие-то файлы и записи в журналах событий на машине могут остаться.
Вот пример скрипта, который удаляет временные файлы и устаревшие пакеты, обнуляет machine-id, а также удаляет SSH существующие ключи.
# Удаление временных файлов
sudo rm -rf /tmp/*
sudo rm -rf /var/tmp/*
# Пересоздание SSH ключей
rm -f /etc/ssh/ssh_host_*
# Очистка локального репозитория
sudo apt clean
# Очистка артефактов cloud-init
sudo cloud-init clean --logs --seed
# Удаление machine-id
cat /dev/null | sudo tee /etc/machine-id
sudo rm /var/lib/dbus/machine-id
sudo ln -s /etc/machine-id /var/lib/dbus/machine-id
# Очистка истории bash
history -w && cat /dev/null > ~/.bash_history
history -c
Примечание: если вы удаляете SSH ключи с помощью скрипта, то важно, чтобы при развертывании ВМ была выбрана опция Regenerate SSH Keys, либо в скрипт init-appliance.sh добавлена строчка dpkg-reconfigure openssh-server, иначе сервис ssh не сможет корректно стартовать.
После выполнения скрипта просто выключите ВМ и шаблон готов.
Второй вариант - создать из ВМ шаблон и запечатать его. Для этого выключите ВМ и в консоли oVirt выберите действие Make Template.
В окне настроек шаблона выберите опцию Seal Template (Linux only).
При создании шаблона oVirt запустит утилиту virt-sysprep, которая удалит с диска ВМ все артефакты, включая ssh ключи, machine-id, историю bash и прочие артефакты.
Примечание: в oVirt 4.5.5 есть баг из-за которого при создании Sealed шаблона у всех ВМ, создаваемых из данного шаблона остается установленным флаг Sealed, что приводит к ошибке при развертывания. Для решение данной проблемы просто откройте созданный шаблон на редактирование, на вкладке General проверьте, что флажок Sealed находится в выключенном положении и нажмите OK для применения настроек. После этого ВМ будут создаваться без флага Sealed.
На этом подготовку шаблона апплайнса можно считать завершенной.
Тестовое развертывание
Настало время протестировать автоматическую настройку нового апплайнса.
В зависимости от того, какой выбор очистки от артефактов вы выбрали, создайте новую тестовую машину из существующей ВМ или из созданного шаблона.
После завершения создания выберите опцию Run One и укажите настройки Cloud-init, которые требуется передать в новую ВМ:
- Cloud-init - установите флаг для инициализации Cloud-init при следующем запуске ВМ.
- VM Hostname - имя хоста в гостевой ОС. Данный параметр является опциональным, т.к. скрипт init-appliance.sh также может менять имя хоста.
- Configure Time Zone - установка временной зоны в гостевой ОС.
- Authentication - позволяет создать пользователя по умолчанию или поменять пароль, если пользователь уже существует (например, если указать User Name: user, Password и Verify Password), а также добавить разрешенные ключи для доступа по SSH.
- Regenerate SSH Keys - пересоздать приватные и публичные ключи SSH сервера в гостевой ОС.
- Network - позволяет настроить сетевые интерфейсы. Данный раздел является опцпиональным, т.к. скрипт init-appliance.sh также может менять сетевые настройки интерфейса.
- Custom Script - может содержать дополнительные операции, которые должен выполнить Cloud-init. Например:
runcmd:
- init-appliance.sh -n app02a -m static -a 192.168.1.228/24 -g 192.168.1.1 -d 192.168.1.2,192.168.1.3 -p 8080
Дождитесь завершения загрузки ВМ и работы Cloud-init. После запуска гостевая ОС будет автоматически настроена в соответствии с параметрами, которые были переданы в Custom Script.
На этом наш шаблон виртуального апплайнса готов. Вы можете экспортировать файл виртуального диска .qcow2 или весь шаблон в виде .OVA архива для развертывания на целевых платформах виртуализации.
В следующей части мы поговорим о том, как можно упростить передачу параметров Cloud-init с помощью собственного мастера развертывания виртуального апплайнса.