Dockerのマルチアーキテクチャイメージについて調べてみた

マルチアーキテクチャイメージを使えば、単一のDockerイメージ(タグ)で複数タイプのOSやCPUアーキテクチャに対応させられます。
2020.04.04

Dockerのマルチアーキテクチャイメージについて調べる機会があったのでまとめてみました。

なお今回はデプロイ済みのマルチアーキテクチャイメージをプルして利用する観点でのまとめとなります。

マルチアーキテクチャイメージとは

Dockerイメージは「マルチアーキテクチャ」という仕様をサポートしています。

Docker images can support multiple architectures, which means that a single image may contain variants for different architectures, and sometimes for different operating systems, such as Windows.

When running an image with multi-architecture support, docker will automatically select an image variant which matches your OS and architecture.

Most of the official images on Docker Hub provide a variety of architectures. For example, the busybox image supports amd64, arm32v5, arm32v6, arm32v7, arm64v8, i386, ppc64le, and s390x. When running this image on an x86_64 / amd64 machine, the x86_64 variant will be pulled and run.

上記のDocker, Inc.のドキュメントを抄訳すると、

  • 単一のDockerイメージで複数種類のOSやCPUアーキテクチャをサポートさせることができる。
  • このイメージを起動させると、Dockerが実行されているホストのアーキテクチャに応じて適切なイメージが自動で選択される。
  • Docker Hub上の公式イメージの多くはマルチアーキテクチャをサポートしている。

とのことことです。このマルチアーキテクチャをサポートしたDockerイメージを「マルチアーキテクチャイメージ」と呼びます。

マルチアーキテクチャイメージをプルしてみる

このマルチアーキテクチャイメージをDocker Hubから実際にプルしてみます。今回はAmazon Linux公式リポジトリで試してみます。以下がリポジトリのページです。

このページで[Description]タブ - [Quick reference]の[Supported architectures]の指定(赤丸部分)を見ると、Amazon Linuxの公式イメージはamd64arm64v8に対応したマルチアーキテクチャイメージであることが分かります。 image.png

そして[Tags]タブでタグ一覧を見ると、[OS/ARCH]欄でどのタグがどのアーキテクチャに対応しているかを確認することができます。例えばlatestタグはamd64arm64v8のアーキテクチャに対応したイメージを指していることが分かります。 image.png

アーキテクチャの自動選択によるプル

それでは実際にアーキテクチャの自動選択によるプルを試してみます。まず前項でamd64arm64v8に対応していることが確認できたlatestタグをプルしてみます。

Dockerを実行しているホストマシンのディストリビューションは「Amazon Linux AMI」、CPUアーキテクチャは「x86_64」です。

$ cat /etc/issue
Amazon Linux AMI release 2018.03
Kernel \r on an \m

$ uname -m
x86_64

docker pull <リポジトリ名>:<タグ名>を実行してlatestタグをプルしてみます。

$ docker pull amazonlinux:latest
latest: Pulling from library/amazonlinux
a8d577519c9f: Pull complete 
Digest: sha256:deadcaae52851831a2f579185eceb9e86c824d67c25334fbd5ef2ee75cf525a9
Status: Downloaded newer image for amazonlinux:latest

プルできました。

$ docker images
REPOSITORY              TAG                 IMAGE ID            CREATED             SIZE
amazonlinux             latest              cd2d92bc1c0c        21 hours ago        163MB

プルしたイメージの詳細をdocker inspect <リポジトリ名>:<タグ名>コマンドにより見てみると、"Architecture": "amd64"とあるのでDockerホストのCPUアーキテクチ「x86_64」に対応するamd64アーキテクチャのイメージが自動選択されてプルされていることが分かります。

$ docker inspect amazonlinux:latest
[
    {
        "Id": "sha256:cd2d92bc1c0c25b0e15c00cfaa44320d84af71ab3fe97280d53a7b769cd96c19",
        "RepoTags": [
            "amazonlinux:latest"
        ],
        "RepoDigests": [
            "amazonlinux@sha256:deadcaae52851831a2f579185eceb9e86c824d67c25334fbd5ef2ee75cf525a9"
        ],
        "Parent": "",
        "Comment": "",
        "Created": "2020-04-01T06:46:33.215020639Z",
        "Container": "78570eeaf7fd35641f7f125766f1c300485dd8cdf5587e03658b003fa3f479d8",
        "ContainerConfig": {(省略)},
        "DockerVersion": "18.09.7",
        "Author": "",
        "Config": {(省略)},
        "Architecture": "amd64",
        "Os": "linux",
        "Size": 162801142,
        "VirtualSize": 162801142,
        "GraphDriver": {(省略)},
        "RootFS": {(省略)},
        "Metadata": {(省略)}
    }
]

