マルチ CPU アーキテクチャのサポートを活用¶
Docker イメージはマルチ・アーキテクチャ(multi-architecture)をサポートしています。つまり1つのイメージ内に、異なるアーキテクチャを含んでいたり、稀に Windows のような異なるオペレーティングシステムを含むことがあります。
マルチ・アーキテクチャをサポートしているイメージの実行時、 docker
は自動的に OS とアーキテクチャに一致した、対応しているイメージを選択します。
Docker Hub 上の大部分の公式イメージには、 様々なアーキテクチャ があります。例えば、 busybox
イメージがサポートするのは amd64
、 arm32v6
、 arm32v7
、 arm64v8
、 i386
、 ppc64le
、 s390x
です。このイメージを x86_64
/ amd64
マシン上で実行しようとすると、 x86_64
対応版を自動的に取得・実行します。
Doker Desktop は binfmt_misc
マルチ・アーキテクチャをサポートします。つまり、 arm
、 mips
、 ppc64le
のような異なる Linux アーキテクチャでコンテナを実行できるだけでなく、 x390x
でさえもです。
Docker for Mac 仮想マシン が qemu-static を使うので、コンテナ内で特別な設定は不要です。これにより、 busybox イメージの arm32v7
や ppc64le
に対応した ARM コンテナを実行可能です。
Buildx [実験的機能]¶
現在の Docker は、 Arm サーバやデバイス向けのコンテナ開発が、以前よりも簡単になりました。標準的な Docker ツールや手順を用いて、異なるコンピュータ・アーキテクチャ上のイメージの開発、送信、受信、実行がシームレスに行えます。なお、Arm 向けにビルド開始しようとするとき、Dockerfile やソースコードに一切変更を加える必要はありません。
Docker には buildx という新しい CLI コマンドライン・ツールを導入しました。Docker Desktop for Mac と Windows では、この buildx コマンドを使うことで、複数のアーキテクチャに対応したイメージを構築し、マニフェスト・ファイルでそれらを一緒にし、コマンド1つでこれら全てを送信できます。エミュレーションを入れておけば、単にネイティブなイメージを作るよりも、透過的に構築できます。Buildx はこれらを行うため、 BuildKit をベースとする新しい構築インスタンスを追加しました。そして、Docker Desktop の技術スタックによって、ネイティブではないバイナリも実行します。
Buildx CLI コマンドに関する詳しい情報は Buildx をご覧ください。
インストール¶
1. Docker Desktop の最新バージョンをダウンロードします。
2. 画面の指示に従い、インストール手順を完了します。Docker Desktop のインストールに成功したら、タスクトレイ内に Docker のアイコンが見えます。
3. Docker メニューから About Docker Desktop をクリックし、インストールした Docker Desktop のバージョンが 2.0.4.0 (33772) 以上かどうかを確認します。
マルチ・アーキテクチャ・イメージの構築と実行¶
docker buildx ls
コマンドを実行し、既存のビルダーを一覧表示します。以下で表示しているのは、デフォルトのビルダーです。これは元々ある古いビルダーです。
$ docker buildx ls
NAME/NODE DRIVER/ENDPOINT STATUS PLATFORMS
default * docker
default default running linux/amd64, linux/arm64, linux/arm/v7, linux/arm/v6
マルチ・アーキテクチャ機能を利用できる新しいビルダーを作成します。
$ docker buildx create --name mybuilder
mybuilder
あるいは、新しいビルダーを作成してコマンド1つで切り替えるには docker buildx create --name mybuilder --use
を実行します。
新しいビルダーに切り替えて調べてみましょう。
$ docker buildx use mybuilder
$ docker buildx inspect --bootstrap
[+] Building 2.5s (1/1) FINISHED
=> [internal] booting buildkit 2.5s
=> => pulling image moby/buildkit:master 1.3s
=> => creating container buildx_buildkit_mybuilder0 1.2s
Name: mybuilder
Driver: docker-container
Nodes:
Name: mybuilder0
Endpoint: unix:///var/run/docker.sock
Status: running
Platforms: linux/amd64, linux/arm64, linux/arm/v7, linux/arm/v6
マルチ・アーキテクチャ・イメージの構築、送信、実行のワークフローが機能するかどうか調べます。簡単なサンプル Dockerfile を作成し、2つの派生イメージを作成し、それらを Docker Hub に送信します。
$ mkdir test && cd test && cat <<EOF > Dockerfile
FROM ubuntu
RUN apt-get update && apt-get install -y curl
WORKDIR /src
COPY . .
EOF
$ docker buildx build --platform linux/amd64,linux/arm64,linux/arm/v7 -t username/demo:latest --push .
[+] Building 6.9s (19/19) FINISHED
...
=> => pushing layers 2.7s
=> => pushing manifest for docker.io/username/demo:latest 2.2
username
の場所には、有効な Docker ユーザ名を入れます。
注釈
--platform
フラグは、buildx に対して AMD 64-bit 、 Arm 64-bit、Armv7 アーキテクチャに対応する Linux イメージを生成するように伝えます。--push
フラグは、生成したマルチ・アーキテクチャ対応マニフェストを生成し、全てのイメージを Docker Hub に送信します。
イメージの調査には imagetools
を使います。
$ docker buildx imagetools inspect username/demo:latest
Name: docker.io/username/demo:latest
MediaType: application/vnd.docker.distribution.manifest.list.v2+json
Digest: sha256:2a2769e4a50db6ac4fa39cf7fb300fa26680aba6ae30f241bb3b6225858eab76
Manifests:
Name: docker.io/username/demo:latest@sha256:8f77afbf7c1268aab1ee7f6ce169bb0d96b86f585587d259583a10d5cd56edca
MediaType: application/vnd.docker.distribution.manifest.v2+json
Platform: linux/amd64
Name: docker.io/username/demo:latest@sha256:2b77acdfea5dc5baa489ffab2a0b4a387666d1d526490e31845eb64e3e73ed20
MediaType: application/vnd.docker.distribution.manifest.v2+json
Platform: linux/arm64
Name: docker.io/username/demo:latest@sha256:723c22f366ae44e419d12706453a544ae92711ae52f510e226f6467d8228d191
MediaType: application/vnd.docker.distribution.manifest.v2+json
Platform: linux/arm/v7
このイメージは Docker Hub 上で username/demo:latest
というタグで利用可能になりました。このイメージを使って、Intel ノート PC 上や、 Amazon EC2 A1 インスタンス上や、Raspberry Pis や、その他のアーキテクチャ上でコンテナを実行できます。Docker はイメージ取得時、各々のアーキテクチャに対応したものをダウンロードします。そのため、 Raspberry Pi では 32-bit Arm バージョンを実行し、EC2 A1 インスタンスでは 64-bit Arm を実行します。 SHA タグの識別は、イメージ派生ごとに保持します。また、Docker Desktop 上では異なるアーキテクチャとしてタグ付けされたイメージを実行可能です。
イメージの実行には SHA タグを使えますし、アーキテクチャの確認もできます。例えば、以下のコマンドを macOS 上で実行します:
$ docker run --rm docker.io/username/demo:latest@sha256:2b77acdfea5dc5baa489ffab2a0b4a387666d1d526490e31845eb64e3e73ed20 uname -m
aarch64
$ docker run --rm docker.io/username/demo:latest@sha256:723c22f366ae44e419d12706453a544ae92711ae52f510e226f6467d8228d191 uname -m
armv7l
この例では、 uname -a
の実行結果が aarch64
と armv7l
になっているだけでなく、各コマンドが macOS 開発マシン上でネイティブに実行しています。
参考
- Leverage multi-CPU architecture support
- https://docs.docker.com/docker-for-mac/networking/