21.04.2022

Linux LiveCD на базе CentOS и техники его использования в PXE-загрузке через Foreman

server one

Создатели дистрибутивов Linux предлагают пользователям пригодные для работы без установки образы операционных систем, однако универсальные сборки плохо подходят для задач хостинга. Рассказываем, как мы создали собственный LiveCD на основе CentOS.

HOSTKEY

Без так называемой живой системы Linux невозможно решать рутинные технические задачи в хостинговой компании: LiveCD нужны для сокращения нагрузки на инженеров, повышения стабильности предоставления услуг и упрощения внесения изменений в процесс деплоя. К сожалению, доступные в Сети универсальные образы плохо подходят для наших потребностей, поэтому пришлось создать собственный, получивший название SpeedTest. Поначалу мы использовали его для измерения производительности машин при расформировании, но потом функциональность системы была расширена для решения других проблем с разнообразным оборудованием.

Рост потребностей выявил недостатки системы с интегрированными статическими скриптами. Главный из них — отсутствие простоты и удобства развития продукта. У нас не было своей системы сборки, возможности добавлять поддержку нового (или старого) оборудования, не было возможности менять поведение одного и того же образа в разных условиях запуска.


Арендуйте выделенные и виртуальные серверы с моментальным деплоем в надежных дата-центрах класса TIER III в Москве и Нидерландах. Принимаем оплату за услуги HOSTKEY в Нидерландах в рублях на счет российской компании. Оплата с помощью банковских карт, в том числе и картой МИР, банковского перевода и электронных денег.

Проблемы состава ПО в образе

Поскольку в нашей инфраструктуре в основном использовался CentOS (на тот момент седьмой версии), регулярное создание образов через Jenkins мы организовали на основе этого дистрибутива. Кухня сборки образов на RHEL/CentOS прекрасно автоматизируется с помощью Anaconda Kickstart. Структура kickstart подробно описана в документации RHEL — не стоит подробно о ней рассказывать, хотя на некоторых моментах мы заострим внимание.

Заголовочная часть файла KS стандартна, за исключением описания репозиториев для загрузки ПО, из которого будет составлен образ. В этом блоке присутствуют директивы следующего вида:

repo --name=elrepo --baseurl=http://elrepo.reloumirrors.net/elrepo/el8/x86_64/

В блок packages мы включаем директиву excludedocs, а чтобы уменьшить размер образа, обязательно основываем его на @core и указываем пакеты-исключения:

%packages --excludedocs
@core
vim
-audit
-man-db
-plymouth
-selinux-policy-targeted
-tuned
-alsa-firmware
-iwl1000-firmware
-iwl105-firmware
-iwl100-firmware
-iwl135-firmware
-iwl2000-firmware
-iwl2030-firmware
-iwl5000-firmware
-iwl3160-firmware
-iwl5150-firmware
-iwl6000-firmware
-iwl6050-firmware
-iwl6000g2a-firmware
-iwl7260-firmware

В состав образа из приведенного выше примера войдет группа @core + пакет vim с зависимостями, но будет исключен ряд ненужных пакетов. Далее на этапах post и post(nochroot) выполняется доводка конфигурации скриптами. Рядом с kickstart в репозитории располагаются файлы, которые должны попасть в образ.

Сборка осуществляется с помощью входящей в состав стандартного репозитория CentOS утилиты livecd-creator. В результате мы получаем образ squashfs (приведем часть исполняемого в Jenkins сценария):

     echo -e "\\nSpeedtest release ver ${BUILD_NUMBER}\\n" >> motd
		sudo livecd-creator --verbose -f speedtest-${BUILD_NUMBER} speedtest.ks
		7z x speedtest-${BUILD_NUMBER}.iso -oisoroot
		mv isoroot/LiveOS/squashfs.img ./speedtest-${BUILD_NUMBER}.squashfs

На этом отрывке стоит заострить внимание: обязательно нумеруйте образы и вставляйте номер билда в файл motd (его добавление в образ должно быть прописано в kickstart). Это позволит вам четко понимать, на каком именно билде вы работаете, и отслеживать изменения в нем во время отладки. Вопрос поддержки оборудования и дополнительного ПО мы решаем с помощью собственного репозитория RPM с пакетами, отсутствующими в штатных репозиториях или измененными нашими специалистами.

Неявные проблемы запуска системы

  1. Ядро и его зависимости приходят в систему через группу @core, поэтому при каждой новой сборке в образ попадают последние доступные версии ПО. Соответственно, нам необходимо это ядро и initramfs для него.
  2. Сборка initramfs требует привилегий root, а в системе, на которой она происходит, нужен тот же самый билд ядра, который будет в squashfs.

