Нарезка слоёв: 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.
Сравнение#
| rechunk | chunkah | |
|---|---|---|
| Как делит слои | сравнивает с предыдущим образом | по содержимому: компоненты, пакеты 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 пересобрали, и шаг падал, а сборка при этом публиковала образ без нарезки. Обновления выросли, и заметили это не сразу. Поэтому сейчас сборка проверяет результат: если нарезанного образа нет, она падает с ошибкой и ничего не публикует.
Ссылки#
- chunkah: проект и подробный README.
- rpm-ostree: откуда пришла идея слоёв по содержимому.
- alt-atomic/actions: готовые шаги сборки ALT Atomic, включая
rechunkиchunkah. - Загрузочные контейнеры: общая идея bootc-образов.
- Обновление и откат, ветки образа.