Upgrade to Pro — share decks privately, control downloads, hide ads and more …

マルチアーキテクチャ対応のコンテナイメージをちゃんと理解して使いこなす

 マルチアーキテクチャ対応のコンテナイメージをちゃんと理解して使いこなす

GREE Tech Conference 2025で発表された資料です。
https://techcon.gree.jp/2025/session/TrackB-4

Avatar for gree_tech

gree_tech PRO

October 17, 2025
Tweet

More Decks by gree_tech

Other Decks in Technology

Transcript

  1. 背景 : 身近になった ARM アーキテクチャ • x86 中心だったサーバサイドでも ARM が広がりを見せている

    • AWS, Google Cloud での身近な ARM トピック ◦ 2018/11 AWS re:Invent にて ARM ベースプロセッサ Graviton 発表 ◦ 2020/06 AWS Tokyo リージョンで Graviton2 が利用可能に ◦ 2023/02 AWS Tokyo リージョンで Graviton3 が利用可能に ◦ 2024/12 AWS Tokyo リージョンで Graviton4 が利用可能に ◦ 2024/04 Google Cloud Next にて ARM ベースプロセッサ Axion 発表 ◦ 2025/春頃 Tokyo リージョン GKE で Axion ベース VM ノードが利用可能に 4
  2. 背景 : 身近になった ARM アーキテクチャ • ARM PC の普及 ◦

    サーバサイド & ローカル PC で同じイメージをエミュレーションなしで実行したい ◦ Apple silicon Mac での将来的な x86 エミュレーション提供の不透明さ • x86 / ARM どちらでも利用可能なコンテナイメージが求められる 5 Single-platform images Multi-platform image
  3. WFS サーバサイド開発の CPU 近況 • 開発者 PC ◦ Mac (Apple

    silicon) & Windows (Intel & AMD) 混在 • 現行ゲームサービスのゲーム API サーバ ◦ 基本的に x86_64 のみ • 非ゲーム API サーバ、開発環境 ◦ x86_64 & ARM 混在 • 新規開発向けゲームサーバ ◦ x86_64 & ARM 混在 6
  4. ただし書き • マルチアーキテクチャとは題しつつも ◦ x86_64, ARM の 2つを対象にして話します ▪ x86_64

    はコード中で amd64 と記載するケースがあります • 本スライド中では基本的に同義です ▪ ARM はコード中で arm64 と記載するケースがあります ◦ 他のアーキテクチャについても外れる話ではないです • コンテナは Linux コンテナのみを扱います 7
  5. ところで? それぞれの矢印でどんなコンテナイメージがやりとりされている? 8 $ docker pull \ hello-world:latest ARM PC

    x86 PC $ docker pull \ hello-world:latest $ docker tag \ hello-world:latest \ foobar/hello-world:latest $ docker push \ foobar/hello-world:latest foobar server (registry) ??
  6. コンテナイメージの構造 • OCI (Open Container Initiative) イメージフォーマット仕様にしたがう ◦ マニフェストおよびファイルシステムレイ ヤー、コンフィグ等によって構成されるこ

    とを規定する仕様 11 https://github.com/opencontainers/image-spec/blob/v1.1.1/image-layout.md https://github.com/opencontainers/image-spec/blob/v1.1.1/spec.md • ファイルとして出力する際の仕様もある => OCI イメージレイアウト仕様 • docker image save などで出力可能 ◦ 例 docker image save alpine:latest | tar xf -C dir/ blobs/ sha256/ ... index.json oci-layout
  7. レジストリ コンテナイメージの構造 (デフォルメ) イメージの名前は何を指すか? 通常は以下のどちらかを参照して使っている • ファイル実体を持ち実行可能なもの • メタデータだけを持ち、 そこから実行可能なイメージを参照するもの

    12 実行可能なイメージ ファイルシステム メタデータ (image.manifest) インデックス メタデータ (image.index) 実行可能なイメージ ファイルシステム メタデータ (image.manifest) 実行可能なイメージ ファイルシステム メタデータ (image.manifest) インデックス メタデータ (image.index) 実行可能なイメージ ファイルシステム メタデータ (image.manifest) ※ いずれも仕様上は広義のイメージですが、 本スライドでは前者をイメージ、 後者をインデックスと呼ぶようにします
  8. マルチアーキテクチャ対応するには • 各アーキテクチャ向けのイメージを作成 • イメージインデックスを作成 ◦ manifests にそれぞれへの参照を含める ▪ platform

    ごと ◦ ユーザに参照してもらうためのタグをつける (latest, v2, 1.2.3-alpine, etc.) 13 { "mediaType": "application/vnd.oci. image.index.v1+json", "manifests": [ { "mediaType": "application/vnd.oci. image.manifest.v1+json", "digest": "sha256:<amd64 イメージの digest>", "platform": { "architecture": "amd64", "os": "linux" } }, { "mediaType": "application/vnd.oci.image.manifest.v1+json", "digest": "sha256:<arm64 イメージの digest>", "platform": { "architecture": "arm64", "os": "linux", "variant": "v8" } } ] } インデックス メタデータ (image.index) ... ... $ docker pull \ hello-world:latest tags: latest
  9. 基本的なコマンドを使った作りかた • 各アーキテクチャ向けのイメージを作成し push ◦ ( 図をいれる ) ◦ (

    レジストリの状態の画像 ) ◦ ◦ ◦ • イメージインデックスを作成 14 # ARM ホストで $ docker build . \ -t someregistry/myapp:0.1.0-arm64 $ docker push \ someregistry/myapp:0.1.0-arm64 # x86_64 ホストで $ docker build . \ -t someregistry/myapp:0.1.0-amd64 $ docker push \ someregistry/myapp:0.1.0-amd64 # Usage: docker manifest create MANIFEST_LIST MANIFEST [MANIFEST...] $ docker manifest create \ someregistry/myapp:0.1.0 \ someregistry/myapp:0.1.0-arm64 \ someregistry/myapp:0.1.0-amd64
  10. より便利なコマンド • 実用的にはもっとイージーに作成可能 • 例 : docker buildx ◦ 各アーキテクチャ向けにビルドしてインデックス作成し

    push ◦ 内容確認 16 $ docker buildx build . \ --platform=linux/amd64,linux/arm64 \ -t someregistry/myapp:0.2.0 \ --push $ docker buildx imagetools inspect someregistry/myapp:0.2.0 Name: someregistry/myapp:0.2.0 MediaType: application/vnd.oci.image.index.v1+json Digest: sha256:c86a1c628af0e47bf09b4c2ad49c68797fa7908822fc16c284f8a52ecf6a2f9c Manifests: Name: someregistry/myapp:0.2.0@sha256:8c8aa16... MediaType: application/vnd.oci.image.manifest.v1+json Platform: linux/amd64 Name: someregistry/myapp:0.2.0@sha256:7aded20... MediaType: application/vnd.oci.image.manifest.v1+json Platform: linux/arm64 ...
  11. ※ 注: build の挙動が異なる場合があります • 前述の docker コマンドによるビルド出力は環境により異なります ◦ 2025/09

    現在、Docker Desktop では自動的にイメージインデックス+イメージのビルド 結果が得られます (設定依存) ▪ その場合に単一のイメージとしてビルドするには 17 $ docker build . \ --provenance=false \ -t someregistry/myapp:0.1.0-arm64
  12. エミュレーションによるビルド ローカル PC の例 ※一時的な作業や検証向けに。 Docker Desktop, Podman Desktop :

    デフォルトでエミュレーション利用可能 docker-ce : QEMU, buildx-plugin の導入で利用可能 22 $ docker buildx build . \ --platform=linux/amd64,linux/arm64 \ -t someregistry/myapp:0.3.0 \ --push $ podman build . \ --platform=linux/amd64,linux/arm64 \ --manifest someregistry/myapp:0.3.0 \ $ podman manifest push \ someregistry/myapp:0.3.0
  13. エミュレーションによるビルド GitHub Actions の例 標準 GitHub Hosted ランナーで setup actions

    を利用 管理コストも低く、広く使われてい ると思われる 23 jobs: build: runs-on: ubuntu-latest steps: ... - name: Set up QEMU uses: docker/setup-qemu-action@v3 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 ... - name: Build and push uses: docker/build-push-action@v6 with: platforms: linux/amd64,linux/arm64 push: true tags: xxx
  14. エミュレーションよしあし • ビルド環境、ワークフローの管理が簡単 • 計算コストが高い場合にパフォーマンス悪化が顕著 ◦ 問題となった事例: PHP gRPC 拡張のインストール

    ▪ もともと時間のかかる処理だったが QEMU 環境でより顕著に ▪ GitHub Actions, on: ubuntu-latest (x86) • Build linux/amd64: 約10分~ • Build linux/arm64: 約250分~ 24 RUN ... && pecl install grpc-1.x.x 関連: 弊社 藤田によるブログ記事 Github ActionsでCloud Spanner対応のPHPイメージをビルドするための工夫|株式会社 WFS https://note.com/wfs_blog/n/na6adcf9c454f
  15. アーキテクチャごとに別ホストでビルド docker buildx の例 • builder にリモートホストを登録可能 • 対象アーキテクチャごとに 使ってほしいホストを指定する

    • push する場合はリモートから registry に疎通可能である必要あり • ローカル書き出しは非サポート (2025/09 現在) 25 $ docker buildx create \ --name multi-node-builder \ --node local \ --platform linux/arm64,linux/arm $ docker buildx create \ --name multi-node-builder \ --append \ --node remote-x86 \ --platform linux/amd64,linux/386 \ ssh://remote-builder-host $ docker buildx use multi-node-builder $ docker buildx build . \ --platform=linux/amd64,linux/arm64 \ -t someregistry/myapp:0.3.0 \ --push
  16. アーキテクチャごとに別ホストでビルド GitHub Actions の例 • x86 用は標準ランナーで • ARM 用には

    Self-Hosted ランナー or GitHub Hosted ランナー を使う • GitHub Hosted ランナーは制限あり ◦ public レポ ◦ Enterprise or Team プラン ▪ org 毎に Large Runner として明示的に追加 • それぞれのビルド後に イメージインデックスを作成する ◦ docker buildx imagetools create \ xxx:latest-amd64 \ xxx:latest-arm64 \ --tag xxx:latest 26 jobs: build-x86: runs-on: ubuntu-latest steps: ... - name: Build amd64 uses: docker/build-push-action@v6 with: platforms: linux/amd64 push: true tags: xxx:latest-amd64 build-arm: # Self-hosted runner または org で Large Runner 登録 runs-on: ubuntu-your-arm-runner steps: ... - name: Build arm64 uses: docker/build-push-action@v6 with: platforms: linux/arm64 push: true tags: xxx:latest-arm64
  17. アーキテクチャごとに別ホストでビルド GitHub Actions から AWS CodeBuildの例 • runs-on: codebuild- で

    AWS CodeBuild をランナーとして利用可能 27 jobs: build-codebuild-x86: runs-on: codebuild-my-x86-prj-${{ github.run_id }}-${{ github.run_attempt }} steps: ... build-codebuild-arm: runs-on: codebuild-my-arm-prj-${{ github.run_id }}-${{ github.run_attempt }} steps: ... --- # または jobs: build-codebuild: runs-on: - codebuild-my-prj-${{ github.run_id }}-${{ github.run_attempt }} image: arm-3.0 instance-size: small steps: ...
  18. まとめ • コンテナイメージのマルチアーキテクチャ対応 ◦ 各アーキテクチャごとのイメージをたばねた イメージインデックス(マニフェストリスト) によって実現される • アーキテクチャの異なるイメージをビルドするには ◦

    エミュレーション or ◦ ネイティブ環境でそれぞれビルドし、インデックスで束ねる • GitHub Actions, AWS を中心とした CI 例の紹介 ◦ 基本手順は同じ ▪ イメージ作成 => インデックス作成 29