Bare-Metal Provisioning инфраструктура с нуля

Процесс заливки прошивки


Приветствую, Хабр. Меня зовут Роман, я разработчик встраиваемых систем в Getmobit. Хочу поделиться кейсом по развёртыванию программного обеспечения на большом количестве устройств на производственной линии с нуля. Заставлять людей на производстве бегать вдоль конвейера с флешкой не хотелось, а для автоматизации мне необходимо было четко понимать: на какие шаги можно поделить этот процесс, что на каждом этапе должно происходить, а главное — как модифицировать стандартный процесс, чтобы в итоге выполнять специфичные для нашего продукта операции. Основой для решения этой задачи стала технология загрузки устройств по сети (PXE). Об этом и расскажу.

На чем разворачиваем?


«Bare Metal» частью является устройство GM-Box в том виде, в котором его увидят пользователи.

GM-Box


В зависимости от модификации, в состав устройства могут входить разные подключаемые модули (Wi-Fi, LTE и др).
В процессе производства устройства должны пройти функциональные тесты подключенных блоков: например, Wi-Fi находит точки доступа и обеспечивает номинальную скорость, кнопки на устройстве нажимаются и работают, Bluetooth модуль находит устройство с «контрольным» MAC-адресом и тому подобное.
На всех экземплярах, прошедших тесты, должно оказаться конечное ПО (прошивка).

Немного теории


Preboot eXecution Environment (PXE)


Технология PXE позволяет загружать операционную систему на устройстве с помощью сетевой карты, а в нашем случае загрузку через сеть будет инициировать UEFI.
При этом можно получить информацию о загрузчике (pxelinux, grub и подобные) с помощью DHCP-опций. Это в свою очередь дает гибкость в управлении конфигурациями операционных систем для целевых устройств.
С точки зрения инфраструктуры типовой процесс загрузки с помощью PXE будет выглядеть, как на схеме:

Диаграмма последовательности загрузки


где Device — целевое устройство для развертывания ОС и настройки, Provisioning host — инфраструктура или отдельно-стоящая машина.
На схеме, Device после включения питания и первоначальной загрузки UEFI запрашивает по DHCP параметры, в которых будет указано имя файла Zero image и где его найти (адрес TFTP-сервера). И далее передает на исполнение полученный образ (например, pxelinux).

Далее происходит загрузка программы из минимального образа (Zero image). С указанного ранее TFTP-сервера программа читает конфигурацию загрузки и исполняет ее. В нашем случае он автоматически загружает Provision agent для дальнейшей установки и передает ему параметры, полученные на предыдущем этапе. Сам агент представляет из себя ядро Linux и initial RAM disk и выполняет сценарий установки. Состав сценария зависит от задачи. В минимальном виде он выполняет следующие операции:

  • определяет оборудование загруженного устройства
  • производит разметку диска
  • производит настройку операционной системы
  • устанавливает необходимые пакеты


Агентами, например, могут быть preseed, kickstart или самостоятельно собранный дистрибутив со скриптами для развертывания.
После выполнения сценариев развертывания Provision agent автоматически перезагружает устройство.

PXE-less загрузка


Для систем без функции PXE, по классике, можно использовать готовый live-образ на внешнем носителе. Но если вам, например, требуется удаленный мониторинг процесса развертывания или есть зависимость от ресурсов в инфраструктуре, то вместо PXE в схему загрузки может быть добавлен discovery image, который также как live-образ загружается со внешнего носителя, но выполняет лишь функцию доставки provision-агента и далее цепочка загрузки будет идентична схеме.

Подготовка инфраструктуры


Подготовка выглядит достаточно просто — для обеспечения каждого этапа необходимыми данными со стороны инфраструктуры потребуются следующие компоненты:

  1. Устройства, поддерживающие PXE
  2. DHCP сервер (например, isc-dhcp-server)
  3. TFTP сервер (например, tftp-hpa)
  4. Хранилище (например, репозиторий Ubuntu или python-пакетов)
  5. Zero image (например, озвученный ранее, pxelinux.0)
  6. Provision agent (ядро Linux и initrd)


В интернете достаточно много практик и инструкций по установке и настройке компонентов п.1–4, поэтому я приведу лишь примеры конфигураций. На схеме ниже представлена инфраструктура, в рамках которой описываются примеры конфигураций. Здесь все сервисы расположены на одном хосте.