アーキテクチャを指定してプル

イメージのアーキテクチャを指定してプルすることもできます。これには大きく分けて以下の2つの方法があります。

  • DIGESTを指定してプル
  • アーキテクチャのリポジトリからプル

それぞれ方法でのプルを試してみます。

DIGESTを指定してプルする

Amazon Linuxリポジトリのタグ一覧ページに戻り、それぞれのタグを見るとアーキテクチャ([OS/ARCH])に対応する[DIGEST]が記載されていることが分かります。イメージのプル時にこのDIGESTを指定することにより、そのDIGESTに対応したアーキテクチャ対応のイメージをプルすることができます。amd64アーキテクチャに対応する49b6d61fd3efのページをリンクから開いてみます。

image.png

開いたページでamd64アーキテクチャに対応するDIGESTの全文が確認できます。これをプル時に指定すれば良いです。 image.png

DIGESTを指定したイメージのプルはdocker pull <リポジトリ名>:<タグ名>@sha256:とコマンドを実行すれば行えます。実際にプルしてみます。

$ docker pull amazonlinux:latest@sha256:49b6d61fd3efc7ec126eddbb9a9c692fe89678d12f69aa96bf834ab10c30c762
sha256:49b6d61fd3efc7ec126eddbb9a9c692fe89678d12f69aa96bf834ab10c30c762: Pulling from library/amazonlinux
Digest: sha256:49b6d61fd3efc7ec126eddbb9a9c692fe89678d12f69aa96bf834ab10c30c762
Status: Downloaded newer image for amazonlinux@sha256:49b6d61fd3efc7ec126eddbb9a9c692fe89678d12f69aa96bf834ab10c30c762

プルできました。因みにここでプルされたのはamd64アーキテクチャ対応のイメージなので、先ほど自動選択によりプルしたものと同じイメージ(cd2d92bc1c0c)がプルされています。

$ docker images
REPOSITORY              TAG                 IMAGE ID            CREATED             SIZE
amazonlinux             latest              cd2d92bc1c0c        22 hours ago        163MB

また、DIGESTのページで[OS/ARCH]のコンボボックスから他のアーキテクチャを選択することができます。「linux/arm64/v8」を選択すると、そのアーキテクチャのDIGESTのページに遷移し、こちらのDIGEST全文も確認することができます。 image.png

これもプルしてみます。

$ docker pull amazonlinux:latest@sha256:13b345bea4a238e53966ef3f2e0c2586e6c12ecc1dc73155c2538befa4d03276
sha256:13b345bea4a238e53966ef3f2e0c2586e6c12ecc1dc73155c2538befa4d03276: Pulling from library/amazonlinux
01d0a3bd5b98: Pull complete 
Digest: sha256:13b345bea4a238e53966ef3f2e0c2586e6c12ecc1dc73155c2538befa4d03276
Status: Downloaded newer image for amazonlinux@sha256:13b345bea4a238e53966ef3f2e0c2586e6c12ecc1dc73155c2538befa4d03276

IMAGE IDがd5e46d9cf7e0のイメージが新しくプルされました。ただし、今回プルしたarm64/v8のイメージは先ほどプルしたのamd64のイメージとタグ名が重複するので、TAGがnoneとなっています。

$ docker images
REPOSITORY              TAG                 IMAGE ID            CREATED             SIZE
amazonlinux             latest              cd2d92bc1c0c        22 hours ago        163MB
amazonlinux             <none>              d5e46d9cf7e0        23 hours ago        193MB

プルしたイメージの詳細をdocker inspectコマンドで見てみると"Architecture": "arm64"とあり、arm64アーキテクチャのイメージがプルできていることが分かります。

$ docker inspect d5e46d9cf7e0
[
    {
        "Id": "sha256:d5e46d9cf7e04cc6828bbcc8acec3828b5b3aeb2c6b37d78549e26ac882dac0d",
        "RepoTags": [],
        "RepoDigests": [
            "amazonlinux@sha256:13b345bea4a238e53966ef3f2e0c2586e6c12ecc1dc73155c2538befa4d03276"
        ],
        "Parent": "",
        "Comment": "",
        "Created": "2020-04-01T05:22:46.624299813Z",
        "Container": "2428cc8f8dd63efb3b185340588b7c8209d7cb9ef073c3327a8ed89deda3b2f6",
        "ContainerConfig": {(省略)},
        "DockerVersion": "18.09.7",
        "Author": "",
        "Config": {(省略)},
        "Architecture": "arm64",
        "Os": "linux",
        "Size": 193217812,
        "VirtualSize": 193217812,
        "GraphDriver": {(省略)},
        "RootFS": {(省略)},
        "Metadata": {(省略)}
    }
]

