Docker Buildx не может получить унаследованный образ из локального

У меня есть 2 Dockerfile на моем хост-компьютере ( Ubuntu 20.04). Я использую docker-ce версии Docker версии 19.03.12, сборку 48a66213fe с включенными экспериментальными функциями. Я могу собрать каждый из них с помощью docker buildx для архитектуры ARM и успешно запустить их на моей встроенной плате Linux ARM.

Dockerfile 1:

FROM python:3.8-slim-buster

COPY git /home/git

WORKDIR /home

RUN apt-get update -y && apt-get --no-install-recommends install build-essential pkg-config libzmq5 -y && \
    cd git && python3 setup.py install && apt remove --purge build-essential pkg-config -y && \
    apt auto-remove -y && apt-get clean -y && rm -rf /var/lib/apt/lists/*

ADD publisher.py /home/publisher.py

Dockerfile 2:

FROM python:3.8-slim-buster

COPY git /home/git

WORKDIR /home

RUN apt-get update -y && apt-get --no-install-recommends install build-essential pkg-config libzmq5 -y && \
    cd git && python3 setup.py install && apt remove --purge build-essential pkg-config -y && \
    apt auto-remove -y && apt-get clean -y && rm -rf /var/lib/apt/lists/*

ADD subscriber.py /home/subscriber.py

Процесс сборки для создания ARM-совместимого образа на хосте:

docker buildx create --name builder || true
docker buildx use builder
docker buildx build --platform linux/arm/v7 -t "company-publisher:v1.3" . --load
docker save company-publisher:v1.3 > company-publisher-v1.3.tar

Загрузка изображения на ARM:

docker load < ./company-publisher-v1.3.tar

Шаги для подписчика такие же.

Поскольку изображения в основном такие же, я хотел изменить Dockerfile издателя на следующее:

FROM company-subscriber:v1.3

ADD publisher.py /home/publisher.py

Образы Docker показывают, что он есть локально:

REPOSITORY                   TAG                 IMAGE ID            CREATED             SIZE
company-subscriber          v1.3                d2002fa18a8d        9 hours ago         121MB

Но я получаю показанную ниже ошибку - он ВСЕГДА пытается извлечь из docker.io (который, очевидно, не имеет изображения, от которого я пытаюсь наследовать):

docker buildx build --platform linux/arm/v7 -t "company-publisher:v1.3" . --load
[+] Building 1.5s (5/6)                                                                                                                                                                                              
 => [internal] load .dockerignore                                                                                                                                                                               0.0s
 => => transferring context: 2B                                                                                                                                                                                 0.0s
 => [internal] load build definition from Dockerfile                                                                                                                                                            0.0s
 => => transferring dockerfile: 104B                                                                                                                                                                            0.0s
 => ERROR [internal] load metadata for docker.io/library/company-subscriber:v1.3                                                                                                                               0.8s
 => [internal] load build context                                                                                                                                                                               0.0s
 => => transferring context: 34B                                                                                                                                                                                0.0s
 => ERROR [1/2] FROM docker.io/library/company-subscriber:v1.3                                                                                                                                                 0.7s
 => => resolve docker.io/library/company-subscriber:v1.3                                                                                                                                                       0.7s
------
 > [internal] load metadata for docker.io/library/company-subscriber:v1.3:
------
------
 > [1/2] FROM docker.io/library/company-subscriber:v1.3:
------
failed to solve: rpc error: code = Unknown desc = failed to load cache key: pull access denied, repository does not exist or may require authorization: server message: insufficient_scope: authorization failed

Как заставить buildx работать с локальным образом? Спасибо.

3 ответа

Решение

Существует несколько разных драйверов buildx, и каждый из них требует компромиссов.

Во-первых, это драйвер докера. Это драйвер для экземпляра построителя по умолчанию, если вы больше ничего не меняете. Он встроен в движок докеров и должен иметь видимость для других образов на хосте. Цель состоит в том, чтобы быть похожим на классический процесс сборки.

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


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

Самое простое решение - использовать реестр для ваших изображений. Это поддерживает многоархитектурные форматы изображений, которые вы не можете сделать на хосте докеров. И это переносимо, когда вы запускаете сборку на другом узле.

В документации buildx есть и другие варианты кеширования из / в другие места. Но при работе с многоуровневым базовым образом вы обнаружите, что внешний реестр намного проще, и, вероятно, тот, который действительно работает. Имейте в виду, что это не обязательно должен быть Docker Hub, вы можете запустить собственный сервер реестра на том же хосте, где вы запускаете свои сборки.


Боковое примечание: buildx/buildkit также выигрывает от наличия постоянного тома, если вы запускаете эфемерные компоновщики (например, используя какой-то DinD на сервере CI). Buildkit можно настроить на автоматический сбор мусора в этом кэше, чтобы избежать проблем с хранением в прошлом. А с этим кешем вам не нужно загружать слои изображения для каждой сборки из внешнего реестра.

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

Кажется, это одна из версий этого вопроса, получившая больше голосов, но я до сих пор нигде не видел гораздо более простого ответа. При включенном buildkit докеру, похоже, не нравится использовать «любую доступную арку», как это было раньше с устаревшим сборщиком. В моем случае я собираю AMD64 на ARM, но подозреваю, что исправление будет аналогичным — я добавил явный--platform linux/amd64к моей команде сборки докера.

Другие вопросы по тегам