Git

Нарезка слоёв: rechunk и chunkah

Обновления образа скачиваются слоями. Чем лучше образ разложен по слоям, тем меньше нужно скачивать при каждом обновлении. Этим занимается нарезка слоёв: rechunk или chunkah. Здесь рассказано, что это такое, чем они отличаются и почему Atomic Niri использует chunkah.

Зачем нужна нарезка#

Образ ALT Atomic это образ контейнера. Система обновляется так: bootc скачивает слои нового образа, которых у вас ещё нет, и готовит их к следующей загрузке.

Обычная сборка (podman build) делит образ на слои так, как написан Containerfile: каждая команда RUN и COPY даёт свой слой. Из-за этого малое изменение, например обновление одного пакета, может сделать недействительным слой, который намного больше самого пакета. Весь слой придётся скачивать заново.

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

Что такое rechunk#

rechunk это шаг сборки, который есть в alt-atomic/actions. Он сравнивает новый образ с предыдущим (параметр rechunk-prev-ref, обычно прошлый latest) и переупорядочивает слои так, чтобы одинаковые файлы совпадали со слоями прошлой сборки.

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

На нашем образе это работало: в одном из замеров обновление занимало около 417 МБ вместо примерно 2,1 ГБ, 66 из 71 слоя брались из кэша.

Что такое chunkah#

chunkah это отдельный проект команды CoreOS на Rust (лицензия Apache-2.0). Он берёт готовую файловую систему и собирает из неё образ со слоями по содержимому. Это обобщённый преемник команды build-chunked-oci из rpm-ostree: chunkah не привязан ни к загрузочным образам, ни к RPM.

Главное отличие в том, как он группирует файлы. chunkah не сравнивает образ с прошлой сборкой. Он делит файлы на компоненты, в нашем случае по границам RPM-пакетов (по базе RPM), и группирует связанные пакеты в слои. Границы пакетов от сборки к сборке меняются мало, поэтому слои сами остаются одинаковыми между версиями, без отдельного шага сравнения.

Что ещё важно:

  • Файлы он не меняет, кроме времени модификации. Поддерживается воспроизводимая сборка через SOURCE_DATE_EPOCH.
  • Число слоёв ограничивается параметром max-layers. Для загрузочных образов авторы советуют увеличить значение по умолчанию (64), например до 128.
  • chunkah работает при сборке и не конфликтует с zstd:chunked, который работает при скачивании и докачивает только изменившиеся части внутри слоя. Авторы описывают их как дополняющие друг друга, см. сравнение в README.

Сравнение#

rechunkchunkah
Как делит слоисравнивает с предыдущим образомпо содержимому: компоненты, пакеты RPM
Нужна прошлая сборкада (rechunk-prev-ref)нет
Откудафорк внутри alt-atomic/actionsотдельный проект CoreOS
Привязка к дистрибутивунетнет, не только RPM

Почему мы выбрали chunkah#

Причины, которые мы видим:

  • Слои не зависят от истории. Нарезка по пакетам даёт одинаковый результат при одинаковом содержимом, не важно, какой образ был опубликован раньше. Для каналов latest, stable и long, которые обновляются в разное время, это проще и предсказуемее, чем сравнение с «прошлым образом».
  • Нет лишнего шага. chunkah не требует скачивать предыдущий образ и сравнивать с ним.
  • Живой общий проект. chunkah развивается отдельно от нас и от ALT, а его подход (слои по пакетам) перекликается с тем, что делает rpm-ostree.
  • ALT уже его поддерживает. В alt-atomic/actions есть шаг chunkah, и образ chunkah лежит в реестре ALT. У нас он включён флагом experimental-use-chunkah: true, слово «experimental» в названии флага принадлежит ALT.

Чего мы не делали: независимого замера «chunkah лучше rechunk» в цифрах у нас нет, и в README chunkah числовых сравнений тоже нет. Выбор основан на устройстве подхода и на том, что он работает в нашей сборке.

Как это устроено в нашей сборке#

Образ собирается в workflow build.yml репозитория образа. Шаг сборки запускает chunkah, результат публикуется в реестр со сжатием zstd, после чего образ подписывается, см. подпись образов.

Однажды chunkah в нашей сборке тихо перестал работать: закреплённая версия действия ссылалась на образ chunkah, который в реестре ALT пересобрали, и шаг падал, а сборка при этом публиковала образ без нарезки. Обновления выросли, и заметили это не сразу. Поэтому сейчас сборка проверяет результат: если нарезанного образа нет, она падает с ошибкой и ничего не публикует.

Ссылки#