【Docker】マルチアーキテクチャ対応のイメージをビルドする
今発売されているMacはすべてARMアーキテクチャを採用したCPUを使用しており,以前のIntelチップやWindowsの多くの機種とアーキテクチャが異なる.
M1 MacではRosettaなどのアーキテクチャ変換技術を用いることでAMDアーキテクチャのイメージを使うことができるが,とても実行に時間がかかる.(逆に,ARMのイメージしかない場合,AMDの環境では実行できるのだろうか?)
そのため,dockerのイメージをDockerfileからビルドして,AMDとARMの複数用意したくなった.
このときのやり方をメモする.
環境
前提
PCの環境
Docker hubに登録しており,ターミナル上でdocker login
を実行し,ログインされた状態.
人間
Dockerfileから自分でイメージをなんとかbuildできるくらいの知識はある.
Mac
M1のMacbook Pro (Monterey)
% sw_vers
ProductName: macOS
ProductVersion: 12.1
BuildVersion: 21C52
Docker
% docker version
Client:
Cloud integration: v1.0.22
Version: 20.10.11
API version: 1.41
Go version: go1.16.10
Git commit: dea9396
Built: Thu Nov 18 00:36:09 2021
OS/Arch: darwin/arm64
Context: default
Experimental: true
Server: Docker Engine - Community
Engine:
Version: 20.10.11
API version: 1.41 (minimum version 1.12)
Go version: go1.16.9
Git commit: 847da18
Built: Thu Nov 18 00:34:44 2021
OS/Arch: linux/arm64
Experimental: false
containerd:
Version: 1.4.12
GitCommit: 7b11cfaabd73bb80907dd23182b9347b4245eb5d
runc:
Version: 1.0.2
GitCommit: v1.0.2-0-g52b36a2
docker-init:
Version: 0.19.0
GitCommit: de40ad0
ちなみに公式的に必要なのは
Docker メニューから About Docker Desktop をクリックし、インストールした Docker Desktop のバージョンが 2.0.4.0 (33772) 以上かどうかを確認します。
マルチ CPU アーキテクチャのサポートを活用 - Docker
らしい.
buildx
自分でインストールした記憶がないが,既に入っていた.いつからかのバージョンから標準搭載になったのかも.
% docker buildx version
github.com/docker/buildx v0.7.1 05846896d149da05f3d6fd1e7770da187b52a247
やり方
ビルダーを作成
以下のコマンドで新たなビルダーを作成.
docker buildx create --name armamd
--name
の後に書いたのがこのビルダーの名前.場合によって変える.以降,armamd
として進める.
作成できたかは,以下のコマンドでビルダーの一覧を取得することで確認できる.
docker buildx ls
作った名前のものがあればOK.
ビルダーを切り替え
以下のコマンドを実行して,先ほど作成したビルダーに切り替える.
docker buildx use armamd
そして,
docker buildx ls
を実行するとビルダー名の横に*
がつく.
以下のコマンドで一応切り替えられたかちゃんと作成できたかとか,色々チェックできる.
docker buildx inspect --bootstrap
自分の場合,結果は以下.
[+] Building 13.8s (1/1) FINISHED
=> [internal] booting buildkit 13.7s
=> => pulling image moby/buildkit:buildx-stable-1 13.1s
=> => creating container buildx_buildkit_armamd0 0.6s
Name: armamd
Driver: docker-container
Nodes:
Name: armamd0
Endpoint: unix:///var/run/docker.sock
Status: running
Platforms: linux/arm64, linux/amd64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/mips64le, linux/mips64, linux/arm/v7, linux/arm/v6
ビルドする
今回は,とりあえずMac全体をターゲットとするイメージを作成したいので,linux/arm64, linux/amd64を対象にする.
公式の例を使うとこんな感じ.
docker buildx build --platform linux/amd64,linux/arm64 -t username/demo:latest --push .
ビルドコマンドを実行すると,当たり前だがビルドが始まるので時間がかかるので注意.
もちろん,usernameやリポジトリ名(今回だとdemo),タグ(今回だとlatest)の部分などは個別の環境で変更する必要がある.
buildコマンドの文法
ビルドコマンドを個別に覚えなきゃいけないのか?と怖かったが,そんなこともなさそうだと思った.
個人的には,普通のビルドのコマンドに対して,以下の変換を行えば良いものだとイメージしている.
docker image build
→docker buildx build
- buildの直後に
--platform linux/amd64,linux/arm64
を追加(直後じゃなくてもいいかもしれないが…) - タグ(先ほどの例だと
-t username/demo:latest
)とDockerfileのパス(先ほどの例だと.
)の間に--push
を追加(これもここじゃなくてもいいかもしれないが…)--push
は生成したイメージとアーキテクチャの対応を踏まえた上で全てのイメージをDocker Hubに送信することを意味する.
たとえば,普通のイメージのビルドを以下のコマンドで行なっているとする.
docker image build \
--build-arg dir_name=$DIR_NAME \
--build-arg user_name=$USER_NAME \
-t username/$DIR_NAME:$IMAGE_VERSION $SCRIPT_DIR/docker
このとき,armとamd用のイメージをビルドして,docker hubにアップロードしたい場合は以下のコマンドを実行すれば良い.
docker buildx build \
--platform linux/amd64,linux/arm64 \
--build-arg dir_name=$DIR_NAME \
--build-arg user_name=$USER_NAME \
-t username/$DIR_NAME:$IMAGE_VERSION \
--push $SCRIPT_DIR/docker
なお,$XXX
は事前にシェルスクリプト内で代入した変数であり,\
はシェルスクリプト内の改行するときのマークである.
実行が終了したあと,Docker hubでちゃんと指定したアーキテクチャのイメージがアップロードされていればOK!
結論
buildx
を使えば簡単にできる.
コメント
結構簡単で,覚えることもそんなになくできたので感動している.
docker buildx ls
をやった時点でdefaultのビルダーが存在したのでもしかしたら新しい環境を作成しなくてもうまくいったのかもしれないが未検証.