![[レポート] CI/CDパイプラインでx86とGravitonの両方に対応するマルチアーキテクチャコンテナイメージの構築方法を学んできました #AWSreInvent #CMP311](https://images.ctfassets.net/ct0aopd36mqt/4pUQzSdez78aERI3ud3HNg/fe4c41ee45eccea110362c7c14f1edec/reinvent2025_devio_report_w1200h630.png?w=3840&fm=webp)
[レポート] CI/CDパイプラインでx86とGravitonの両方に対応するマルチアーキテクチャコンテナイメージの構築方法を学んできました #AWSreInvent #CMP311
はじめに
皆様こんにちは、あかいけです。
AWS re:Invent 2025に参加しており、「Build Once, Run Everywhere: Multi-Architecture in Your CI/CD Pipelines」というChalk Talkセッションを聴いてきました。
古今東西、Apple SiliconのMacBookを使っている開発者は一定数いるかと思いますが、
「ローカル環境ではarm64で開発しているのに、本番環境はx86_64で動いている...。」そんな状況に困ったことはありませんか?私はあります。
また、AWS Gravitonプロセッサを使うとコスト削減やパフォーマンス向上が期待できますが、既存のx86ベースのコンテナをどうやって移行すればいいのか悩むこともあるかと思います。
このセッションでは、x86とarm64の両方で動作するマルチアーキテクチャコンテナイメージの構築方法と、CI/CDパイプラインへの統合について詳しく解説されていましたので、その内容をまとめてみました。
セッション概要
タイトル
Build Once, Run Everywhere: Multi-Architecture in Your CI/CD Pipelines [REPEAT] (CMP311-R1)
概要
Building your containers to run on both x86 and AWS Graviton can help you optimize costs, improve performance, reduce your carbon footprint, and support local development on newer laptops. In this chalk talk, we'll take a web application built for x86, understand what it takes to run it on Graviton, then build a multi-architecture container image that allows you to run on the platform of your choice. We will demonstrate how to integrate that process in popular CI/CD systems like ArgoCD, GitLab, and GitHub.
x86とAWS Gravitonの両方で動作するコンテナを構築することで、コストの最適化、パフォーマンスの向上、カーボンフットプリントの削減、そして新しいラップトップでのローカル開発のサポートが可能になります。このChalk Talkでは、x86用に構築されたWebアプリケーションを取り上げ、Gravitonで動作させるために必要なことを理解し、好みのプラットフォームで実行できるマルチアーキテクチャコンテナイメージを構築します。ArgoCD、GitLab、GitHubなどの一般的なCI/CDシステムにそのプロセスを統合する方法をデモンストレーションします。
セッション情報
- セッションタイプ: Chalk talk
- レベル: 300 - Advanced
- トピック: Compute, Migration & Modernization
- 関連サービス: Amazon Elastic Kubernetes Service (Amazon EKS), Amazon EC2 - Graviton, Amazon EC2 Spot

セッション内容
なぜx86とarm64は互換性がないのか
まず、x86_64とarm64が互換性を持たない理由について説明がありました。

同じCのコード(int sum() { int a = 10, b = 20; return a + b; })をコンパイルしても、生成されるアセンブリコードは全く異なります。
- x86_64:
mov,addなどのx86固有の命令セット - arm64:
mov,str,ldr,addなどのARM固有の命令セット
これはISA (Instruction Set Architecture) が異なるためです。同じソースコードでも、CPUアーキテクチャが異なれば生成されるバイナリは別物になります。
CPUアーキテクチャの違いがコンテナに与える影響

CPUアーキテクチャの違いは、ソフトウェアスタック全体に影響を与えます。
- Applications & Code
- Libraries & Frameworks
- Container Runtime & Images
- Operating System
- Hypervisor
- CPU (Hardware)
ソフトウェアスタック全体がCPUアーキテクチャ(arm64, x86_64)と互換性を持つ必要があります。
コンテナの場合、以下の要素がアーキテクチャごとに異なる可能性があります。
- コンパイル言語で書かれたアプリケーションのバイナリ
- ランタイム(Python, Node.jsなど)
- ネイティブ拡張を含むライブラリ
- コンテナイメージのベースイメージ
- OSのカーネル
なぜマルチアーキテクチャ対応が必要なのか

セッションでは、マルチアーキテクチャ対応が必要な理由について参加者とのディスカッションがありました。
ローカル開発の利便性
- 開発者がApple Silicon Mac (arm64)を使用している場合、クラウド上のGravitonインスタンス(arm64)と同じアーキテクチャでローカル開発ができる
- 逆に、開発者がx86マシンを使用していて、クラウドでGravitonを使いたい場合も対応可能
Spotインスタンスの活用
- Spotインスタンスは大幅な割引価格で利用できるが、中断される可能性がある
- 複数のアーキテクチャに対応していれば、より多くのインスタンスタイプから選択でき、中断リスクを軽減できる
- Matt Garman CEOの基調講演によると、過去3年間でデータセンターに追加された新規キャパシティの50%以上がGravitonベース
インスタンスの可用性
- 特定のリージョンや特定のインスタンスタイプが利用できない場合がある
- 複数のアーキテクチャに対応していれば、代替のインスタンスタイプを利用できる
ISV (Independent Software Vendor) の柔軟性
- ソフトウェアベンダーとして、顧客に幅広い選択肢を提供できる
移行時の安全性
- x86からGravitonへの移行時に、いつでもロールバックできる安心感
マルチアーキテクチャコンテナイメージのビルド方法

マルチアーキテクチャコンテナイメージをビルドする方法には、大きく2つのアプローチがあります。
- エミュレーション: x86マシン上でarm64をエミュレートしてビルド(QEMU使用)
- ネイティブビルド: 各アーキテクチャのネイティブマシンでビルド
エミュレーション vs ネイティブビルド
| 観点 | エミュレーション | ネイティブビルド |
|---|---|---|
| 導入の容易さ | 簡単(ソフトウェアのインストールのみ) | ハードウェアの準備が必要 |
| ビルド速度 | 遅い(特にコンパイル言語) | 高速 |
| 信頼性 | エミュレータ由来のエラーが発生する可能性 | 安定 |
本番環境のCI/CDパイプラインではネイティブビルドが推奨されます。
エミュレーションはローカル開発や検証には便利ですが、コンパイル言語のビルドでは著しく遅くなり、エミュレータ特有のエラーが発生することもあります。
ネイティブビルドの具体的な方法

CI/CDパイプラインでネイティブビルドを行う場合の推奨構成が紹介されました。
arm64インスタンスでのビルド
$ docker build \
-t 123456789012.dkr.ecr.us-west-2.amazonaws.com/myapp:test-arm64 .
$ docker push 123456789012.dkr.ecr.us-west-2.amazonaws.com/myapp:test-arm64
x86インスタンスでのビルド
$ docker build \
-t 123456789012.dkr.ecr.us-west-2.amazonaws.com/myapp:test-x86 .
$ docker push 123456789012.dkr.ecr.us-west-2.amazonaws.com/myapp:test-x86
マニフェストの作成(いずれかのインスタンスで実行)
$ docker manifest create 123456789012.dkr.ecr.us-west-2.amazonaws.com/myapp:test \
123456789012.dkr.ecr.us-west-2.amazonaws.com/myapp:test-arm64 \
123456789012.dkr.ecr.us-west-2.amazonaws.com/myapp:test-x86
$ docker manifest push 123456789012.dkr.ecr.us-west-2.amazonaws.com/myapp:test
ポイントは、最終的に単一のタグ(myapp:test)を参照するだけで、実行環境のアーキテクチャに応じた適切なイメージが自動的に選択されることです。
Dockerfileを2つ管理する必要はない
セッション中、「各アーキテクチャ用に別々のDockerfileを管理する必要があるのか?」という質問がありました。
答えはNoです。 Docker BuildKitのAutomatic Platform Args機能を使えば、単一のDockerfileで両方のアーキテクチャに対応できます。
ARG TARGETPLATFORM
ARG TARGETARCH
# $TARGETPLATFORMや$TARGETARCHを使って
# アーキテクチャ固有の処理を記述できる
これらの変数はdocker build実行時に自動的に設定されます。
CI/CDパイプラインへの統合

典型的なCI/CDパイプラインでのマルチアーキテクチャビルドの流れが紹介されました。
- Code repo
- ソースコードのリポジトリ
- 並列ビルド
- x86ランナー: Build and push (x86) → Test (x86)
- Gravitonランナー: Build and push (arm64) → Test (arm64)
- アーティファクトの作成
- 両方のビルドが完了したら、マニフェストを作成
- Deploy
- 単一のタグでデプロイ
重要なポイントは、「両方のアーキテクチャでテストを実行すること」
セッションでは、x86のイメージだけをテストして4ヶ月後にarm64でバグが発覚した事例が紹介されました。
特に、パフォーマンステストは両方のアーキテクチャで実施することが推奨されています。
Docker BuildKitによる並列ビルドの簡素化
セッション中、別のアプローチとしてDocker BuildKitのリモートビルダー機能も紹介されました。
複数のBuildKitインスタンス(x86用とarm64用)を用意し、単一のdocker buildコマンドで両方のアーキテクチャのビルドを並列実行できます。
これにより、CIシステム側で並列処理を管理する必要がなくなります。
AWS Gravitonプロセッサの特徴

AWS Gravitonプロセッサの重要な特徴として、vCPU = 物理コアという点が説明されました。
Intel/AMD (例: C6iインスタンス)
- 2つのvCPUが1つの物理コアを共有(SMT/ハイパースレッディング)
- プロセッサ実行リソースを2つのvCPUで分け合う
AWS Graviton (例: C7gインスタンス)
- 各vCPUが独立した物理コアに対応
- プロセッサ実行リソースを占有
Gravitonのメリット
- 高負荷時でも安定したパフォーマンス
- マルチテナント環境での一貫したパフォーマンス
- 1 vCPUでもアイソレーションを維持した「medium」サイズインスタンスが利用可能
CPU使用率に関する注意点
セッションでは、x86とGravitonを混在させる環境でのスケーリングについても議論がありました。
CPU使用率ベースのスケーリングの課題
ハイパースレッディングが有効なx86インスタンスでは、CPU使用率とスループットの関係が線形ではありません。一定のCPU使用率を超えると、スループットの伸びが鈍化します。
一方、GravitonインスタンスではvCPU = 物理コアのため、より線形に近い関係になります。
推奨されるアプローチ
- CPU使用率ではなく、レイテンシベースのスケーリングを検討
- KDAなどを使用してリクエストのレイテンシを監視
Kubernetesでのマルチアーキテクチャ運用
Amazon EKSでGravitonノードを導入する際のアプローチについても解説がありました。
段階的な導入方法
-
- Node Selectorの活用
- arm64をサポートするワークロードにのみ
nodeSelectorを設定
-
- Taintsの活用
- Gravitonノードにtaintを設定し、対応するワークロードのみがスケジュールされるようにする
-
- Karpenterの活用
- 複数のアーキテクチャをNode Poolで定義し、ワークロードの要求に応じて適切なノードをプロビジョニング
サイドカーコンテナに注意
EKSでGravitonを導入する際、見落としがちな点としてサイドカーコンテナが挙げられました。
アプリケーションコンテナだけでなく、ロギングやモニタリング用のサイドカーコンテナもマルチアーキテクチャ対応が必要です。
eks-node-viewerというツールを使うと、クラスター内のすべてのコンテナをスキャンし、arm64対応状況を確認できます。
依存ライブラリの対応状況
Pythonを使用している場合、Graviton porting advisorというオープンソースツールが紹介されました。
このツールは、リポジトリをスキャンして以下を確認します。
- requirements.txtの依存関係
- 各依存関係のarm64サポート状況
- arm64対応に必要なバージョンアップの情報
Javaの場合、JARファイル内にx86固有のネイティブライブラリが含まれていないかをスキャンするツールもあります。
参考リソース

セッションで紹介された参考リソースです。
このガイドには以下の情報が含まれています。
- 各言語・ランタイムのGraviton対応状況
- 最適化のベストプラクティス
- パフォーマンスチューニングの方法
価格とパフォーマンスについて
セッションで言及された、Gravitonの価格とパフォーマンスに関する情報です。
- 価格: 同等のx86インスタンスと比較して約20%安いオンデマンド価格
- パフォーマンス: アプリケーションによって異なるが、最大40%のコスト削減効果(価格の低さ + パフォーマンス向上の組み合わせ)
ただし、パフォーマンスはアプリケーションの特性に大きく依存するため、実際にベンチマークを取ることが重要です。
さいごに
以上、「Build Once, Run Everywhere: Multi-Architecture in Your CI/CD Pipelines」のセッションレポートでした。
このセッションにおいて、個人的には以下の点が印象的でした。
- マルチアーキテクチャ対応の価値
- ローカル開発の効率化、Spotインスタンスの活用、移行時の安全性など、様々なメリットがある
- ネイティブビルドの推奨
- 本番環境のCI/CDでは、エミュレーションではなくネイティブビルドを使用すべき
- 両アーキテクチャでのテスト
- 機能テストだけでなく、パフォーマンステストも両方で実施することが重要
- Gravitonの特徴
- vCPU = 物理コアという設計により、一貫したパフォーマンスを提供
- 段階的な移行
- Node SelectorやTaintsを活用して、段階的にGravitonを導入可能
マルチアーキテクチャ対応は一見複雑に思えますが、Docker BuildKitやマニフェストの仕組みを活用すれば、単一のDockerfileで両方のアーキテクチャに対応できることがわかりました。
Gravitonへの移行を検討している方や、Apple SiliconのMacでの開発環境とクラウド環境の差異に悩んでいる方には、ぜひマルチアーキテクチャコンテナの導入を検討してみてください。
この記事が皆様のコンテナ運用の参考になれば幸いです。








