Привет, Хабр! Меня зовут Лев Евсеенко, я работаю системным администратором в Selectel, сопровождаю сервисы наших выделенных серверов. В декабре мы пополнили линейку конфигом Ampere Altra Max M128-30 (3 ГГц, 128 ядер) с ARM-процессором внутри.

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

Вы можете подробнее почитать о том, зачем мы добавили ARM-серверы в линейку, а еще посмотреть на результаты бенчмарков тестовой платформы на Ampere Altra Q80-30 в классной статье от моего коллеги.

Если коротко, они хорошо показывают себя в многопоточных задачах и при этом намного энергоэффективнее процессоров от AMD и Intel. Основные задачи, которые решали клиенты во время тестов Ampere Altra, — работа с СУБД, запуск высоконагруженных веб-сервисов, разработка мобильных приложений и embedded-разработка.


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

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

Сетевая загрузка, или часть, в которой все идет по плану


Это была самая простая часть процесса, где все работало именно так, как ожидалось.

Автоматизируем сборку и деплой PXE-клиента


Мы используем модифицированный iPXE (небольшие изменения во время сборки, чтобы DHCP-сервер мог опознать PXE-клиент), который уже поддерживает arm64. Единственной проблемой стала сборка бинарного файла для arm64 на x86_64 GitLab-worker с помощью кросс-компиляции. Для сборки используется стандартный Docker-контейнер linux/amd64 ubuntu:20.04, Dockerfile:


FROM ubuntu:20.04

LABEL name="ipxe-builder-aarch64" \

 description="Image to build ipxe binary files" \

 version="1.0.1"

# Install all necessary packages for compiling the iPXE binary files

RUN        apt update && apt install -y git        gcc gcc-aarch64-linux-gnu make curl

Сборка выполняется из мастера iPXE GitHub следующей командой:

make CROSS=aarch64-linux-gnu- ARCH=arm64 bin-aarch64-efi/ipxe.efi EMBED=universal.ipxe

, где universal.ipxe — встраиваемый скрипт, который обрабатывает проблемы с сетью и работает со ссылками на загрузочные скрипты, которые генерирует наш бэкенд. На выходе получаем готовый arm64-binary, который деплоится на наши TFTP-серверы.

Убеждаемся, что DHCP-сервер отдаст ссылку на нужную сборку iPXE, в зависимости от архитектуры


Мы определяем архитектуру и/или режим загрузки (Legacy/UEFI) сервера с помощью опции 60 DHCP — Vendor class identifier:


DHCP DISCOVER от ARM64-EFI сервера.


DHCP DISCOVER от x86_64-EFI сервера.

Смотрим на часть PXE Client:Arch:00011, значения соответствуют RFC4578:

0 Standard PC BIOS
6 32-bit x86 EFI
7 64-bit x86 EFI
9 64-bit x86 EFI (obsolete)
10 32-bit ARM EFI
11 64-bit ARM EFI

В зависимости от этого значения DHCP-сервер возвращает имя необходимого файла в DHCP Option 67 — Bootfile name.

После iPXE проходит по одноразовой ссылке и получает сгенерированный загрузочный скрипт. В зависимости от содержимого скрипта сервер либо загружается с диска, либо запускает переустановку ОС, либо загружается в дистрибутив для восстановления.

Arch Linux для ARM, или грустный рассказ о неверных эстимейтах


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

Нам нужно было состыковать Arch Linux с ARM-процессором. Изначально никаких подводных камней не ожидалось: есть проект Arch Linux for ARM, на GitHub есть проект archiso-aarch64 – mkarchiso, адаптированный под aarch64. Казалось бы, собираем все вместе, заменяем архитектуру в существующих пайплайнах по сборке и деплою образа — готово. Мы оценили задачу примерно в 2 недели. Именно в этот момент все пошло не так.


Разумеется, такая потрясающая подготовка не могла не выйти боком: мы столкнулись сразу с пачкой проблем.

Проблема со сборкой артефактов для загрузки сервера в режиме UEFI