アーキテクチャごとのリポジトリからプルする

前項で、Amazon LinuxリポジトリTOPページの[Description]タブ - [Quick reference]の[Supported architectures]欄にてAmazon Linuxの公式イメージが対応しているアーキテクチャを確認しましたが、この[amd64]と[arm64v8](赤丸部分)が実はそれぞれのアーキテクチャごとのリポジトリのページへのリンクになっています。 image.png

[amd64]のリンク先は「amd64/amazonlinux」というamd64アーキテクチャ対応のAmazon Linuxイメージのリポジトリページとなっています。(これはamd64リポジトリのamazonlinuxというサブリポジトリのページであるとも言えます)

[arm64v8]のリンク先は「arm64v8/amazonlinux」というarm64v8アーキテクチャ対応のAmazon Linuxイメージのリポジトリページとなっています。(これはarm64v8リポジトリのamazonlinuxというサブリポジトリのページであるとも言えます)

これらのアーキテクチャのリポジトリの[Tag]タブのページでは、そのアーキテクチャに対応しているタグのみの一覧を確認することができます。 image.png

そしてこれらのタグはpullコマンドをdocker pull <アーキテクチャ名>/<サブリポジトリ名>:<タグ名>のように実行すればプルすることができます。この方法であれば、DIGESTを指定せず、かつDockerを実行している環境によらずとも、任意のアーキテクチャに対応したイメージをプルすることができます。

例えばamd64/amazonlinuxリポジトリのlatestタグのイメージをプルするのであれば以下のように実行します。

$ docker pull amd64/amazonlinux:latest
latest: Pulling from amd64/amazonlinux
Digest: sha256:49b6d61fd3efc7ec126eddbb9a9c692fe89678d12f69aa96bf834ab10c30c762
Status: Downloaded newer image for amd64/amazonlinux:latest

ちなみに、今しがたプルしたamd64/amazonlinux:latestのイメージと、先ほどプルしたamazonlinux:latestのイメージは、プル元のリポジトリは異なりますがIMAGE IDは同じであり、実態は同一イメージであることが分かります。

$ docker images
REPOSITORY              TAG                 IMAGE ID            CREATED             SIZE
amd64/amazonlinux       latest              cd2d92bc1c0c        28 hours ago        163MB
amazonlinux             latest              cd2d92bc1c0c        28 hours ago        163MB

まとめ

  • 単一のDockerイメージ(タグ)で複数種類のOSやCPUアーキテクチャに対応するイメージを「マルチアーキテクチャイメージ」という。

また、ここまで確認したマルチアーキテクチャイメージのプル方法をまとめると以下のようになる。(実行例はamazonlinuxリポジトリからlatestタグをプルする場合)

  • 方法1 アーキテクチャの自動選択によるプル
    • コマンド:docker pull <リポジトリ名>:<タグ名>
    • 実行例:docker pull amazonlinux:latest
  • 方法2 アーキテクチャのDIGESTを指定してプル
    • コマンド:docker pull <リポジトリ名>:<タグ名>@sha256:<アーキテクチャのDIGEST>
    • 実行例:docker pull amazonlinux:latest@sha256:13b345bea…
  • 方法3 アーキテクチャごとのリポジトリからプル
    • コマンド:docker pull <アーキテクチャ名><サブリポジトリ名>:<タグ名>
    • 実行例:docker pull amd64/amazonlinux:latest

おわりに

以上、マルチアーキテクチャイメージについてプルして利用する観点で調べてまとめてみたという記事でした。

Dockerのマルチアーキテクチャサポートが提供され始めたのはここ2,3年で、AMDアーキテクチャが主に使われるWindowsやLinuxだけでなく、ARMアーキテクチャを主に採用している組み込み機器やIoTデバイスの上でも同じコンテナ環境をシームレスに扱えるようにするための仕様であるようです。

また、機会があれば自分でマルチアーキテクチャイメージをビルドしてリポジトリに登録するということもやってみようと思います。

参考

以上