Образ Docker, созданный в Mac OSX, не будет работать на экземпляре AWS EC2

Образ, созданный на Mac OSX с процессором M1, развернут в экземпляре EC2. Но когда скрипты запускаются, выдает ошибку:

standard_init_linux.go:219: exec user process caused: exec format error

В другом месте на Stackoverflow это объясняется несоответствием архитектуры ОС. Конечно, запуск uname -m в экземпляре EC2 показывает, что это x86_64, а docker image inspect показывает, что контейнер имеет архитектуру arm64.

Вот чего я не понимаю. uname -m на моем Mac показывает, что это тоже x86_64. Так как же контейнер наследует другую архитектуру?

Что еще более важно, как мне создать образ на моем Mac, который я могу запустить на EC2?

Файл Docker - это просто

FROM python
WORKDIR /
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY src /src

с src, содержащим в настоящее время несколько простых скриптов Python, выполняемых таким образом:

docker run container/name python test.py

Это отлично работает на моем Mac, но при выполнении на AWS дает указанную выше ошибку.


person petercoles    schedule 28.01.2021    source источник


Ответы (3)


OK. Вот что происходит. На моем Mac установлен новый чип M1, и я использую Предварительная техническая версия Docker Desktop. Под капотом чип имеет архитектуру arm64, но, опрашивая его через iTerm и VSCode, вместо этого он утверждает, что это x86_64, отсюда и мое замешательство, когда я разместил вопрос. Вероятно, это связано с тем, что оба этих приложения незаметно запускаются симулятором Intel за кулисами, и это то, что отвечает на команду uname.

Однако, поскольку процессор на самом деле arm64, это базовая архитектура, когда я извлекаю образы Python из Docker (я пробовал множество разных вариантов и версий Python - все с одинаковыми результатами).

Чтобы принудительно использовать amd64 AWS-совместимый образ, я изменил первую строку Dockerfile на:

FROM --platform=linux/x86-64 python.

Когда контейнеры из этого образа запускаются на Mac, возникает предупреждение

WARNING: The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm64/v8) and no specific platform was requested

но это просто предупреждение, и сценарий запускается (предположительно, путем перенаправления обратно через симулятор Intel. Теперь сценарии запускаются без проблем (или предупреждений) на экземпляре EC2.

person petercoles    schedule 29.01.2021
comment
Я должен иметь это в виду - это обязательно будет появляться все больше и больше в будущем, хороший ответ! - person Maurice; 29.01.2021
comment
Вы также можете использовать buildx для принудительного создания образов для разных платформ. docker.com/blog / multi-platform-docker-builds - person Software Engineer; 29.01.2021

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

  1. Поместите свой код в github.
  2. Настройте репозиторий на hub.docker.com для своего образа и настройте автоматические сборки из github
  3. ssh на свой экземпляр ec2 и вытащите образ прямо из концентратора докеров

Альтернативный вариант - начать с шага 1, затем войти в свой ec2 с помощью ssh и клонировать репо на этой машине. Затем вы можете построить его непосредственно на реальной машине Linux (ваша машина osx не работает под Linux, что мгновенно несовместимо с докером). Если вы построите его на сервере, вы сможете без проблем запустить его там.

person Software Engineer    schedule 28.01.2021
comment
Это тестирование пути с целью переноса клиентской работы в Docker, поэтому общедоступные образы на самом деле не вариант. Некоторые изображения будут помещены в контейнеры и отправлены на парк серверов, поэтому создание образа на каждом сервере также не работает в этом случае. Тем не менее, знать об автоматических сборках из github интересно и может быть где-нибудь еще. Большое спасибо за то, что обратил на это мое внимание. - person petercoles; 29.01.2021
comment
Кстати, вы также можете использовать частные репозитории - вам не нужно оставлять их открытыми для публики. Это стандартный шаблон, которому вы захотите следовать, если вы используете более одного сервера. Это, безусловно, самый простой из возможных вариантов. Вы даже можете запустить более ограниченный реестр, такой как собственный ECR Amazon. В конечном счете, если вы делаете это для парка серверов, вам также следует использовать кубернеты - это сложно, но это самый простой способ заставить все это работать вместе и поддерживать кластер серверов. - person Software Engineer; 29.01.2021

Попробуйте запустить CMD ["lscpu"] или что-то подобное, например cat /proc/cpuinfo в контейнере, сравните архитектуры

Еще одна вещь: вы можете использовать arm архитектуру образа Python при сборке и попытаться запустить его на x86_64 (EC2).

person Telinov Dmitri    schedule 29.01.2021
comment
docker image inspect | grep Architecture также предоставляет эту информацию без необходимости вставлять код в изображение. Однако вы правы, речь шла о том, чтобы вытащить изображения с неправильной архитектурой, и ваш ответ вдохновил меня копнуть глубже и разобраться в этом. - person petercoles; 29.01.2021