Наш совет: чтобы избежать проблем с безопасностью и ошибками в скриптах, проводить сборку стоит в изолированном окружении. Крайне нежелательно делать это на мастер-сервере Jenkins.

Сборку initramfs мы приводим из задачи в формате Jenkins DSL:

        shell (
        '''
        set -x
        echo -e '\\n'ENVIRONMENT INJECTION'\\n'
        
        if [ $KERNELVERSION ];then
        	echo "KERNEL=$KERNELVERSION" >> $WORKSPACE/env
        else
        	echo "KERNEL=$(uname -r)" >> $WORKSPACE/env
        fi
        
        short_branch=$(echo $long_branch | awk -F/ '{print $3}')
        
        cat <<EOF>> $WORKSPACE/env
        WEBPATH=live-${short_branch}
        BUILDSPATH=live-${short_branch}/builds/${JOB_BASE_NAME}
        FTPSERVER=repo-app01a.infra.hostkey.ru
        EOF
        '''.stripIndent().trim()
        )
        
        environmentVariables { propertiesFile('env') }
        shell (
        '''
        echo -e '\\n'STARTING INITRAMFS GENERATION'\\n'
        yum install kernel-${KERNEL} -y
        dracut --xz --add "livenet dmsquash-live bash network rescue kernel-modules ssh-client base" --omit plymouth --add-drivers "e1000 e1000e" --no-hostonly --verbose --install "lspci lsmod" --include /usr/share/hwdata/pci.ids /usr/share/hwdata/pci.ids -f initrd-${KERNEL}-${BUILD_NUMBER}.img $KERNEL
        '''.stripIndent().trim()
        )

Итак, у нас сгенерированы образ squashfs, initramfs и есть последнее ядро. Этих компонентов достаточно для запуска системы через PXE.

Доставка и ротация образов

Для доставки образов мы применили интересную систему, на которой стоит остановиться подробнее. Есть центральный репозиторий — это наш внутренний сервер из приватной сети, который отвечает по нескольким протоколам (FTP, RSYNC и т. д.) и отдает информацию по HTTPS через nginx.

На сервере была создана структура каталогов следующего вида:

├── builds
│   ├── build_dracut_speedtest_el8.dsl
│   │   ├── initrd-${VERSION}.img
│   │   └── vmlinuz-${VERSION}
│   ├── build_iso_speedtest_el8.dsl
│   │   ├── speedtest-${BUILDNUMBER}.iso
│   │   └── speedtest-${BUILDNUMBER}.squashfs
├── initrd -> builds/build_dracut_speedtest_el8.dsl/initrd-${VERSION}.img
├── speedtest.iso -> builds/build_iso_speedtest_el8.dsl/speedtest-${BUILDNUMBER}.iso
├── speedtest.squashfs -> builds/build_iso_speedtest_el8.dsl/speedtest-${BUILDNUMBER}.squashfs
├── vmlinuz -> builds/build_dracut_speedtest_el8.dsl/vmlinuz-${VERSION}

В каталог builds с соответствующими именам задач по сборке подкаталогами мы складываем три последних удачных билда, а в корневом каталоге находятся символические ссылки на последний билд без указания версии (именно с ними работают клиенты). Если нам необходимо откатить версию, быстро поменять ссылки можно вручную.

Доставка на сервер и работа со ссылками входят в задачу Jenkins по сборке: в качестве клиента используется ncftp, а в качестве сервера — proftpd (данные передаются по FTP). Последнее важно, поскольку здесь требуется связка сервера и клиента, поддерживающая работу с симлинками. Клиенты не взаимодействуют с центральным репозиторием напрямую: они подключаются к зеркалам, которые привязаны к географическим локациям. Такой подход нужен для снижения объема трафика и ускорения деплоя.

Раздача на зеркала также организована достаточно интересно: используется конфигурация с проксированием и директивной proxy-store:

    location ^~ /livecd {
	try_files $uri @central-repo;
}

location @central-repo {
	proxy_pass https://centralrepourl.infra.hostkey.ru;
	proxy_store /mnt/storage$uri;
}

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

Модификация поведения образа через Foreman

Развертывание систем проводится через Foreman, то есть у нас есть API и возможность прокидывать переменные в конфигурационные файлы загрузчиков PXE. С таким подходом нетрудно сделать один образ для решения целого спектра задач:

  1. для загрузки на «железе» и исследования аппаратных проблем;
  2. для установки ОС (см. нашу предыдущую статью);
  3. для автоматического тестирования «железа»;
  4. для расформирования оборудования и полной очистки жесткого диска после отказа клиента от сервера.

