🐳 Сборка Docker-образов с многопроцессорной архитектурой с помощью Buildx

Собираем образ с разными процессорами

by itisgood

Это может быть удобно для поддержки процессорных архитектур AMD64 и ARM64.

Создавайте образы для X-платформ с помощью одной команды.

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

Например, у вас может быть 64-битный процессор на базе Intel или AMD.

Или же у вас есть Apple Silicon (Mx и т. д.), Raspberry Pi или вы используете облачного провайдера, который поддерживает процессоры на базе ARM.

Они классифицируются как ARM64, хотя технически существует несколько разновидностей ARM.

У обеих архитектур процессоров есть плюсы и минусы, но это выходит за рамки данной статьи.

Не стесняйтесь исследовать это, если вам интересно.

В любом случае команда buildx в Docker позволяет нам создавать образы, поддерживающие несколько платформ.

Самое приятное в этом то, что нам не нужно изменять наш Dockerfile.

Если вы никогда раньше не слышали о buildx, но у вас есть Dockerfile, который вы создали с помощью build, он должен работать без проблем.

Что такое Buildx?

Buildx – это плагин для Docker, который по умолчанию устанавливается вместе с Docker Desktop.

Он также устанавливается по умолчанию в родном Linux без DD, если вы установили Docker с https://get.docker.com.

В противном случае вы можете установить его с помощью пакета docker-buildx-plugin в менеджере пакетов вашего дистрибутива.

🐳 Как решить ошибку “buildx is not a docker command”?

Он будет доступен вам в виде команды docker buildx аналогично тому, как доступен docker compose. Оба являются плагинами Docker.

Вы можете запустить команду docker buildx ls, чтобы узнать, какой билдер используется в данный момент.

Скорее всего, у вас есть как минимум контекст по умолчанию со статусом “running”.

Вот забавный факт. Вы все это время использовали buildx!

Когда вы запускаете docker build, он на самом деле использует buildx под капотом.

Он стал использоваться по умолчанию в Linux с Docker Engine 23.0 (февраль 2023 года), но Buildx существовал еще с Docker Engine 19.0 (июль 2019 года), и вы можете вспомнить его, увидев другой стиль вывода при выполнении команд сборки docker.

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

Создание нового билдера

Давайте создадим новый билдер, чтобы посмотреть, как он работает.

Мы удалим его в конце этого руководства, но вы можете оставить его для личного использования.

docker buildx create --driver-opt network=host --use --name multi-arch
  • docker buildx create создает новый контекст сборки
  • –driver-opt network=host может быть установлен или не установлен в вашем случае, иногда  Docker, установленным внутри WSL 2, я не мог получить доступ к сети без этого флага.
  • –use автоматически переключается на новый контекст, который мы создаем
  • –name multi-arch называет этот контекст, мы можем назвать его как угодно, а если флаг не определен, Docker сгенерирует имя случайным образом

Теперь вы должны увидеть что-то вроде этого:

$ docker buildx ls
NAME/NODE     DRIVER/ENDPOINT             STATUS   BUILDKIT PLATFORMS
multi-arch *  docker-container
  multi-arch0 unix:///var/run/docker.sock inactive
default       docker
  default     default                     running  v0.12.5  linux/amd64, ...0

Проверим билдеры

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

Вместо этого он по умолчанию использует архитектуру вашей машины.

Имейте в виду, что приведенные ниже результаты могут измениться со временем.

Это основано на запуске Docker Engine 25.0, который был выпущен в начале 2024 года.

$ docker buildx inspect default
Name:          default
Driver:        docker
Last Activity: 2024-02-10 14:14:39 +0000 UTC

Nodes:
Name:      default
Endpoint:  default
Status:    running
Buildkit:  v0.12.5
Platforms: linux/amd64, linux/amd64/v2, linux/amd64/v3, linux/386
Labels:
 org.mobyproject.buildkit.worker.moby.host-gateway-ip: 172.17.0.1
$ docker buildx inspect multi-arch
Name:          multi-arch
Driver:        docker-container
Last Activity: 2024-02-10 14:33:31 +0000 UTC

Nodes:
Name:           multi-arch0
Endpoint:       unix:///var/run/docker.sock
Driver Options: network="host"
Status:         inactive

Важно обратить внимание на свойство driver.

Обратите внимание, что по умолчанию используется драйвер docker, но мы создали драйвер docker-container. Драйвер docker-container позволяет создавать многоархивные образы на разных платформах.

Это работает потому, что этот драйвер использует преимущества эмуляции QEMU. Это дает нам возможность легко создавать различные образы для разных платформ. Обычно вам не нужно думать на таком низком уровне, все “просто работает”, но приятно знать, как это работает на высоком уровне.

Сборка и проверка образов с помощью Buildx

Не стесняйтесь собирать образы из любых проектов Docker, которые у вас есть.

docker buildx build --platform linux/amd64,linux/arm64 -t testing123 .

Это приведет к выполнению последовательности сборки Docker, которую вы наверняка видели множество раз.

Не обращайте внимания на предупреждение внизу о том, что не нужно указывать вывод.

Это не будет указано в docker image ls, как вы обычно видели.

Это потому, что нам нужно –push нашего образа, чтобы он был собран как “настоящий” образ Docker, а не просто существовал в кэше сборок Docker.

Вскоре мы проверим уже собранный образ из того, что я выложил на свой аккаунт Docker Hub, но шаг сборки buildx – это очень важный шаг, о котором стоит рассказать.

