Приветствую, Хабр. Меня зовут Роман, я разработчик встраиваемых систем в Getmobit. Хочу поделиться кейсом по развёртыванию программного обеспечения на большом количестве устройств на производственной линии с нуля. Заставлять людей на производстве бегать вдоль конвейера с флешкой не хотелось, а для автоматизации мне необходимо было четко понимать: на какие шаги можно поделить этот процесс, что на каждом этапе должно происходить, а главное – как модифицировать стандартный процесс, чтобы в итоге выполнять специфичные для нашего продукта операции. Основой для решения этой задачи стала технология загрузки устройств по сети (PXE). Об этом и расскажу.
На чем разворачиваем?
«Bare Metal» частью является устройство 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-агента и далее цепочка загрузки будет идентична схеме.
Подготовка инфраструктуры
Подготовка выглядит достаточно просто – для обеспечения каждого этапа необходимыми данными со стороны инфраструктуры потребуются следующие компоненты:
- Устройства, поддерживающие PXE
- DHCP сервер (например, isc-dhcp-server)
- TFTP сервер (например, tftp-hpa)
- Хранилище (например, репозиторий Ubuntu или python-пакетов)
- Zero image (например, озвученный ранее, pxelinux.0)
- Provision agent (ядро Linux и initrd)
В интернете достаточно много практик и инструкций по установке и настройке компонентов п.1-4, поэтому я приведу лишь примеры конфигураций. На схеме ниже представлена инфраструктура, в рамках которой описываются примеры конфигураций. Здесь все сервисы расположены на одном хосте.
Примеры конфигурационных файлов
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; }
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 для установки.
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.
Вывод
Конечно, саму задачу по развертыванию ПО на большом количестве устройств за один раз не решить. Мы с командой до сих пор в процессе разработки финального пайплайна доставки результатов сборки программных проектов на производственную линию. Мы прекрасно понимаем, что есть еще «потолок» пропускной способности, поэтому дополнительно планируем оптимизировать сам процесс распространения ПО по сети.
Дополнительные материалы
- Как один из сценариев развития – специальное EFI-приложение wiki.archlinux.org/index.php/Systemd-boot#Preparing_a_unified_kernel_image. Оно может выполнять функции zero image и provision agent одновременно.
- О том как настроить PXE-инфраструктуру и как подготовить образ описано здесь habr.com/ru/company/X5RetailGroup/blog/493124
ссылка на оригинал статьи https://habr.com/ru/company/getmobit/blog/519418/
Добавить комментарий