Сбой сборки Docker для образов ARM

Я пытаюсь создать образ докера для нескольких архитектур на Travis-CI. Это хорошо работает для amd64 и i386, но не для ARM.

Dockerfile построить поверх {ARCH}/nextcloud:apache который построен на вершине php:7.3-apache-stretch который снова использует debian:stretch-slim, Таким образом, все изображения используют один и тот же стек и должны реагировать одинаково.

.travis.yml

env:
  - TAG=i386     ARCH=i386
  - TAG=amd64    ARCH=amd64
  - TAG=armhf    ARCH=arm32v7
  - TAG=aarch64  ARCH=arm64v8

before_script:
  - docker run --rm --privileged multiarch/qemu-user-static:register --reset

script:
  - docker build --pull --build-arg ARCH=$ARCH -t escoand/nextcloud:$TAG nextcloud

Dockerfile

ARG ARCH

FROM ${ARCH}/nextcloud:apache

RUN apt-get update && apt-get install -y supervisor && \
    rm -rf /var/lib/apt/lists/* && \
    mkdir /var/log/supervisord /var/run/supervisord

Как уже упоминалось, сборка для i386 и amd64 работает без проблем. Сборки ARM терпят неудачу уже с первой командой RUN:

standard_init_linux.go:185: exec user process caused "no such file or directory"
The command '/bin/sh -c apt-get update && apt-get install -y supervisor &&     rm -rf /var/lib/apt/lists/* &&     mkdir /var/log/supervisord /var/run/supervisord' returned a non-zero code: 1

https://travis-ci.org/escoand/dockerfiles/jobs/562967055

Для меня это звучит как /bin/sh это проблема, но не знаю, как справиться с этим.

1 ответ

Прежде всего, давайте разберемся, что именно вы пытаетесь сделать, используя следующий прием:

before_script:
  - docker run --rm --privileged multiarch/qemu-user-static:register --reset

Когда вы просите ядро ​​Linux запустить какой-нибудь исполняемый файл, ему нужно знать, как загрузить этот конкретный файл и совместим ли этот файл с текущей машиной или нет. По умолчанию двоичный файл ELF скомпилирован, скажем, для arm64v8 отклоняется ядром, работающим на amd64 аппаратное обеспечение.

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

С чего начался контейнер с картинки multiarch/qemu-user-static:register делает? Он регистрирует новые обработчики для двоичных файлов ELF, созданных для альтернативных архитектур, например:

$ cat /proc/sys/fs/binfmt_misc/qemu-aarch64
enabled
interpreter /usr/bin/qemu-aarch64-static
flags: 
offset 0
magic 7f454c460201010000000000000000000200b700
mask ffffffffffffff00fffffffffffffffffeffffff

Когда этот обработчик зарегистрирован, ядро ​​знает, что если оно сталкивается с двоичным файлом, начинающимся с магических байтов, указанных в magic поле (также с учетом mask), это должно бежать /usr/bin/qemu-aarch64-static двоичный (интерпретатор), и пусть он позаботится о загрузке и запуске запрошенного двоичного файла.

Проблема в вашем вопросе: где /usr/bin/qemu-aarch64-static переводчик, который умеет бегать aarch64 двоичные файлы на amd64? Там нет никого, так как базовое изображение, которое вы используете, не включает его (я вытащил и arm64v8/nextcloud:apache изображение вручную, чтобы подтвердить это)!

Согласно manpage для execve(2), когда ядро ​​не может загрузить интерпретатор, оно возвращает ошибку "ENOENT" (такой файл или каталог отсутствует):

ERRORS
<...>
       ENOENT The file pathname or a script or ELF interpreter does not exist,
       or a shared library needed for the file or interpreter cannot be found.

Итак, вот что происходит: вы строите образ и указываете базовый образ, созданный для машин ARM. Во-первых RUN, ядро ​​пытается выполнить /bin/sh file from the image, находит обработчик QEMU для этого типа двоичных файлов, затем ищет интерпретатор, не находит его и выдает ошибку, следовательно, возникает ошибка "нет такого файла или каталога".

Чтобы решить эту проблему, вы должны использовать базовый образ, на котором установлен QEMU (и, таким образом, /usr/bin/qemu-aarch64-static внутри), что позволит вам выполнить RUNs.

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