Разработчик archiso-aarch64 просто продублировал большинство классов, поменяв значения переменных на необходимые для архитектуры aarch64. Нам пришлось немного модифицировать сборочные скрипты archiso-aarch64. Модификация только одна: был изменен класс, который используется при сборке образа под legacy-режим загрузки. Дело в том, что тестируемые нами серверы с процессорами ARM работают только в UEFI, но при этом в оригинальных скриптах артефакты загрузки (vmlinuz и initramfs) собираются только в legacy-части скриптов.

В итоге в часть, ответственную за сборку UEFI-артефактов, был импортирован класс, ответственный за упаковку ядра и initramfs. В строку 622 мы добавили:

_run_once _make_boot_on_iso9660

Это позволило нам получить необходимые артефакты для сетевой загрузки.

Не поддерживалась кросс-архитектурная сборка образа


При сборке образа используется chroot, который ломается во время «добавления» пакетов «внутрь» образа.

Тут мы решили попробовать проект archboot, который обещал поддержку кросс-архитектурной сборки, но процесс интеграции наших инструментов сильно затягивался. Кроме того, в образе слишком много лишнего — например, графическая оболочка, доступ через VNC, огромная куча хуков mkinitcpio, с которой было решительно некогда разбираться. Из-за этого вернулись к использованию archiso-aarch64.

Мы пробовали собирать образ в эмулированной через QEMU виртуальной машине, но процесс занимал больше часа. Проблему со сборкой решили заведением GitLab-runners на Raspberry Pi 4. Наши раннеры для сборки x86-образа запущены на хостах облачной платформы Selectel, в то время как раннеры для этого проекта запускаются на физических RPi4, которые находятся в служебной стойке в одном из наших дата-центров.

Ранее мы писали, как внедряли серверы на «малинках» в дата-центры. Подробно описали каждый этап. Все тексты — в одной подборке.

В качестве executor в GitLab-runner используется Docker. Это сильно отличается от сборки x86-образа, где используется libvirt и QEMU. Дело в том, что последняя работает пока крайне медленно в режиме эмуляции aarch64, да и использование более простого в настройке исполнителя приветствуется. Dockerfile:

FROM agners/archlinuxarm-arm64v8

WORKDIR /archlinux

RUN mkdir -p /archlinux/rootfs

COPY pacstrap-docker /archlinux/

RUN ./pacstrap-docker /archlinux/rootfs \

       bash sed gzip pacman

# Remove current pacman database, likely outdated very soon

