моя контактная информация
Почтамезофия@protonmail.com
2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
buildx — это инструмент сборки, официально предоставляемый Docker. Он может помочь пользователям быстро и эффективно создавать образы Docker и поддерживает создание нескольких платформ. Используя buildx, пользователи могут создавать образы для нескольких архитектур, таких как архитектуры x86 и Arm, с помощью одной команды без необходимости вручную выполнять несколько команд сборки. Кроме того, buildx также поддерживает многоэтапное создание и кэширование Dockerfile, что может значительно повысить эффективность и скорость создания образа.
buildx — это плагин CLI, который управляет сборками Docker. Базовый уровень использует BuildKit для расширения возможностей сборки Docker.
BuildKit — это высокопроизводительный механизм сборки, официально предоставляемый Docker, который можно использовать для замены исходного механизма сборки Docker. По сравнению с исходным движком, BuildKit имеет более высокую скорость сборки, более высокий параллелизм, меньшее использование ресурсов и лучшую безопасность.
Чтобы установить и использовать buildx, номер версии Docker Engine должен быть больше или равен 19.03.
Конструктор поддерживает различные стратегии создания кроссплатформенных образов.
Если вы используете Docker Desktop, QEMU уже поддерживается и представляет собой простейшую стратегию создания кроссплатформенных образов. Он не требует каких-либо изменений в исходном файле Dockerfile и реализует кроссплатформенное выполнение программ с помощью функции ядра Linux binfmt_misc.
Принцип работы:
QEMU — это симулятор процессора, который может моделировать различные архитектуры процессора. Мы можем понимать его как еще одну форму виртуальной машины. В buildx QEMU используется для выполнения двоичных файлов для неродных архитектур в процессе сборки. Например, при создании образа ARM на хосте x86 QEMU может моделировать среду ARM и запускать двоичные файлы ARM.
binfmt_misc — это модуль ядра Linux, который позволяет пользователям регистрировать форматы исполняемых файлов и соответствующие интерпретаторы.Когда ядро обнаруживает исполняемый файл неизвестного формата, binfmt_misc используется для поиска интерпретатора, связанного с форматом файла (в данном случае QEMU), и запуска файла. . На платформе rk3568 эта функция отключена.
Комбинация QEMU и binfmt_misc делает возможной кроссплатформенную сборку с помощью buildx. Это позволяет нам создавать образы Docker для одной архитектуры на хосте для других архитектур без необходимости владения реальным целевым оборудованием.
Хотя Docker Desktop предварительно настроен с поддержкой binfmt_misc для других платформ, для других версий Docker вам может потребоваться использовать образ tonistiigi/binfmt для запуска привилегированного контейнера для поддержки.
docker run --privileged --rm tonistiigi/binfmt --install all
Выполнение этой команды установит программы-интерпретаторы разных архитектур, то есть симулятор qemu в каталог /usr/bin:
Модуль binfmt_misc загружается на наш сервер компиляции:
Docker Buildx — это экспериментальная функция Docker, которая расширяет возможности сборки Docker, включая использование нескольких узлов, qemu и т. д. QEMU — это программное обеспечение виртуальной машины с открытым исходным кодом, которое может моделировать различные процессоры и другое оборудование, что позволяет нам создавать образ другой операционной системы в одной операционной системе.
Использование функции qemu в Docker Buildx может помочь нам создавать образы Docker для различных архитектур (таких как ARM, MIPS и т. д.).
Ниже приведен простой пример, показывающий, как использовать Docker Buildx и QEMU для создания образа Docker для архитектуры ARM:
- # 创建一个新的 buildkit 实例
- docker buildx create --name mybuilder --use
-
- # 启动 buildkit 实例
- docker buildx start mybuilder
-
- # 启用 QEMU 驱动支持
- docker buildx inspect --bootstrap
-
- # 构建一个面向 ARM 架构的 Docker 镜像
- docker buildx build --platform linux/arm/v7 -t myimage:latest .
В этом примере--platform
Параметр указывает, что целевой платформой, для которой мы хотим создать, является ARM v7. Таким образом, Docker будет использовать QEMU для моделирования среды ARM и создания образа Docker для архитектуры ARM на машине с архитектурой x86.
binfmt-misc — это функция, предоставляемая ядром Linux, аналогичная ассоциации файлов в Windows, но более мощная, чем ассоциация файлов, заключается в том, что она может не только судить по имени суффикса файла, но также может быть открыта с помощью различных программ на основе файла. содержимое (магические байты). Типичный сценарий использования — использование qemu для запуска двоичных файлов на других архитектурных платформах.
Включить binfmt-misc
Чтобы временно включить его, используйте следующую команду:
$ sudo mount binfmt_misc -t binfmt_misc /proc/sys/fs/binfmt_misc
Этот метод станет недействительным после перезапуска. Если вы хотите, чтобы он действовал в течение длительного времени, вы можете добавить строку в файл /etc/fstab:
none /proc/sys/fs/binfmt_misc binfmt_misc defaults 0 0
Вы можете использовать следующую команду, чтобы проверить успешность открытия:
- $ mount | grep binfmt_misc
- binfmt_misc on /proc/sys/fs/binfmt_misc type binfmt_misc (rw,relatime)
- $ ls -l /proc/sys/fs/binfmt_misc
- 总用量 0
- --w------- 1 root root 0 2月 5 22:55 register
- -rw-r--r-- 1 root root 0 2月 5 22:55 status
Сначала подготовьте программу с архитектурой Arm64. После ее выполнения выдается сообщение об ошибке:
bash: ./go-test:无法执行二进制文件: 可执行文件格式错误
Теперь давайте выполним команду apt install qemu-user-binfmt, а затем запустим указанную выше программу Arm64 и обнаружим, что она может работать нормально. После установки qemu-user-binfmt в каталоге /proc/sys/fs/binfmt_misc будет создано несколько файлов, в том числе один qemu-aarch64. Давайте посмотрим на содержимое этого файла:
- root@ubuntu:/proc/sys/fs/binfmt_misc# cat qemu-aarch64
- enabled
- interpreter /usr/bin/qemu-aarch64-static
- flags: OC
- offset 0
- magic 7f454c460201010000000000000000000200b700
- mask ffffffffffffff00fffffffffffffffffeffffff
- root@ubuntu:/proc/sys/fs/binfmt_misc#
Этот файл описывает файл правил:
Первая строка включена означает, что правило включено;
Интерпретатор второй строки /usr/bin/qemu-aarch64-static указывает на использование /usr/bin/qemu-aarch64-static для выполнения двоичного файла;
Третья строка: OC представляет текущий флаг, конкретное значение следующее:
P: означает save-argv, что означает, что при вызове симулятора исходные параметры (argv) будут сохранены.Это полезно в ситуациях, когда тихие программы должны знать свое имя (т. е. argv[0]) во время выполнения.
O: представляет собой смещение, что означает, что перед запуском симулятора необходимо прочитать смещение из двоичного файла, и это смещение будет использоваться как параметр симулятора.
C: означает учетные данные, что означает, что эмулятор будет работать с тем же идентификатором пользователя и идентификатором группы, которые использовались исходной программой, что помогает гарантировать, что эмулятор работает с теми же разрешениями, что и исходная программа.
Четвертая строка: смещение 0 означает начало чтения файла со значения 0;
Пятая строка: Magic 7f454c460201010000000000000000000200b700 представляет байт по модулю, который необходимо сопоставить;
Магическое поле в заголовке файла ELF архитектуры Arm64 выглядит следующим образом. Это означает, что файловая система binfmt_misc может определить, какой симулятор архитектуры использовать для запуска файла, на основе магического поля в файле ELF:
Ниже представлены две разные архитектуры
Mips архитектура: 7f454c4601020100000000000000000000020008
Архитектура Arm64: 7f454c460201010000000000000000000200b700
Строка 6: маска ffffffffffffff00ffffffffffffffffffffffff представляет собой байтовую маску, которую можно использовать для игнорирования некоторых неважных байтов в файле.
Теперь мы используемдокерКоманда запускает образ Arm64:
- $ docker run -it arm64v8/ubuntu bash
- Unable to find image 'arm64v8/ubuntu:latest' locally
- latest: Pulling from arm64v8/ubuntu
- 005e2837585d: Pull complete
- Digest: sha256:ba545858745d6307f0d1064d0d25365466f78d02f866cf4efb9e1326a4c196ca
- Status: Downloaded newer image for arm64v8/ubuntu:latest
- standard_init_linux.go:207: exec user process caused "no such file or directory"
После некоторых исследований я обнаружил, что пока я выполняю следующую команду:apt install qemu-user-static
, затем запустите докерконтейнерЭто нормально.
Сложность кросс-компиляции кроется не в Docker, а в самой программе. Например, программы Go можно легко кросс-компилировать. Вам нужно всего лишь выполнить две переменные среды GOOS и GOARCH при сборке программы с помощью go build.
Чтобы использовать buildx для создания кроссплатформенного образа, нам нужно сначала создать построитель, который можно перевести как построитель.
Используйте команду docker buildx ls для просмотра списка сборщиков:
- root@ubuntu:/proc# docker buildx ls
- NAME/NODE DRIVER/ENDPOINT STATUS PLATFORMS
- mybuild * docker-container
- mybuild0 unix:///var/run/docker.sock running linux/arm64*, linux/amd64, linux/amd64/v2, linux/amd64/v3, linux/amd64/v4, linux/386
- vigilant_hugle docker-container
- vigilant_hugle0 unix:///var/run/docker.sock stopped
- default docker
- default default running linux/amd64, linux/386
Знак * указывает на используемый в данный момент сборщик. Когда мы запускаем команду сборки docker, мы используем этот сборщик для сборки образа. DRIVER/ENDPOINT во втором столбце указывает используемый драйвер. buildx поддерживает следующие драйверы:
Поскольку сборщик по умолчанию, использующий драйвер docker, не поддерживает создание кроссплатформенных образов с помощью одной команды (параметр --platform сборщика по умолчанию принимает только одно значение), нам необходимо создать новый сборщик с помощью драйвера docker-container. .
Синтаксис команды следующий:
$ docker buildx create --name=<builder-name> --driver=<driver> --driver-opt=<driver-options>
Значение параметров следующее:
--name: Обязательное созданное имя.
--driver: драйвер Builder, по умолчанию — docker-container.
--driver-opt: параметры драйвера. Например, параметр --driver-opt=image=moby/buildkit:v0.11.3 позволяет установить указанную версию BuildKit. Значение по умолчанию — moby/buildkit.
Мы можем создать новый построитель, используя следующую команду:
- $ docker buildx create --name mybuilder
- mybuilder
Проверьте список застройщиков еще раз:
- $ docker buildx ls
- NAME/NODE DRIVER/ENDPOINT STATUS BUILDKIT PLATFORMS
- mybuilder * docker-container
- mybuilder0 unix:///var/run/docker.sock inactive
- default docker
- default default running 20.10.21 linux/arm64, linux/amd64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/arm/v7, linux/arm/v6
- desktop-linux docker
- desktop-linux desktop-linux running 20.10.21 linux/arm64, linux/amd64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/arm/v7, linux/arm/v6
Вы можете обнаружить, что выбранная сборка была переключена на Mybuilder. Если она не выбрана, вам нужно вручную использовать команду docker buildx use mybuilder для переключения сборщика.
Наш недавно созданный mybuilder в настоящее время неактивен, и его необходимо запустить, прежде чем его можно будет использовать.
- $ docker buildx inspect --bootstrap mybuilder
- [+] Building 16.8s (1/1) FINISHED
- => [internal] booting buildkit 16.8s
- => => pulling image moby/buildkit:buildx-stable-1 16.1s
- => => creating container buildx_buildkit_mybuilder0 0.7s
- Name: mybuilder
- Driver: docker-container
-
- Nodes:
- Name: mybuilder0
- Endpoint: unix:///var/run/docker.sock
- Status: running
- Buildkit: v0.9.3
- Platforms: linux/arm64, linux/amd64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/mips64le, linux/mips64, linux/arm/v7, linux/arm/v6
Подкоманда проверки используется для проверки статуса сборки. Используйте параметр --bootstrap, чтобы запустить сборщик mybuilder. Еще раз проверьте список сборщиков. Статус mybuilder изменился на «работает».
- $ docker buildx ls
- NAME/NODE DRIVER/ENDPOINT STATUS BUILDKIT PLATFORMS
- mybuilder * docker-container
- mybuilder0 unix:///var/run/docker.sock running v0.9.3 linux/arm64, linux/amd64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/mips64le, linux/mips64, linux/arm/v7, linux/arm/v6
- default docker
- default default running 20.10.21 linux/arm64, linux/amd64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/arm/v7, linux/arm/v6
- desktop-linux docker
- desktop-linux desktop-linux running 20.10.21 linux/arm64, linux/amd64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/arm/v7, linux/arm/v6
Значение, отображаемое в столбце ПЛАТФОРМЫ.
linux/arm64, linux/amd64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/mips64le, linux/mips64, linux/arm/v7, linux/arm/v6 поддерживаются текущей сборкой. Все платформы.
Теперь используйте команду docker ps, чтобы убедиться, что контейнер BuildKit, соответствующий сборщику mybuilder, запущен.
- $ docker ps
- CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
- b8887f253d41 moby/buildkit:buildx-stable-1 "buildkitd" 4 minutes ago Up 4 minutes buildx_buildkit_mybuilder0
Этот контейнер используется для помощи нам в создании кроссплатформенных образов. Не удаляйте его вручную.
$ docker buildx build --platform linux/arm64,linux/amd64 -t jianghushinian/hello-go .
Синтаксис сборки docker buildx такой же, как и у сборки docker. Параметр --platform указывает целевую платформу для сборки образа, -t указывает тег образа. . указывает, что контекстом является текущий каталог.。
Единственное, что не работает, — это поддержка параметра --platform. Параметр --platform сборки docker поддерживает передачу только одной информации о платформе, например --platform linux/arm64, что означает, что один образ платформы может быть передан. быть построены за один раз.
Использование сборки docker buildx для создания образа поддерживает одновременную передачу информации о нескольких платформах, разделенной английскими запятыми, что позволяет реализовать функцию создания нескольких кроссплатформенных образов с помощью всего лишь одной команды.
После выполнения вышеуказанной команды мы получим предупреждение:
WARNING: No output specified with docker-container driver. Build result will only remain in the build cache. To push result image into registry use --push or to load image into docker use --load
Это предупреждение напоминает нам, что мы не указали выходные данные для драйвера docker-container. Сгенерированные результаты будут храниться только в кеше сборки. Используйте --push, чтобы отправить образ в удаленный репозиторий Docker Hub, и используйте --load. чтобы сохранить изображение локально.
Это связано с тем, что наш вновь созданный mybuilder запускает контейнер для запуска BuildKit. Он не может напрямую вывести созданный кроссплатформенный образ на локальный компьютер или отправить его на удаленный компьютер. Пользователь должен вручную указать место вывода.
Мы можем попробовать указать --load, чтобы сохранить изображение на локальном хосте.
- $ docker buildx build --platform linux/arm64,linux/amd64 -t jianghushinian/hello-go . --load
- [+] Building 0.0s (0/0)
- ERROR: docker exporter does not currently support exporting manifest lists
Результатом будет журнал ошибок. Кажется, что он не поддерживает экспорт кроссплатформенных изображений в локальную систему. На самом деле это связано с тем, что передается несколько --platform. Если --platform передает только одну платформу, вы можете использовать --load для вывода построенного изображения. машина.
Тогда мы сможем отправить кроссплатформенный образ на удаленный склад только через параметр --push. Однако прежде чем делать это, вам необходимо обязательно использовать логин Docker для завершения входа в систему.
$ docker buildx build --platform linux/arm64,linux/amd64 -t jianghushinian/hello-go . --push
Теперь войдите в Docker Hub, и вы увидите отправленный кроссплатформенный образ.
Мы также можем использовать imagestools для проверки информации манифеста кросс-платформенного образа. Эту команду можно использовать только для получения информации об изображении в хранилище, а локальные изображения просмотреть невозможно.
- $ docker buildx imagetools inspect jianghushinian/hello-go
- Name: docker.io/jianghushinian/hello-go:latest
- MediaType: application/vnd.docker.distribution.manifest.list.v2+json
- Digest: sha256:51199dadfc55b23d6ab5cfd2d67e38edd513a707273b1b8b554985ff562104db
-
- Manifests:
- Name: docker.io/jianghushinian/hello-go:latest@sha256:8032a6f23f3bd3050852e77b6e4a4d0a705dfd710fb63bc4c3dc9d5e01c8e9a6
- MediaType: application/vnd.docker.distribution.manifest.v2+json
- Platform: linux/arm64
-
- Name: docker.io/jianghushinian/hello-go:latest@sha256:fd46fd7e93c7deef5ad8496c2cf08c266bac42ac77f1e444e83d4f79d58441ba
- MediaType: application/vnd.docker.distribution.manifest.v2+json
- Platform: linux/amd64
Как видите, этот кроссплатформенный образ содержит образы двух целевых платформ, а именно linux/arm64 и linux/amd64.