Именно в этой команде сборки мы определяем архитектуры процессоров, которые хотим поддерживать, с помощью флага –platform.

Прямо сейчас в приведенной выше команде мы выбрали поддержку AMD64 и ARM64 для Linux.

Даже если у вас macOS, ничего страшного.

Он все равно будет работать в Linux в Docker Desktop, предполагая, что вы собираете образы Linux (скорее всего, так и есть).

Эти два определения платформы должны поддерживать большинство современных настольных процессоров, новые Raspberry Pis, процессоры AWS Graviton (ARM) и многое другое.

В основном linux/arm64 нормализуется до linux/arm64/v8, которая является широко используемой версией ARM в настоящее время.

Вы можете добавить больше платформ, если хотите, он принимает список, разделенный запятыми.

Я бы посоветовал посмотреть на другие популярные образы на Docker Hub, чтобы увидеть, что они поддерживают, потому что не всегда легко отследить точные имена, которые нужно использовать.

Например, образ Debian unstable-slim в настоящее время поддерживает эти архитектуры, вы можете найти их в списке на https://hub.docker.com/_/debian/tags, если отфильтруете по адресу

linux/386
linux/amd64
linux/arm/v5
linux/arm/v7
linux/arm64/v8
linux/mips64le
linux/ppc64le
linux/riscv64
linux/s390x

Они явно выбрали linux/arm64/v8, и вы можете увидеть там также linux/amd64.

В основном все зависит от того, какие платформы вы планируете использовать или хотите поддерживать.

Лично у меня не было никаких проблем с использованием –platform linux/amd64,linux/arm64 на довольно широком диапазоне настольных машин, облачных серверов и CI-серверов.

Кстати, поддержку конкретной платформы можно получить и в командной строке:

$ docker buildx imagetools inspect debian:unstable-slim
Name:      docker.io/library/debian:unstable-slim
MediaType: application/vnd.docker.distribution.manifest.list.v2+json
Digest:    sha256:0717daf2e3c953dedd675b28984e251c4f9dbb39df71040e67efb4e1a14b8aa8

Manifests:
  Name:      docker.io/library/debian:unstable-slim@sha256:5ee8267a79bfdbc62c974f26f66432ef86e81821e82b4483115504daa9ffedac
  MediaType: application/vnd.docker.distribution.manifest.v2+json
  Platform:  linux/amd64

  Name:      docker.io/library/debian:unstable-slim@sha256:3c8063bbd029ddb7591b985a1c6410dec1e99fa4da4b7b518474de7fa6728830
  MediaType: application/vnd.docker.distribution.manifest.v2+json
  Platform:  linux/arm/v5

  Name:      docker.io/library/debian:unstable-slim@sha256:a0bf0f3923fbedcb7fabe7484da59f5417e370107bbc8f55222f1310a3726eae
  MediaType: application/vnd.docker.distribution.manifest.v2+json
  Platform:  linux/arm/v7

  Name:      docker.io/library/debian:unstable-slim@sha256:17c0ca8090ce0b53fa545d8ea2cf275211951d303e43a3e3ae91b8dc217992a9
  MediaType: application/vnd.docker.distribution.manifest.v2+json
  Platform:  linux/arm64/v8

  Name:      docker.io/library/debian:unstable-slim@sha256:9ca4d3a39f4b879cab9852e04bb841d3fef1e9e4751916cc790dede3be85e9dd
  MediaType: application/vnd.docker.distribution.manifest.v2+json
  Platform:  linux/386

  Name:      docker.io/library/debian:unstable-slim@sha256:e30973681a7fa80148c92da6121f55eff5f4c92509a79c869f4e8bd91c19fda7
  MediaType: application/vnd.docker.distribution.manifest.v2+json
  Platform:  linux/mips64le

  Name:      docker.io/library/debian:unstable-slim@sha256:0c8af0927d01684204a790aaf423438f60dd9c90d8dbeececb883a35dd9cd315
  MediaType: application/vnd.docker.distribution.manifest.v2+json
  Platform:  linux/ppc64le

  Name:      docker.io/library/debian:unstable-slim@sha256:6e4c03f66c878ad4f282e44f0dd3480d2b3e8a8979cec635c798f4d50b244a57
  MediaType: application/vnd.docker.distribution.manifest.v2+json
  Platform:  linux/riscv64

  Name:      docker.io/library/debian:unstable-slim@sha256:ea553a31be91cc64fea255d407eb70a94a9db1d5a2b7dcbd87661d4ac022ee2e
  MediaType: application/vnd.docker.distribution.manifest.v2+json
  Platform:  linux/s390x

Проверка образа

На моей системе, работающей на 64-битном процессоре Intel, это выдает сообщение amd64.

Если бы вы запустили это на Apple Silicon, то получили бы ответ arm64.

docker image inspect nickjj/webserver:v0.3.4 | grep Architecture
        "Architecture": "amd64",

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

Отправка образов на Docker Hub

Я предполагаю, что у вас уже есть учетная запись Docker Hub, и вы вошли в нее в командной строке через docker login.

Если вы не используете Docker Hub, вы можете использовать любой реджестри Docker, который у вас есть.

Мы можем запустить команду buildx build, как и раньше, но добавить –push:

docker buildx build --platform linux/amd64,linux/arm64 --push -t hello/testing123:v1 .

Помните, что я поместил сюда hello/testing123, и ожидается, что вы замените hello на свой аккаунт Docker Hub, testing123 на имя образа и v1 на нужный тег.

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

см. также:

You may also like

Leave a Comment