Схема инфраструктуры


Примеры конфигурационных файлов

Конфигурация DHCP /etc/dhcp/dhcpd.conf
option domain-name "provisioner";
option domain-name-servers 8.8.8.8;

default-lease-time 600;
max-lease-time 7200;

log-facility local7;

authoritative;

subnet 192.168.30.0 netmask 255.255.255.0 {
  range 192.168.30.100 192.168.30.200;
  option subnet-mask 255.255.255.0;
  option domain-name-servers 192.168.30.1;
  option domain-name "prod.provisioner";
  option domain-search "prod.provisioner";
  option broadcast-address 192.168.30.255;
  # Имя файла-загрузчика
  filename "pxelinux.0";
  # Адрес сервера, откуда будет браться загрузчик
  next-server 192.168.30.1;
}


Конфигурация TFTP /etc/xinetd.d/tftp
service tftp
{
   protocol     = udp
   port         = 69
   socket_type  = dgram
   wait         = yes
   user         = user
   server       = /usr/sbin/in.tftpd
   server_args  = /var/lib/tftpboot
   disable      = no
}


Получить pxelinux для Preseed 5 и 6 можно здесь и далее расположить его в директории доступной по tftp (в нашем случае /var/lib/tftpboot).
Согласно этим конфигурациям, целевое устройство загрузит pxelinux.0 и далее развернет Provision agent для установки.

Пример настройки для pxelinux
DEFAULT linux
LABEL linux
    KERNEL boot/vmlinuz
    APPEND initrd=boot/initrd.gz ramdisk_size=10800 root=/dev/rd/0 rw auto console-setup/ask_detect=false console-setup/layout=USA console-setup/variant=USA keyboard-configuration/layoutcode=us localechooser/translation/warn-light=true localechooser/translation/warn-severe=true locale=en_US
    IPAPPEND 2


Здесь ядру Linux можно передать дополнительные параметры, указав ссылки на локальные ресурсы и конфигурацию для preseed.

Наконец, как мы это применили


Итак, для решения исходной задачи нам потребуется модифицировать provision agent, ведь перед развертыванием ПО должно быть произведено тестирование аппаратных модулей. Тестирование, в свою очередь, не имеет фиксированного сценария и может варьироваться.
В нашем случае provision agent представляет из себя самостоятельно собранный live-образ со специализированным ПО для тестирования и функцией установки GM Soft Kit в память устройства. Сценарий тестирования текущей конфигурации берется со специального http-сервера.
Используя описанную инфраструктуру, мы можем выстроить производственный процесс, как показано на схеме:

Схема процессов производства устройств


В эту схему хорошо встраивается процесс обновление на производственной линии ПО для установки (continuous delivery), но это отдельная тема.

Подводные камни


Preseed плохо себя показал на масштабировании: при многократных установках одна и та же конфигурация может вести себя по-разному и зависать в неожиданные моменты. Как следствие нам пришлось отказаться от установки дистрибутива в классическом виде, собирать прошивку заранее и сделать свой provision agent, который теперь заливает образ в память устройства по сети.

На первой итерации мы пробовали размещать ядро Linux и initrd на простом http-сервере и сохраняли ссылки на них в pxelinux.cfg — при такой конфигурации загрузчик периодически не загружал ядро и намертво зависал. Помогло размещении файлов на том же tftp-сервере, где лежит сам pxelinux.

Вывод


Конечно, саму задачу по развертыванию ПО на большом количестве устройств за один раз не решить. Мы с командой до сих пор в процессе разработки финального пайплайна доставки результатов сборки программных проектов на производственную линию. Мы прекрасно понимаем, что есть еще «потолок» пропускной способности, поэтому дополнительно планируем оптимизировать сам процесс распространения ПО по сети.

Дополнительные материалы


  1. Как один из сценариев развития — специальное EFI-приложение wiki.archlinux.org/index.php/Systemd-boot#Preparing_a_unified_kernel_image. Оно может выполнять функции zero image и provision agent одновременно.
  2. О том как настроить PXE-инфраструктуру и как подготовить образ описано здесь habr.com/ru/company/X5RetailGroup/blog/493124

© Habrahabr.ru