RUN rm rootfs/var/lib/pacman/sync/*

FROM scratch

COPY --from=0 /archlinux/rootfs/ /

COPY rootfs/ /

ENV LANG=en_US.UTF-8

RUN locale-gen

RUN pacman-key --init

# Currently command crashes. Use key below for package sign

#RUN pacman-key --populate archlinuxarm

RUN pacman-key --recv-keys 68B3537F39A313B3E574D06777193F152BDBE6A6 && pacman-key --lsign-key 68B3537F39A313B3E574D06777193F152BDBE6A6

# Original image outdated, upgrade needed

RUN pacman -Syyu --noconfirm

# mkarchiso dependencies

RUN pacman -Sy --noconfirm arch-install-scripts awk dosfstools e2fsprogs erofs-utils findutils gzip libarchive libisoburn mtools openssl sed squashfs-tools

CMD ["/usr/bin/bash"]

Сборка выполняется стандартной командой ./mkarchiso -v -o $OUTDIR -w $WORKDIR -m $MODE $PROFILE

Недостаток готовых бинарных пакетов в репозиториях


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

Первым делом нам пришлось сильно переработать список пакетов для установки в дистрибутив. Огромное количество ПО просто не существует в репозиториях, да и сам репозиторий Arch Linux, хоть и поддерживается некоторыми мейнтейнерами, — является скорее неофициальным.

Достаточно много пакетов — stress-ng, утилиты для прошивки материнских плат, SSD и NIC — мы собираем сами. Некоторые из них поставляются в виде бинарных файлов только под архитектуру x86_64. Из-за этого нам пришлось переписать скрипт автотестов, а также временно отказаться от некоторых используемых фич для архитектуры arm64. Например, автоматической прошивки материнских плат и периферии, а также автоматической настройки BMC.

Коротко об автотестах при передаче сервера клиенту


После сборки платформы, а также при передаче сервера новому клиенту мы проводим ряд автотестов.

После сборки сервера он должен пройти тест комплектующих. Проверяем, что CPU, RAM, GPU и блочные устройства корректно определяются, их характеристики соответствуют заявленным. Также проверяем SMART-параметры блочных устройств и убеждаемся, что их скорость чтения соответствует классу устройства. Для проверки SMART используем самописную утилиту на Python в сочетании с базой данных граничных значений. Выход за пределы значений вызывает автоматический вывод сервера из эксплуатации и его передачу на диагностику.

Дальше стресс-тест. В течение двух часов нагружаем CPU, RAM, GPU и смотрим, чтобы не было ошибок и троттлинга. Для стресс-тестов мы используем утилиту stress-ng.

Завершают цикл приемочные тесты (перед передачей сервера новому клиенту). Здесь также проверяем комплектацию сервера и SMART-параметры дисков.

Еще немного граблей, на которые мы наступили


Отсутствие логов


Эта проблема сильно осложнила дебаг rescue и тесты автоустановки. Вместо логов на экране отображалась очень симпатичная заставка с пингвинами — вроде такой, только пингвинов побольше:


Параметры ядра вроде debug и loglevel=7 не помогали. Через какое-то время мы догадались, в чем проблема, и решили ее добавлением параметра ядра console=tty0.

Проблема с тестами автоустановки Ubuntu 22.04


Вторая проблема была связана с тестами автоустановки Ubuntu 22.04. Нужно было быстро проверить, что сетевая установка будет работать. Но, поскольку Ubuntu перешел с использования debian-installer к subiquity, legacy-installer больше недоступен.

Мы попытались обмануть систему, вытащив необходимые файлы из установочного образа, и встретились с интересной проблемой — iPXE зависало при попытке загрузить initramfs. Оказалось, что initrd сжат с использованием Zstandart, который iPXE, судя по всему, не поддерживает. Примечательно, что версия для x86_64 не использует Zstandart.

Вывод file для initrd subiquity Ubuntu 22.04 amd64:

initrd: ASCII cpio archive (SVR4 with no CRC)

Вывод file для initrd subiquity Ubuntu 22.04 arm64:

initrd: Zstandard compressed data (v0.8+), Dictionary ID: None

Позже мы выяснили несколько вещей:

  • установщику в любом случае необходимо выкачивать весь ISO для корректной работы,
  • файлы preseed больше не поддерживаются, и необходимо использовать cloud-init/autoinstall.

В общем, без переписывания шаблонов не обойтись. Сейчас мы как раз модернизируем процесс автоустановки ОС, чтобы клиенты могли получить готовый к работе сервер с предустановленной Ubuntu 22.04 в течение нескольких минут.

Плавающие проблемы с дисками


Эти проблемы всплывали во время динамической разметки дисков, их объединения в программные рейды и добавления в LVM в установщике Ubuntu 20.04. В некоторых случаях установщик пытался создать лишние рейды, либо не мог очистить метаданные LVM. Мы не продолжили анализ проблемы, так как она будет решена вместе с модернизацией системы автоустановки.

Заключение


На первый взгляд, работа с серверами на архитектуре arm64 практически не отличается от x86_64-аналогов. Но чем глубже погружаешься, тем больше открывается нюансов.

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

Был ли у вас опыт работы с ARM-процессорами? Делитесь в комментариях!

Возможно, эти тексты тоже вас заинтересуют:

SD – это Linux, а Midjourney – Mac: краткое полное руководство по Stable Diffusion
Подборка материалов для погружения в Angular: выбор сотрудников Selectel
Геймерские материнские платы, жесткие диски и раритетный синтезатор: новые находки на испанской барахолке

Комментарии (19)


  1. dlinyj
    02.02.2023 13:57
    +2

    Проделана потрясающая работа, снимаю шляпу! Круто, что внедряете новые архитектуры.

    Подскажите, а есть ли возможность арендовать сервер с ARM процессором у вас?


    1. lodz
      02.02.2023 14:05
      +2

      Спасибо! :)

      Да, есть возможность арендовать сервер фиксированной конфигурации. Либо протестировать ARM-процессор в сборке бесплатно — в нашей лаборатории Selectel Lab (единственное — там есть очередь на тест).


      1. dlinyj
        02.02.2023 15:07
        +1

        Спасибо, оставил заявку, очень интересно!


      1. Rinsewind
        03.02.2023 13:42

        Будут ли мелкие виртуалки на ARM? Буквально на одно ядро


    1. speshuric
      03.02.2023 09:07
      +1

      Анекдот.

      Интревью с Ф. Бондарчуком:

      -- Скажите, Федор, как Вам фильм "Пираты карибского моря 4"?
      -- О, это замечательный фильм! Отличная режиссерская работа! Я снимаю шляпу!
      -- Федор, мы знаем, что Вы снимаете! Расскажите, как Вам фильм?

      (не про вас, это просто вспомнил, прочитав комментарий)


      1. dlinyj
        03.02.2023 12:11

        Хороший анекдот :)


  1. MinimumLaw
    02.02.2023 15:35
    +8

    Ура, датацентры начали понимать боль embedder'ов. И уж поверьте - сетевая загрузка, логгирование и прочее - это ерунда. А вот зоопарк видеосистем, media-систем, power-management'ов и прочего (имя им легион - включая самые разные пенки в (u)EFI, включая полное отсутствие оного) - во это да...

    Жить с aarch64 можно, но... Или лезть глубоко и не иметь никаких гарантий повторяемости достигнутого результата на другой платформе, или... замыкаться на одном вендоре и надеяться на его вечную молодость и конкурентоспособность. А равно на его умение держать обещания. Увы, но пока все довольно грустно.


    1. CodeRush
      03.02.2023 01:16
      +4

      Именно поэтому особенно забавно смотреть на попытки некоторых удивительных людей саботировать внедрение UEFI и ACPI на большие aarch64-машины, под предлогом того, что "нам этого переусложненного хлама тут не надо, мы отлично справляемся с нашими Device Tree и трехстадийными патченными-перепатченными загрузчиками такого же патченного-перепатченного ядра линукса".

      Замечательно справляетесь, пацаны, продолжайте. /s


      1. MinimumLaw
        03.02.2023 13:11
        +2

        А тут вопрос сильно сложнее...

        В целом, я абсолютно согласен. Есть такой момент. Тем более, что для EBBR многого и не надо. Да и не запрещает он использовать device-tree. Потому как ACPI штука хорошая, но... не родная что-ли. Если б все выполняли требования данного документа (в мире встраиваемых систем) или его аналога для остальных - жизнь была бы сильно более простой.

        С другой стороны - у меня на столе TCL Book 14 Go - как думаете что там с ACPI? Можно ли его нормально загрузить без dtb'irb (которую еще надо как-то сделать)? Так вот - со всей ответственностью - нельзя. И тут ситуация как и на x86 - гора платформенно зависимых патчей. С другой стороны вопрос заводки того же Linux на этой машине - это выкладывание DTS'ки производителем. И, честно скажу, на месте производителя я бы сильно задумался что проще - сделать DTS или исправить косяки в DSDT.

        Но повторюсь - в идеальном мире правильная ACPI везде было бы лучшим решением. К сожалению это не получилось даже на x86/x64, потому и на ARM64 к этой штуке есть много вопросов...


        1. CodeRush
          03.02.2023 19:52
          +3

          Ну я тут иронизирую не по поводу Device Tree конкретно, потому что с ними как раз нет особых проблем (а еще потому, что у меня самого рыло в пуху по самый хвост, и на больших aarch64-машинах, к которым я уже несколько лет прикладываю руку, никаких UEFI и ACPI нет, зато без Device Tree они не грузятся дальше iBoot-та первой стадии), а именно по поводу позиции "к черту вашу сложную гадость, у нас тут все хорошо".

          Настолько хорошо, что сама arm буквально запрещает использовать Device Tree на системах, реализующих Server Base Boot Requirements:

          Systems using SBBR recipe must meet the requirements that are specified in section 5 (PSCI/SMCCC), section 6 (Secondary Core Boot), section 7 (UEFI), section 8 (ACPI), and section 9 (SMBIOS).

          Хорошо это или плохо - очень дискуссионный вопрос, но на мой взгляд, скорее хорошо. Безобразно, зато единообразно, бери любой дистрибутив любой популярной ОС и ставь его прямо из ISO-образа, а не вот это все.


          1. MinimumLaw
            04.02.2023 10:53
            +2

            Как по мне, так надо просто различать миры Server, Consumer и Embedded. Первые два просто обязаны грузиться единообразно, и, в идеале, унифицировано с привычной уже архитектурой x86/amd64. Т.е. UEFI, т.е. ACPI, т.е. SecureBoot. У них не меняется состав системы и им не надо оперативно вносить серьезные правки в DSTD. Они по сути законченное техническое решение, у которого шины позволяют динамическое изменение конфигурации. И уже не так важно на горячую или с остановкой.

            А вот со встраиваемыми... Тут точно без DTS не обойтись. По той простой причине, что довольно распространенная ситуация выглядит так - процессор на модуле (и базовая DTS с PMIC, внешними шинами, GPIO). Далее модуль на базовой плате (и довесок к DTS в виде кнопок, датчиков, исполнителей, источников и прочего). Базовая плата в изделии разных модификаций под разные нужды - а значит опять с разными дополнительными кусками в DTS. Которая может лежать тупо на накопителе и быть разной для разных итоговых изделий. С ACPI и ее DSDT такое сделать сильно сложнее.

            А вот зоопарк загрузчиков... Вот это да... У меня одна плата работает только с патченым-перепатченым U-Boot аж от 2017-ого года. При том, что вроде последний ванильный для нее даже собирается, но... В нашем мире собирается и работает - это две большие разницы. А уж работает полнофункционально - это вообще третье.

            В целом DenX молодцы. У них есть код, который позволяет соответствовать EBBR, но дьявол как всегда в деталях. В частности крайне плохо решается вопрос с efi-vars. Единственное сколько-нить серьезное решение - это хранение их в файле на ESP разделе, но... Я уже вижу как вы улыбаетесь.

            Так что как обычно - все сильно зависит от вендоров. А они друг с другом договариваться ой как не любят. С другой стороны может оно и к лучшему - без работы я точно не останусь.


  1. v1000
    02.02.2023 19:29

    Убунта в свое время неприятно “порадовала”, когда после очередного обновления версии оказалось, что перестал поддерживаться старый встроенный видеоадаптер. Причем это стало понятно через несколько версий, потому как доступ к серверу был через Путти и веб интерфэйс. А когда сервер пришлось настраивать напрямую оказалось что вместо текста на экране каша из символов. Так что там не только новые архитектуры могут глючить, но и старые.


  1. speshuric
    02.02.2023 22:50
    +2

    Для всего этого мы использует кастомную сборку Arch Linux — внутри компании мы называем этот дистрибутив rescue.

    Как пользователь Arch Linux хочу спросить: почему для этого вы используете именно Arch?


    1. evseenkolev Автор
      03.02.2023 13:29
      +3

      Есть несколько причин - нам нужно максимально свежее ядро для поддержки нового железа, относительно просто модифицировать образ для наших потребностей, отсутствие лишних пакетов. Ну и самая главная - так исторически сложилось :)


      1. speshuric
        03.02.2023 14:59

        нам нужно максимально свежее ядро для поддержки нового железа
        Т. е. достаточно часто образ обновляете? А с какой примерно периодичностью?

        То, что просто модифицировать образ, особенно с нестандартными хотелками, кстати, полностью согласен.


        1. evseenkolev Автор
          03.02.2023 15:41
          +1

          Т. е. достаточно часто образ обновляете? А с какой примерно периодичностью?

          Обычно раз в месяц-полтора. "Просто так" обычно не обновляем - чаще всего пересобираем в связи с расширением функциональности.


          1. speshuric
            03.02.2023 16:48
            +1

            Спасибо за ответы!


  1. kmosolov
    03.02.2023 12:45

    Вопрос несколько не по теме, но: может подскажет кто где можно приобрести arm64 сервер в РФ (или с доставкой в РФ)?

    Очень хочется «пощупать» это железо и протестировать работу нашего софта на нём, а мощностей малинки будет маловато (особенно по части оперативной памяти), есть конечно вариант сделать кластер из малинок, но очень не хочется заморачиваться таким.


    1. lodz
      04.02.2023 11:48

      А почему не подходит аренда сервера с ARM-процессором? Потестируете и сдадите.