ECSでNginxコンテナを起動時のexec /docker-entrypoint.sh: exec format error対応
GOAL
以前、ECRからNginxのイメージを取得して、ECS環境を立ち上げました。
次のステップとして、Local環境で利用していたNginxコンテナをイメージ化して、ECS上でひとまず動かすことをGOALとしました。しかし、そこでエラーとなったため、デバッグと解決方法を探しました。
前提
NginxのイメージをBuildして、ECRにPUSHしておく必要があります。
非常に単純なNginxコンテナ環境を用意します.
Dockerファイル
FROM nginx:stable-alpine
COPY ./docker/nginx/default.conf /etc/nginx/conf.d/default.conf
default.conf
server {
listen 80;
index index.php index.html;
location / {
return 200 'Hello, this is a simple response from nginx!';
add_header Content-Type text/plain;
}
}
ECRへのPUSH方法はご確認ください。
※コマンドだけ.
aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin <acount-id>.dkr.ecr.ap-northeast-1.amazonaws.com
docker build -f <dockerfileのdirectory> -t ecs-navi-nginx .
docker tag ecs-navi-nginx:latest <acount-id>.dkr.ecr.ap-northeast-1.amazonaws.com/ecs-navi-nginx:latest
docker push <acount-id>.dkr.ecr.ap-northeast-1.amazonaws.com/ecs-navi-nginx:latest
問題
ECS環境にコンテナを起動しようとしところ、タスクが直ぐに停止してしまいます。
ログには、 exec /docker-entrypoint.sh: exec format error というエラーが出ていました。
解決へのアプローチ
"exec format error"原因を探す
exec format error は幾つか原因があるようです。
今回の場合は、ECSのfargate環境 VS コンテナ環境でCPUアーキテクチャが違ったことが原因でした。
ECSのCPUアーキテクチャを確認
タスク >> 設定からアーキテクチャを確認できます。
Linux/X86_64 になっています。
コンテナ環境のCPUアーキテクチャを確認
Local環境で確認します。
ECRへPUSHしたBuild済みのイメージをコンテナ起動して、CPUアーキテクチャを確認してみます。
### コンテナ起動
docker run -d -p 8080:80 --name local-nginx ecs-navi-nginx
### コンテナへアクセス
docker exec -it local-nginx sh
### CPUアーキテクチャを確認
/ # uname -m
aarch64
aarch64 となっています。
x86_64 と aarch64 の違い
x86_64 (AMD64):
- インテルやAMDが開発している64ビットのCPUアーキテクチャです。
- デスクトップPCやサーバーの多くで使用されています。
- x86アーキテクチャを64ビットに拡張したものなので、従来の32ビット(x86)のソフトウェアとの互換性があります。
aarch64 (ARM64):
- ARM社が設計した64ビットのCPUアーキテクチャです。
- 主にスマートフォン、タブレット、IoTデバイス、および省電力サーバー(例えばAWSのGraviton2プロセッサなど)で使用されます。
- ARMアーキテクチャは低消費電力設計が特徴です。
x86_64 と aarch64 は別々のアーキテクチャであり、バイナリの互換性がありません。つまり、x86_64 用にコンパイルされたプログラムは aarch64 上では動作せず、その逆も同様です。
解決方法
ECSのアーキテクチャ環境にコンテナ環境をあわせます。
Build時にアーキテクチャを明示的に指定する方法で合わせます。コマンドの修正内容は下記です。
--platform linux/amd64 を明示的に追記してあげます。
Before
docker build -f <dockerfileのdirectory> -t ecs-navi-nginx .
After
docker build --platform linux/amd64 -f <dockerfileのdirectory> -t ecs-navi-nginx .
終わりに
タスクが起動して、return 200 'Hello, this is a simple response from nginx!'が返却されるようになればOKです。
ECSはログ設定をしなければログが表示されないのでデバッグするためにログの設定をしてエラーを確認しましょう。
Discussion