ARM時代のWindows…WSLでARM非対応のコンテナイメージが動かないときの対応
WindowsもARM機の時代へ…?
ARMアーキテクチャによるApple Siliconを採用した M1 Mac が登場してからなんともう3年半以上経過しています。時の流れは速いものですね。
当時は発熱が少ない、バッテリーが持つ、性能も良いということで、Intel Macにはもう戻れないくらいの感動がありました。
そしてついに2024年6月になって Surfaceを筆頭に一斉にSnapdragon X Eliteを搭載したWindows機が発売されています。
ようやくWindowsでも本格的にARMプロセッサが普及するか…という兆しを見せていますね。
さて、エンジニアとしてやはり気になるのが 結局ARMのWindowsって開発機として使えるの? というところです。
最近ARMのWindows機を使って開発環境を構築したり検証したりしてきたので、その結果についてまたまとめようと思っていますが、差し当たって多くの人に欠かせないであろう「Docker」の話をできればと思います。(WSL2のUbuntu環境での話です)
DockerイメージのPlatform
様々な環境を手軽に作れるDockerですが、Dockerイメージを実行するハードウェアのアーキテクチャおよびOSの組み合わせがPlatformとして指定されています。
複数のPlatform用にビルドされたイメージを一つのmanifestにまとめたイメージもあります。これであれば、自動的に自分の環境に合ったイメージが手に入るということです。
そういった背景もあり、カジュアルに使用している場合はあまり意識することはないのかもしれません。
たとえば、 dockerhub の ubuntu のイメージ を見てみると
こんな感じで OS/ARCH
として複数のPlatformの組みあわせがあります。
この中から自動で自分の環境に合わせたものが取得されるということです。
ただ、全てのイメージがこのように複数のPlatformに対応したものを用意しているわけではありません。
例えば、ARMでない、 x86_64
( amd64
)な環境で、強引にARM系の aarch64
のためにビルドされたイメージを動かそうとすると多くの場合コケます。
というわけで、普通にしているとLinuxとARMの組みあわせの環境では linux/amd64
なイメージしかないものと遭遇するたびにコケてしまいます。。
本記事ではこのようなシチュエーションで強引に動かす方法について記述します。
対応: QEMUを使う
QEMUとは
QEMU は、オープンソースのエミュレーションソフトウェアです。
エミュレーション、つまり、擬似的に違うアーキテクチャのCPUの動きを再現できます。
逆向き(aarch64をamd64環境で動かす)は対応方法が確立されている
基本的にはARM系でなくx86_64(amd64)系の環境のほうが現時点ではMacを除いてはメジャーですので、今やりたいと思っている「 linux/aarch64
で linux/amd64
なイメージを動かす」のと逆向きの「 linux/amd64
で linux/aarch64
なイメージを動かす」の情報はめちゃくちゃあります。
一番メジャーな対応方法は multiarch/qemu-user-static を使うことです。
しかし、問題はこの逆向きの対応についてはほとんど情報がないことでした。。
結論: 設定方法
やりたいこととしては、 linux/amd64
向けに作られたイメージを x86_64用のQEMUエミュレータで動かすことですので、
特定のマジックコードに対して /proc/sys/fs/binfmt_misc
によって /usr/bin/qemu-x86_64-static
を呼び出すように設定してあげればいいということになります。
何言ってるかわからない、という人向けにとりあえずやることを記述しておきます。
qemuを入れてから…
sudo apt install qemu-user-static
下記のコードによって qemu-x86_64
という名前の上記設定を放り込みます
echo ':qemu-x86_64:M:0:\\x7fELF\\x02\\x01\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x02\\x00\\x3e\\x00:\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\x00\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xfe\\xff\\xff\\xff:/usr/bin/qemu-x86_64-static:OCF' | sudo tee /proc/sys/fs/binfmt_misc/register
一応の解説
なんやねんこれは… という感じかもしれません。一応物好きな人達のために補足すると
まず、 binfmt_misc
に指定する内容の書式は Kernel Support for miscellaneous Binary Formats (binfmt_misc) のページにあるとおり、 :name:type:offset:magic:mask:interpreter:flags
です。
ここでマジックコードとmaskとして
magic 7f454c460201010000000000000000000200b700 mask ffffffffffffff00fffffffffffffffffeffffff
を指定する、というのが先ほどの「逆向き」である multiarch/qemu-user-static でやっていることでした。(READMEにそのまま記載があります)
ミソはマジックコードの後ろのほうにある b7
で、これがターゲットアーキテクチャの識別子のうち AARCH64
を指しています。 ここを 3e
に変えれば x86_64
になりますので
magic 7f454c4602010100000000000000000002003e00 mask ffffffffffffff00fffffffffffffffffeffffff
としておけば、 x86_64
なバイナリは /usr/bin/qemu-x86_64-static
でエミュレーションすることになります。(magicの末尾が 3e00
となれば良いということです)
というわけで、このような設定になるように仕込んでいます。
永続化させたい場合
永続化させたい場合は service
を作ればよいかと思います
/etc/systemd/system/qemu-binfmt.service
とかで
[Unit] Description=Register qemu-x86_64 binary format with binfmt_misc After=network.target [Service] Type=oneshot ExecStart=/bin/sh -c 'echo ":qemu-x86_64:M:0:\\x7fELF\\x02\\x01\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x02\\x00\\x3e\\x00:\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\x00\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xfe\\xff\\xff\\xff:/usr/bin/qemu-x86_64-static:OCF" | sudo tee /proc/sys/fs/binfmt_misc/register' [Install] WantedBy=multi-user.target
のようなものをつくって
sudo systemctl enable qemu-binfmt.service sudo systemctl start qemu-binfmt.service
で永続化されるかとおもいます。
動作確認
dockerの動作確認でおなじみの hello-world
イメージを linux/amd64
指定で動かしてみます。
コマンドとしては
docker run --rm --platform linux/amd64 hello-world
ですね
動きました! aarch64
なWSLで動いているのが確認できると思います。
なお、この設定をする前は
> docker run --rm --platform linux/amd64 hello-world exec /hello: exec format error
という悲しい一行だけ出力されて終わります。
まとめ
今回はQEMUを使って強引にARM非対応なDockerイメージをARM機のWSL上で動かす方法を扱いました。
逆のパターンはいっぱい情報が出てきますが、Apple Siliconな Macでの情報以外はほとんどでてきませんので誰かの参考になっていれば幸いです。
(ちなみにApple SiliconなMacではDocker自体がこのあたり上手に対応されているので意識しなくていいようです)
これから本格的にARMなWindowsの時代に突入しそうな雰囲気を感じますが、まだまだ対応していないものが多すぎて実用に持っていくにはまだちょっと壁がたくさんありますね。。
M1 Macも当初はそんな感じでしたが…あの時よりもさらにもうちょっと待ったほうがよさげな感触があります。
ARM対応ソフトであれば、めっちゃサクサク動くんですけどね。
数年後、普及していろいろとやりやすくなっていることを祈っています 🙏