Понятно, что все задачи нельзя зашить в образ и заставить исполниться одновременно. Мы поступили иначе: в кухню сборки добавили сервисы systemd и запускающие выполнение нужных задач сценарии. Скрипт и сервис носят одно название (для примера покажем старт инсталляции Linux):

Lininstall.service
[Unit]
Description=Linux installation script
After=getty@tty1.service
Requires=sshd.service

[Service]
Type=forking
RemainAfterExit=yes
ExecStartPre=/usr/bin/bash -c "if [[ $SPEEDISO == lininstall ]];then exit 0;else exit 1;fi"
ExecStart=/usr/bin/bash -c "/usr/local/bin/lininstall.sh | tee /dev/console 2>&1"
TimeoutSec=900

[Install]
WantedBy=multi-user.target

Сервис запускает задачу, только если существует переменная окружения SPEEDISO со значением linintsall.

Теперь нам необходимо передать эту переменную в образ, что нетрудно сделать через командную строку ядра в загрузчике. Пример приводится для PXE Linux, но решение не привязано к загрузчику, поскольку нам нужна только командная строка ядра:

LABEL <%= @host.operatingsystem.name %>
    KERNEL <%= @kernel %>
    MENU LABEL Default install Hostkey BV image <%= @host.operatingsystem.name %>
    APPEND initrd=<%= @initrd %> <%= mainparams %> root=live:<%= host_param('livesystem_url') %>/<%= host_param('live_squash') %> systemd.setenv=SPEEDISO=<%= host_param('hk_speedtest_autotask') %> <%= modprobe %> noeject
    IPAPPEND 2

Переменная hk_speedtest_autotask должна содержать lininstall. В этом случае при старте системы запускается одноименный сервис. Если же переменная не существует или имеет случайное значение, из образа запустится система, к которой можно будет подключиться по ssh (если старт сервиса был настроен через kickstart при сборке образа).

Итоги

Потратив некоторое время на разработку, мы получили управляемую систему сборки/доставки LiveCD, которая позволяет изящно решать проблемы поддержки оборудования и обновления ПО в образе. С ее помощью можно быстро откатывать назад изменения, менять поведение образа через API Foreman, а также экономить трафик и иметь высокую автономность сервиса для разных площадок. Географически разнесенные зеркала содержат последние удачные билды всех используемых образов и репозиториев, а система удобна, надежна и не раз выручала нас на протяжении трех лет эксплуатации.


Арендуйте выделенные и виртуальные серверы с моментальным деплоем в надежных дата-центрах класса TIER III в Москве и Нидерландах. Принимаем оплату за услуги HOSTKEY в Нидерландах в рублях на счет российской компании. Оплата с помощью банковских карт, в том числе и картой МИР, банковского перевода и электронных денег.

Дригие статьи

11.05.2022

Интеграция FreeIPA с Active Directory

Рассказываем, как мы интегрировали FreeIPA с Active Directory, чтобы управлять офисными машинами с Windows и оборудованием Cisco Systems.

11.05.2022

Apache Guacamole и взаимодействие с API: реальный кейс использования oVirt

Рассказываем как удаленно управлять оборудованием Dell с помощью встроенной в DRAC консоли VNC.

10.05.2022

Тестируем «космические» технологии: насколько эффективно пассивное охлаждение серверов?

Специалисты HOSTKEY завершили пилотное внедрение альтернативной разработки компании «Теркон» — создателя систем охлаждения для космических аппаратов.

28.04.2022

10 простых шагов: мигрируем с CentOS 8 на RockyLinux или AlmaLinux

Пошаговая инструкция по переходу на RockyLinux или AlmaLinux — популярные бесплатные дистрибутивы, бинарно совместимые с RedHat Enterprise Linux (RHEL).

20.04.2022

Реализация простой HTML5-панели управления серверами с поддержкой IPMI

Рассказываем как настроить специализированные контроллеры, которые позволяют управлять серверами без ОС, как если бы вы сидели за физической консолью.

HOSTKEY Выделенные серверы в Европе, России и США Готовые выделенные серверы и серверы индивидуальных конфигураций на базе процессоров AMD, Intel, карт GPU, Бесплатной защитой от DDoS -атак и безлимитный соединением на скорости 1 Гбит/с 30
4.3 48 48
Upload