|

2024-07-19

Tips

ARMなWindowsのWSLでamd64なDockerイメージをQEMUで強引に動かす方法

WindowsWSLDockerQEMU

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 のイメージ を見てみると ubuntu_Tags__Docker_Hub_2024-07-19_08-52-39

こんな感じで 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/aarch64linux/amd64 なイメージを動かす」のと逆向きの「 linux/amd64linux/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

ですね

  Monosnap__2024-07-18_20.53.24

 

動きました! 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対応ソフトであれば、めっちゃサクサク動くんですけどね。

数年後、普及していろいろとやりやすくなっていることを祈っています 🙏

 


この記事の著者

プロフィール画像

伴 拓也

朝日放送グループホールディングス株式会社 DX・メディアデザイン局 デジタル・メディアチーム

アプリケーションからインフラ、ネットワーク、データエンジニアリングまで幅広い守備範囲が売り。最近はデータ基盤の構築まわりに力を入れて取り組む。 主な実績として、M-1グランプリ敗者復活戦投票システムのマルチクラウド化等。