Estoy tratando de construir una imagen multiplataforma (amd64, arm64 y armv7) usando docker buildx. Como estoy usando una máquina amd64 con Ubuntu 18.04, seguí las instrucciones en el sitio web de Docker e instalé qemu a través de:
sudo apt install qemu-user
Sin embargo, aparece un error extraño cuando ejecuto el comando anterior. Más específicamente, parece haber un problema con el servicio de soporte de binfmt . Aquí está el registro completo:
Reading package lists... Done Building dependency tree Reading state information... Done Starting pkgProblemResolver with broken count: 0 Starting 2 pkgProblemResolver with broken count: 0 Done The following additional packages will be installed: binfmt-support qemu-user-binfmt The following NEW packages will be installed: binfmt-support qemu-user qemu-user-binfmt 0 upgraded, 3 newly installed, 0 to remove and 1 not upgraded. Need to get 0 B/7.409 kB of archives. After this operation, 63,4 MB of additional disk space will be used. Do you want to continue? [Y/n] Selecting previously unselected package binfmt-support. (Reading database ... 245278 files and directories currently installed.) Preparing to unpack .../binfmt-support_2.1.8-2_amd64.deb ... Unpacking binfmt-support (2.1.8-2) ... Selecting previously unselected package qemu-user. Preparing to unpack .../qemu-user_1%3a2.11+dfsg-1ubuntu7.21_amd64.deb ... Unpacking qemu-user (1:2.11+dfsg-1ubuntu7.21) ... Selecting previously unselected package qemu-user-binfmt. Preparing to unpack .../qemu-user-binfmt_1%3a2.11+dfsg-1ubuntu7.21_amd64.deb ... Unpacking qemu-user-binfmt (1:2.11+dfsg-1ubuntu7.21) ... Setting up binfmt-support (2.1.8-2) ... Job for binfmt-support.service failed because the control process exited with error code. See "systemctl status binfmt-support.service" and "journalctl -xe" for details. invoke-rc.d: initscript binfmt-support, action "start" failed. ● binfmt-support.service - Enable support for additional executable binary formats Loaded: loaded (/lib/systemd/system/binfmt-support.service; enabled; vendor preset: enabled) Active: failed (Result: exit-code) since Wed 2020-02-05 17:20:29 CET; 4ms ago Docs: man:update-binfmts(8) Process: 7766 ExecStart=/usr/sbin/update-binfmts --enable (code=exited, status=2) Main PID: 7766 (code=exited, status=2) feb 05 17:20:29 XPS-15-9570 systemd[1]: Starting Enable support for additional executable binary formats... feb 05 17:20:29 XPS-15-9570 update-binfmts[7766]: update-binfmts: warning: unable to close /proc/sys/fs/binfmt_misc/register: No such file or directory feb 05 17:20:29 XPS-15-9570 update-binfmts[7766]: update-binfmts: exiting due to previous errors feb 05 17:20:29 XPS-15-9570 systemd[1]: binfmt-support.service: Main process exited, code=exited, status=2/INVALIDARGUMENT feb 05 17:20:29 XPS-15-9570 systemd[1]: binfmt-support.service: Failed with result 'exit-code'. feb 05 17:20:29 XPS-15-9570 systemd[1]: Failed to start Enable support for additional executable binary formats. Setting up qemu-user (1:2.11+dfsg-1ubuntu7.21) ... Setting up qemu-user-binfmt (1:2.11+dfsg-1ubuntu7.21) ... update-binfmts: warning: current package is qemu-user-binfmt, but binary format already installed by qemu-user-static update-binfmts: exiting due to previous errors dpkg: error processing package qemu-user-binfmt (--configure): installed qemu-user-binfmt package post-installation script subprocess returned error exit status 2 Processing triggers for man-db (2.8.3-2ubuntu0.1) ... Processing triggers for ureadahead (0.100.0-21) ... Processing triggers for neon-settings (0.0+p18.04+git20191212.1343) ... Processing triggers for systemd (237-3ubuntu10.33) ... Errors were encountered while processing: qemu-user-binfmt E: Sub-process /usr/bin/dpkg returned an error code (1)A pesar de eso, traté de continuar con el procedimiento habitual, a saber:
docker buildx create --name mybuilder docker buildx use mybuilder docker buildx inspect --bootstrapDonde la salida del último comando es:
[+] Building 5.0s (1/1) FINISHED => [internal] booting buildkit 5.0s => => pulling image moby/buildkit:buildx-stable-1 4.3s => => creating container buildx_buildkit_mybuilder0 0.7s Name: mybuilder Driver: docker-container Nodes: Name: mybuilder0 Endpoint: unix:///var/run/docker.sock Status: running Platforms: linux/amd64, linux/386Como puede ver, "linux/amd64" y "linux/386" se enumeran como las únicas plataformas disponibles; sin embargo, también necesitaría crear la imagen para las plataformas "linux/arm64" y "linux/arm/v7". He estado buscando una solución a este problema durante horas, aunque no encontré nada que funcionara.
Parece que pude resolver parte del problema ejecutando:
sudo apt purge --auto-remove qemu-user qemu-user-binfmt binfmt-supportY luego volver a instalarlos. De hecho, ejecutando de nuevo este comando:
sudo apt install qemu-userno da ningún error en absoluto:
Reading package lists... Done Building dependency tree Reading state information... Done Starting pkgProblemResolver with broken count: 0 Starting 2 pkgProblemResolver with broken count: 0 Done The following additional packages will be installed: binfmt-support qemu-user-binfmt The following NEW packages will be installed: binfmt-support qemu-user qemu-user-binfmt 0 upgraded, 3 newly installed, 0 to remove and 0 not upgraded. Need to get 0 B/7.409 kB of archives. After this operation, 63,4 MB of additional disk space will be used. Do you want to continue? [Y/n] Selecting previously unselected package binfmt-support. (Reading database ... 245437 files and directories currently installed.) Preparing to unpack .../binfmt-support_2.1.8-2_amd64.deb ... Unpacking binfmt-support (2.1.8-2) ... Selecting previously unselected package qemu-user. Preparing to unpack .../qemu-user_1%3a2.11+dfsg-1ubuntu7.21_amd64.deb ... Unpacking qemu-user (1:2.11+dfsg-1ubuntu7.21) ... Selecting previously unselected package qemu-user-binfmt. Preparing to unpack .../qemu-user-binfmt_1%3a2.11+dfsg-1ubuntu7.21_amd64.deb ... Unpacking qemu-user-binfmt (1:2.11+dfsg-1ubuntu7.21) ... Setting up binfmt-support (2.1.8-2) ... Created symlink /etc/systemd/system/multi-user.target.wants/binfmt-support.service → /lib/systemd/system/binfmt-support.service. Setting up qemu-user (1:2.11+dfsg-1ubuntu7.21) ... Setting up qemu-user-binfmt (1:2.11+dfsg-1ubuntu7.21) ... Processing triggers for man-db (2.8.3-2ubuntu0.1) ... Processing triggers for ureadahead (0.100.0-21) ... Processing triggers for neon-settings (0.0+p18.04+git20191212.1343) ... Processing triggers for systemd (237-3ubuntu10.38) ... De manera similar, la salida de systemctl status binfmt-support.service es la esperada:
● binfmt-support.service - Enable support for additional executable binary formats Loaded: loaded (/lib/systemd/system/binfmt-support.service; enabled; vendor preset: enabled) Active: active (exited) since Mon 2020-02-10 11:42:23 CET; 1min 11s ago Docs: man:update-binfmts(8) Main PID: 7161 (code=exited, status=0/SUCCESS) Tasks: 0 (limit: 4915) CGroup: /system.slice/binfmt-support.service feb 10 11:42:23 XPS-15-9570 systemd[1]: Starting Enable support for additional executable binary formats... feb 10 11:42:23 XPS-15-9570 systemd[1]: Started Enable support for additional executable binary formats.Sin embargo, parte del problema sigue ahí, como resultado después de ejecutar estos tres comandos:
docker buildx create --name mybuilder docker buildx use mybuilder docker buildx inspect --bootstrapes lo mismo que antes, a saber:
[+] Building 2.6s (1/1) FINISHED => [internal] booting buildkit 2.6s => => pulling image moby/buildkit:buildx-stable-1 2.0s => => creating container buildx_buildkit_mybuilder0 0.6s Name: mybuilder Driver: docker-container Nodes: Name: mybuilder0 Endpoint: unix:///var/run/docker.sock Status: running Platforms: linux/amd64, linux/386 ¿Porqué es eso? ¿Por qué me muestra linux/amd64 y linux/386 como las únicas plataformas disponibles?
La salida del docker context ls es:
NAME DESCRIPTION DOCKER ENDPOINT KUBERNETES ENDPOINT ORCHESTRATOR default * Current DOCKER_HOST based configuration unix:///var/run/docker.sock swarmTambién intenté reiniciar la ventana acoplable después de la instalación de qemu, pero no tuve éxito. Además, especificando las plataformas de destino en el comando docker buildx:
docker buildx build -t <mytag> --platform linux/amd64,linux/arm64,linux/arm/v7 --load .da como resultado este error:
[+] Building 0.6s (5/20) => [internal] load .dockerignore 0.0s => => transferring context: 2B 0.0s => [internal] load build definition from Dockerfile 0.0s => => transferring dockerfile: 32B 0.0s => [linux/arm/v7 internal] load metadata for docker.io/alegeno92/opencv_python3:3.4.2 0.6s => CANCELED [linux/arm64 internal] load metadata for docker.io/alegeno92/opencv_python3:3.4.2 0.6s => CANCELED [linux/amd64 internal] load metadata for docker.io/alegeno92/opencv_python3:3.4.2 0.6s failed to solve: rpc error: code = Unknown desc = failed to solve with frontend dockerfile.v0: failed to load LLB: runtime execution on platform linux/arm/v7 not supported Por cierto, mi versión del kernel es 4.15.0-76-generic
Ejecute primero el contenedor multiarch
docker run --rm --privileged multiarch/qemu-user-static --reset -p yes docker buildx rm builder docker buildx create --name builder --driver docker-container --use docker buildx inspect --bootstrapY deberías tener tus arquitecturas alternativas.
Etiquetado en esta respuesta en respuesta al primer error. Los comandos se actualizaron según https://docs.docker.com/buildx/working-with-buildx/ .
QEMU es un emulador multiplataforma responsable de obtener los archivos binarios para diferentes arquitecturas (a través del controlador binfmt_misc).
Algunas personas ahorrarán algo de tiempo para comenzar con este comando primero:
docker run --privileged --rm tonistiigi/binfmt --install allPara github CI, agregue el siguiente complemento para resolver esto por mí
- name: Set up QEMU id: qemu uses: docker/setup-qemu-action@v1 with: image: tonistiigi/binfmt:latest platforms: allHay varios paquetes binfmt y hay una configuración que creo que se pasó por alto cuando se hizo esta pregunta.
Para los diversos paquetes, optaría por qemu-user-static en qemu-user-binfmt para evitar problemas de vinculación dinámica. Los dos paquetes están haciendo lo mismo, por lo que deberá elegir uno u otro.
La siguiente parte debería arreglarse en las versiones actuales, pero creo que te estabas tropezando con esto antes. Esa es la marca fix binary o F que verá al seleccionar los archivos en /proc/sys/fs/binfmt_misc , por ejemplo, vea la marca F aquí:
$ cat /proc/sys/fs/binfmt_misc/qemu-arm enabled interpreter /usr/libexec/qemu-binfmt/arm-binfmt-P flags: POCF offset 0 magic 7f454c4601010100000000000000000002002800 mask ffffffffffffff00fffffffffffffffffeffffff Los detalles sobre lo que significa el indicador F se pueden encontrar en esta publicación de kernel.org, pero en resumen, los espacios de nombres de contenedores incluyen un espacio de nombres de sistema de archivos diferente, y el intento de acceder al intérprete desde ese espacio de nombres fallará (a menos que haga algo como bind mount /usr/libexec/qemu-binfmt en su contenedor). Las versiones más nuevas de los paquetes qemu configuran automáticamente este indicador, por lo que si su sección de indicadores no tiene la F definida, consulte estos informes de errores para la versión a la que deberá actualizar:
El botón fácil es usar los binarios de la imagen multiarch . Esto es bueno en CI si tiene una VM dedicada (menos ideal si está modificando el host utilizado por otras compilaciones). Sin embargo, si reinicia, se rompe hasta que vuelve a ejecutar el contenedor. Y requiere que recuerde actualizarlo para cualquier parche ascendente. Por lo tanto, no lo recomendaría para un host de compilación de larga duración.
docker run --rm --privileged multiarch/qemu-user-static --reset -p yes