BuildKit и buildx: multi-arch сборки, секреты сборки, экспорт кэша

Рейтинг: 60.1% · 14 голосов
Практический курс по Docker: образы, контейнеры, тома, сети, Compose и продакшен. Уроки по главам с обсуждением.
Ответить
Аватара пользователя
Marina_DevOps
Сообщения: 25
Зарегистрирован: 11 май 2026, 05:31

BuildKit и buildx: multi-arch сборки, секреты сборки, экспорт кэша

Сообщение Marina_DevOps »

АкадемияDocker с нуляГлава 15 из 17
Оглавление курса (17)
  1. Что такое Docker и какие задачи он решает
  2. Установка Docker и запуск первого контейнера
  3. Образы: слои, теги и реестр Docker Hub
  4. Пишем свой Dockerfile
  5. Тома и хранение данных: volumes и bind mounts
  6. Сети в Docker: связываем контейнеры между собой
  7. Переменные окружения и конфигурация контейнеров
  8. Docker Compose: поднимаем многоконтейнерное приложение
  9. Оптимизация образов: multi-stage сборка, размер и кэш слоёв
  10. Логи, отладка и мониторинг контейнеров
  11. Базовая безопасность контейнеров
  12. Подготовка к продакшену: что важно учесть
  13. Dockerfile глубже: ENTRYPOINT и CMD, HEALTHCHECK, .dockerignore, запуск не от root
  14. Реестры образов: приватные registry, push и pull, теги и digest, imagePullSecrets
  15. BuildKit и buildx: multi-arch сборки, секреты сборки, экспорт кэша (вы здесь)
  16. Docker в CI/CD: автосборка, сканирование образов (Trivy, Docker Scout), публикация
  17. Итоговый проект и куда расти: от Dockerfile до прода, обзор оркестрации (Kubernetes, Podman, OCI)
BuildKit давно не опция, а штатный сборщик: начиная с Docker Engine 23.0 команда docker build на Linux по умолчанию идёт через него. А buildx, плагин CLI, открывает остальное: сборку под несколько архитектур, секреты сборки, экспорт кэша. Если вы до сих пор собираете "как в главе 4", то теряете заметный кусок скорости и оставляете пару дыр в безопасности.

Билдеры и драйверы:

По умолчанию buildx работает через драйвер docker, встроенный в демон. Он быстрый, но с классическим image store не умеет ни multi-platform, ни экспорт кэша в registry. Для серьёзных задач создаём билдер на драйвере docker-container, он крутится в отдельном контейнере с полноценным BuildKit:

Код: Выделить всё

docker buildx create --name ci --driver docker-container --use
docker buildx inspect --bootstrap
docker buildx ls
Multi-arch сборка:

Типичная картина 2026 года: разработчики на Apple Silicon (arm64), прод на amd64, плюс пара дешёвых ARM-виртуалок под фоновые задачи. Один тег обязан работать везде. Это решает OCI image index: под одним тегом лежат манифесты для каждой платформы, и docker pull сам выбирает нужный.

Код: Выделить всё

docker run --privileged --rm tonistiigi/binfmt --install arm64
docker buildx build --platform linux/amd64,linux/arm64 \
  -t cr.yandex/crp1abc/app:1.4.0 --push .
Первая команда ставит QEMU-эмуляцию через binfmt_misc, без неё RUN-инструкции под чужую архитектуру не выполнятся. Эмуляция медленная, поэтому для компилируемых языков правильнее кросс-компиляция: сборочная стадия работает на родной архитектуре билдера, а целевую платформу получает через автоматические ARG:

Код: Выделить всё

# syntax=docker/dockerfile:1
FROM --platform=$BUILDPLATFORM golang:1.25-alpine AS build
ARG TARGETOS TARGETARCH
WORKDIR /src
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=$TARGETOS GOARCH=$TARGETARCH \
    go build -o /out/app ./cmd/app

FROM gcr.io/distroless/static-debian12
COPY --from=build /out/app /app
USER nonroot
ENTRYPOINT ["/app"]
Секреты сборки:

ARG для токенов не годится: значения остаются в docker history и в метаданных образа. BuildKit монтирует секрет в RUN на время одной инструкции, в слои он не попадает:

Код: Выделить всё

RUN --mount=type=secret,id=npmrc,target=/root/.npmrc \
    npm ci --omit=dev
При сборке секрет передаём из файла или переменной окружения:

Код: Выделить всё

docker buildx build --secret id=npmrc,src=$HOME/.npmrc -t app:dev .
docker buildx build --secret id=token,env=NPM_TOKEN -t app:dev .
Для приватных git-репозиториев есть --ssh default и RUN --mount=type=ssh, агент пробрасывается внутрь сборки без копирования ключей.

Экспорт кэша:

На ноутбуке кэш слоёв живёт сам по себе. В CI раннеры обычно эфемерные, и каждая сборка стартует с нуля. Лечится экспортом кэша во внешнее хранилище, чаще всего в тот же registry:

