3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Docker Buildx でマルチプラットフォームビルドを実現

Last updated at Posted at 2024-11-29

背景

Windows環境(Intel/AMD)で開発を進めている中で、Lambda(Linux/ARM64)にデプロイするための Docker イメージをビルドしようとしたところエラーが発生しました。
結論、ホストマシンとビルドターゲット間のプラットフォームの違いが原因でした。
この記事では、このような異なるプラットフォーム間のビルド課題を解消するために、Docker Buildxを活用する方法を解説します。

Docker Buildx とは

Docker Buildx は、Docker の拡張ツールで、特にマルチプラットフォーム対応のコンテナイメージをビルドするために使われます。
通常の Docker ビルドではホストと同じプラットフォーム向けのイメージしか作成できませんが、Buildx を使えば、異なるプラットフォーム向けのイメージを簡単にビルドできます。

なぜ異なるプラットフォームでのビルドができない?

そもそも、なぜ異なるプラットフォーム間でビルドができないのかというと、ホストマシンとターゲットプラットフォーム間のアーキテクチャや命令セットの違いが原因です。

1. CPUアーキテクチャの違い

ホストマシン(ビルドを実行するマシン)とターゲットプラットフォームのCPUアーキテクチャが異なる場合、互換性がないバイナリが生成される可能性があります。
例えば、ホストが x86_64(Intel/AMD) で、ターゲットが arm64(ARM) の場合、生成されるコードが異なるCPUの命令セットを理解できません。
そのままではターゲットの環境で実行できないコンテナイメージが作成されます。

2. ネイティブ依存関係

Dockerイメージの中には、ネイティブのライブラリやバイナリ(CやC++で書かれたコード)を含む場合があります。
これらのネイティブコンポーネントは、ビルド時のプラットフォーム(ホスト)でコンパイルされるため、異なるプラットフォームで動作しない可能性があります。
例えば、x86_64 でビルドされたライブラリ(例:glibc)は、arm64 では動作しません。
特に、Dockerfileで RUN コマンドを使用してソフトウェアをインストールする際に問題が発生します。

3. Dockerの設計方針

Dockerは、シンプルで高速なビルドを提供するため、基本的にはホストプラットフォームと同じアーキテクチャをターゲットにしています。
ホストとターゲットのアーキテクチャが一致する場合、ネイティブな速度でビルドと実行が可能です。
一致しない場合、標準的なDockerではこれをサポートしていないため、エラーになります。

マルチプラットフォームビルドの流れ

1.Buildx インスタンスの作成

docker buildx create --use --name mybuilder

mybuilderの部分は任意の名前で大丈夫です。

2.QEMUの有効化

docker run --rm --privileged docker/binfmt:a7996909642ee92942dcd6cff44b9b95f08dad64

QEMU をインストールすることで異なるプラットフォームへのビルドがエミュレート可能になります。

3.Buildx インスタンスを初期化

docker buildx inspect --bootstrap

docker buildx createはインスタンスを作成するだけなので初期化が必要

4. プラットフォームの確認

docker buildx ls

下記のように出力されれば大丈夫です。PLATFORMSにlinux/amd64やlinux/arm64があるので、マルチプラットフォームが有効になっています。

NAME/NODE        DRIVER/ENDPOINT                   STATUS    BUILDKIT   PLATFORMS
mybuilder*       docker-container
 \_ mybuilder0    \_ unix:///var/run/docker.sock   running   v0.17.2    linux/amd64, linux/arm64, linux/arm/v7, linux/386

5.マルチプラットフォームビルドの実行

docker buildx build --platform linux/arm64 --tag my-image:latest .

QEMU とは

QEMUは、オープンソースのエミュレーターで、異なるプラットフォーム間(例:x86_64 と arm64)の互換性を提供します。具体的には、ホストマシンがサポートしていないCPUアーキテクチャの命令セットをエミュレーションし、その環境でアプリケーションやOSを実行可能にします。Dockerと組み合わせることで、異なるプラットフォーム向けのコンテナイメージをビルドできるようになります。

Buildx だけではダメな理由

Buildx はマルチプラットフォームビルドをサポートしますが、ホストプラットフォーム以外のアーキテクチャ向けのビルドには QEMU が必要です。
Buildx はあくまで Docker のビルド機能を拡張するツールであり、異なるCPUアーキテクチャ(例:x86_64 → arm64)の命令セットそのものをエミュレーションする機能は持っていません。

Buildx 関連の便利コマンド

1. Buildx バージョン確認

docker buildx version

2. ターゲットプラットフォームの確認

現在のホストマシンのプラットフォームを確認します。

uname -m

3. Buildx インスタンスの削除

不要になった Buildx インスタンスを削除します。

docker buildx rm mybuilder

・追記

Docker デーモンが再起動すると、 QEMU 設定がリセットされるので、定期的に有効化が必要になる。

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?