arm64のM2 MacでDockerを使ってx86-64の実行環境を作る
諸事情により、arm64アーキテクチャのM2 mac上で、x86-64アーキテクチャ用にコンパイルされているバイナリファイルを実行したくなりました。そのときのメモです。
実行環境
- M2 Macbook Air
- Docker Desktop for Macをインストール済み
M2チップなのでarm64アーキテクチャで動作しています。
$ uname -m
arm64
失敗した方法
Docker HubからUbuntuのイメージをダウンロードして、Dockerコンテナを立ち上げ、ローカルから実行したいx86-64のバイナリと、異なるアーキテクチャをエミュレートできるQEMUバイナリをコンテナにコピーして、ファイルを実行・・・という方法でやろうとしましたが、うまく行きませんでした。
成功した方法
「マルチアーキテクチャ対応のDockerイメージを使用すれば、arm64ホストでx86_64バイナリを実行できる場合がある」(GPT先生談)ということで、Docker Hubで「linux mult arch」で検索。
すると、Alpineがヒットしました。
Supported architectures
の項目を確認すると、x86_64、arm64の両方が含まれています。これで試してみます。
Docker HubからAlpineイメージをダウンロードします。
$ docker pull alpine:latest
コンテナを起動。
$ docker run -it --rm alpine:latest /bin/sh
別タブで、コンテナIDを確認。
$ docker ps
ホストマシンから実行したいバイナリファイルをコピーします。
$ docker cp [実行したいバイナリファイル名] [コンテナID]:/tmp/
Alpineのシェルに戻り、上記のファイルがコピーできているか確認。
/ # ls
bin dev etc home lib media mnt opt proc root run sbin srv sys tmp usr var
/ # cd tmp
/tmp # ls
[実行したいバイナリファイル名]
バイナリを実行しようとするとエラーが出ました。
/tmp # ./[実行したいバイナリファイル名]
qemu-x86_64: Could not open '/lib64/ld-linux-x86-64.so.2': No such file or directory
ChatGPT先生に聞いてみよう。
このエラーは、Alpine Linuxのコンテナ内で/lib64/ld-linux-x86-64.so.2という動的リンカ(または動的ローダー)が存在しないために発生しています。このファイルは、Linuxのx86-64アーキテクチャで動的にリンクされたバイナリを実行するために通常必要です。
Alpine Linuxはmusl libcを使用しているため、glibcベースのLinuxディストリビューションとは互換性がありません。そのため、glibcベースのバイナリ(/lib64/ld-linux-x86-64.so.2が必要なもの)は、Alpine Linuxでは通常は実行できません。
Alpine Linuxにglibcをインストールすることで、一部のglibc依存のバイナリを実行できるようになる場合があります。ただし、これは公式にはサポートされていない方法です。
ふむふむ。
ChatGPT先生に教えられた通りにglibcをインストール。
/tmp # apk add --no-cache curl
/tmp # curl -L -o /etc/apk/keys/sgerrand.rsa.pub https://alpine-pkgs.sgerrand.com/sgerrand.rsa.pub
/tmp # curl -L -O https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.34-r0/glibc-2.34-r0.apk
/tmp # apk add glibc-2.34-r0.apk
apk add glibc-2.34-r0.apk
を実行した際に1つエラーが出ました(ERROR: glibc-2.34-r0: trying to overwrite etc/nsswitch.conf owned by alpine-baselayout-data-3.4.3-r1.
)が、バイナリファイルは実行できました!
/tmp # ./[実行したいバイナリファイル名]
[実行結果]
Discussion