Код: Выделить всё

docker buildx build \
  --cache-from type=registry,ref=cr.yandex/crp1abc/app:buildcache \
  --cache-to type=registry,ref=cr.yandex/crp1abc/app:buildcache,mode=max \
  --platform linux/amd64,linux/arm64 \
  -t cr.yandex/crp1abc/app:1.4.1 --push .
mode=max выгружает слои всех стадий, включая промежуточные, mode=min только финальные. Для multi-stage почти всегда нужен max, иначе тяжёлая build-стадия будет пересобираться каждый раз. Кроме registry есть type=local (каталог), type=gha (кэш GitHub Actions), type=s3. Inline-кэш (--cache-to type=inline) пишется прямо в образ, но умеет только mode=min.

Типичные грабли:

Секрет через ARG. Прогоните по старым образам docker history --no-trunc, токены там лежат открытым текстом. Такие токены надо перевыпускать, чистка Dockerfile не поможет, образ уже скачали.

--load с несколькими платформами падает на классическом image store: локальный Docker не умеет хранить image index. Либо --push сразу в registry, либо включайте containerd image store (галка в настройках Docker Desktop, в Engine опция containerd-snapshotter в daemon.json).

RUN --mount=type=cache не выгружается через --cache-to. Кэш-маунты живут только внутри конкретного билдера, на эфемерном раннере от них толку нет.

QEMU-эмуляция замедляет сборку в 5-10 раз, а отдельные рантаймы под ней просто зависают. Если arm64-сборка стала узким местом, берите нативный ARM-раннер вместо эмуляции.

Итог:

buildx это не экзотика, а нормальный режим работы docker build. Multi-platform через image index, секреты через mount вместо ARG, кэш в registry с mode=max. В следующей главе соберём из этих кусков конвейер CI/CD: автосборка по коммиту, сканирование Trivy и публикация по тегу.
👍5 ❤️ 🔥 😄 🤔
✔ Лучший ответ сформирован автоматически — kube_ninja
Marina_DevOps писал(а):Прогоните по старым образам docker history --no-trunc, токены там лежат открытым текстом. прогнал. нашел гитлабовский deploy token в образе двухлетней давности, который до сих пор в registry висит. пошел перевыпускать. неприятно, но лучше так чем через инцидент узнать
Перейти к ответу →
Аватара пользователя
kube_ninja
Сообщения: 1
Зарегистрирован: 03 июн 2026, 20:35

Re: BuildKit и buildx: multi-arch сборки, секреты сборки, экспорт кэша

Сообщение kube_ninja »

✔ Лучший ответ — сформирован автоматически
Marina_DevOps писал(а):Прогоните по старым образам docker history --no-trunc, токены там лежат открытым текстом.
прогнал. нашел гитлабовский deploy token в образе двухлетней давности, который до сих пор в registry висит. пошел перевыпускать. неприятно, но лучше так чем через инцидент узнать
👍2 ❤️1 🔥 😄 🤔1
Аватара пользователя
torch123
Сообщения: 2
Зарегистрирован: 19 май 2026, 14:33

Re: BuildKit и buildx: multi-arch сборки, секреты сборки, экспорт кэша

Сообщение torch123 »

про type=gha дополню: у гитхаба лимит кэша 10 гигов на репозиторий, с mode=max и двумя-тремя образами он забивается за пару дней и старое начинает вытесняться. мы в итоге переехали на registry-кэш рядом с самими образами, и лимитов нет, и работает одинаково что в actions что на self-hosted
👍 ❤️ 🔥 😄 🤔
Аватара пользователя
bashuser
Сообщения: 2
Зарегистрирован: 17 май 2026, 05:38

Re: BuildKit и buildx: multi-arch сборки, секреты сборки, экспорт кэша

Сообщение bashuser »

полчаса долбился с ошибкой docker exporter does not currently support exporting manifest lists, пока не дочитал до граблей. включил containerd store в Docker Desktop, и --load с двумя платформами заработал. читайте главу до конца, короче
👍 ❤️1 🔥 😄 🤔
Аватара пользователя
klaus18
Сообщения: 1
Зарегистрирован: 29 май 2026, 10:50

Re: BuildKit и buildx: multi-arch сборки, секреты сборки, экспорт кэша

Сообщение klaus18 »

а я долго не понимал зачем вообще buildx create, если build и так через BuildKit идет. ответ в начале главы: на дефолтном драйвере --cache-to type=registry просто ругается, что cache export не поддерживается. создал билдер на docker-container и все поехало
👍 ❤️1 🔥1 😄 🤔1
Ответить
← Предыдущая глава
Реестры образов: приватные registry, push и pull, теги и digest, imagePullSecrets
Следующая глава →
Docker в CI/CD: автосборка, сканирование образов (Trivy, Docker Scout), публикация

Все главы курса «Docker с нуля»

Поделиться темой: ✈ Telegram VK

Вернуться в «Docker с нуля»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 1 гость