こんにちは、たねやつです。
前回は、GitLab CI/CDを使ってDockerイメージのビルドとプッシュを自動化しました。しかし、そのイメージは開発PC(x86_64アーキテクチャ)でビルドされたもので、そのままでは最終目標であるRaspberry Pi(ARMアーキテクチャ)では動作しません。
今回はこのアーキテクチャの壁を乗り越えるため、docker buildx という強力なツールを使います。目標は、「1回のビルドで、x86とARMの両方で動作するマルチプラットフォームイメージを作成する」ことです。
前の記事
この記事でできること
- CPUアーキテクチャ(x86_64とARM)の違いが開発にどう影響するか理解できる。
docker buildxの役割と基本的な使い方がわかる。- GitLab CI/CDパイプラインを修正し、マルチプラットフォーム対応のDockerイメージをビルドできるようになる。
CPUアーキテクチャの壁とは?
CPUには様々な設計思想(アーキテクチャ)があり、PCで一般的なのはx86_64(またはamd64)、Raspberry Piや多くのスマートフォンで使われているのがARM(arm64またはaarch64)です。
これらは互換性がないため、x86_64向けに作られたプログラム(Dockerイメージも含む)は、ARMのCPU上では原則として動きません。
この問題を解決するのが、マルチプラットフォームビルドです。1つのイメージ名(例: my-app:latest)の中に、複数のアーキテクチャに対応したプログラムを格納しておくことで、Dockerが実行環境のCPUアーキテクチャを自動で判別し、適切なプログラムを実行してくれます。
Docker Buildxとは?
docker buildxは、このマルチプラットフォームビルドを簡単に行うためのDocker公式の拡張機能です。内部ではQEMUというエミュレータを利用して、例えばx86のCPU上でARMのプログラムをビルドする、といったことを可能にしています。
マルチプラットフォームビルド対応のパイプライン構築手順
GitLab CI/CDでdocker buildxを使うために、.gitlab-ci.ymlを修正していきます。
1. QEMUのセットアップ
docker buildxが異なるアーキテクチャのコードをビルドするためには、エミュレータであるQEMUが必要です。幸いなことに、これを簡単に行うためのDockerイメージが公開されています。
2. .gitlab-ci.ymlの修正
前回の.gitlab-ci.ymlを、docker buildxを使うように以下のように変更します。
.gitlab-ci.yml(変更後):
stages: - build variables: IMAGE_TAG: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG # ビルド対象のプラットフォームを定義 PLATFORMS: linux/amd64,linux/arm64 build_multiarch_image: stage: build image: docker:latest services: - docker:dind before_script: # buildxを有効化し、QEMU(エミュレータ)をセットアップする - docker context create builder-context - docker buildx create --name mybuilder --driver docker-container --use builder-context - docker run --rm --privileged multiarch/qemu-user-static --reset -p yes - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY script: # docker buildx を使ってマルチプラットフォームビルドを実行 - docker buildx build --platform $PLATFORMS -t $IMAGE_TAG --push . only: - main
変更点のポイント:
- ジョブ名の変更:
- 分かりやすく
build_multiarch_imageに変更しました。
- 分かりやすく
- PLATFORMS変数:
- ビルド対象のプラットフォームを
linux/amd64(x86_64) とlinux/arm64の両方を指定するようにしました。
- ビルド対象のプラットフォームを
- before_script:
docker buildx createで、buildx用のビルダーインスタンスを作成しています。multiarch/qemu-user-staticイメージを実行し、QEMUをセットアップしています。これにより、異な るCPUアーキテクチャのバイナリを実行できるようになります。- script:
- コマンドが
docker buildからdocker buildx buildに変わりました。 --platform $PLATFORMSオプションで、ビルド対象のプラットフォームを指定します。--pushオプションを付けています。docker buildxでは、複数のイメージをまとめて出力するために、ビルドと同時にレジ ストリにプッシュする必要があります。
- コマンドが
3. パイプラインの実行と確認
この修正を加えた.gitlab-ci.ymlをコミットし、mainブランチにプッシュします。
git add .gitlab-ci.yml git commit -m "Update .gitlab-ci.yml for multi-platform build" git push
GitLabでパイプラインの実行状況を確認しましょう。buildxのセットアップと2つのプラットフォーム向けのビルドが実行されるため、前回よりも少し時間がかかります。
これで、1つのイメージで開発PC(WSL)とRaspberry Piの両方で動く準備が整いました!
最後に
今回は、docker buildxを導入し、CI/CDパイプラインでマルチプラットフォームイメージをビルドする方法を学びました。これで、開発環境と本番環境のCPUアーキテクチャの違いという大きな壁を乗り越えることができました。
いよいよ次は、このイメージを最終目標であるRaspberry Piにデプロイします。次回は、Raspberry Piに軽量Kubernetesである「K3s」をインストールし、手動でアプリケーションをデプロイする手順を解説します。