IoT デバイス向けのマルチアーキテクチャ コンテナ イメージ

このドキュメントは、自動継続的インテグレーション(CI)パイプラインを構築して、Google Cloud でマルチ アーキテクチャのコンテナ イメージを構築する方法を説明するシリーズのパート 1 です。このドキュメントで説明するコンセプトは、すべてのクラウド環境に適用されます。

このシリーズは、このドキュメントと付属のチュートリアルで構成されています。このドキュメントでは、コンテナ イメージを構築するパイプラインの構造について説明し、その概要手順を示します。このチュートリアルでは、サンプル パイプラインの構築について説明します。

このシリーズは、コンテナ イメージを構築するための複雑なパイプラインの簡素化と合理化、またそれらのパイプラインを拡張してマルチアーキテクチャ イメージの構築を担当する IT プロフェッショナルを対象としています。クラウド テクノロジーとコンテナに精通していることを前提としています。

CI パイプラインを実装すると、アーティファクトの構築手順が効率的になります。特定のアーキテクチャのコンテナ イメージを構築するために、専用のツールやハードウェアを維持する必要はありません。たとえば、現在のパイプラインが x86_64 アーキテクチャで実行されていて、そのアーキテクチャのコンテナ イメージのみを生成する場合、ARM ファミリーなどの他のアーキテクチャ用のコンテナ イメージを作成するには、追加のツールやハードウェアの維持が必要になることがあります。

モノのインターネット(IoT)ドメインでは、多くの場合、マルチ アーキテクチャのビルドが必要です。さまざまなハードウェアや OS ソフトウェア スタックで大量のデバイスを使用している場合、個別のデバイスのソフトウェア アプリケーションの開発、テスト、管理のプロセスは非常に大きな課題になります。マルチ アーキテクチャのビルドプロセスを使用すると、IoT アプリケーションの管理を簡素化できます。

マルチアーキテクチャ コンテナ イメージの構築の課題

多くの場合、コンテナ イメージの実装はアーキテクチャに依存します。たとえば、x86_64 アーキテクチャのコンテナ イメージを作成すると、ARM ファミリーのアーキテクチャでは実行できません。

この制限は、次のようないくつかの方法で解消できます。

  1. コンテナイ メージが必要なターゲット アーキテクチャにコンテナ イメージを構築する。
  2. 専用ツールとハードウェア デバイスを維持する。コンテナ イメージの構築に使用するアーキテクチャごとに、少なくとも 1 台のデバイスが必要になります。
  3. マルチアーキテクチャ コンテナ イメージを構築する。

どの戦略が最適かは、以下のようなさまざまな要因によって決まります。

  • パイプラインの複雑さ
  • 自動化の要件
  • コンテナ イメージを構築するための環境の設計、実装、維持に使用できるリソース

たとえば、ランタイム環境で電力使用の制限がある場合は、ランタイム環境とは別の環境でのコンテナ イメージの構築が必要な場合があります。

次の図は、実行可能な戦略を選択する際のデシジョン ポイントを示しています。

マルチアーキテクチャ コンテナ イメージを構築するための最適な戦略を決定するフローチャート。

ターゲット アーキテクチャにコンテナ イメージを構築する

1 つ目の戦略は、次の図に示すように、コンテナ自体をサポートするランタイム環境内に直接、必要なコンテナ イメージを構築することです。

ソースコード リポジトリからランタイム環境へのビルドパス。

ビルドごとに次の操作を行います。

  1. ランタイム環境の各デバイスのソースコード リポジトリから、コンテナ イメージのソースコードをダウンロードします。
  2. ランタイム環境でコンテナ イメージを構築します。
  3. コンテナ イメージを、ランタイム環境で各デバイスに対してローカルなコンテナ イメージ リポジトリに保存します。

この戦略の利点は、ランタイム環境の要件に加えて、ハードウェアのプロビジョニングとメンテナンスが不要になる点です。この戦略にはデメリットもあります。まず、ランタイム環境のすべてのハードウェア インスタンスでビルドプロセスを繰り返す必要があるため、リソースが無駄になります。たとえば、コンテナ化されたワークロードを、デバイスが電源に常時接続できないランタイム環境にデプロイすると、このようなデバイスでビルドタスクが実行されるたびに時間と電力が無駄遣いされ、ワークロードの新しいバージョンのデプロイが必要になります。また、ランタイム環境でコンテナ イメージをビルドするには、各コンテナ イメージのソースコードにアクセスするツールを維持する必要もあります。

専用のツールとハードウェアを維持する

2 つ目の戦略は、コンテナ イメージを構築するタスク専用のハードウェアを維持することです。次の図は、この戦略のアーキテクチャを示しています。

ソースコード リポジトリから専用のビルド環境へのビルドパス。

ビルドごとに次の操作を行います。

  1. 必要なハードウェア アーキテクチャとリソースを有するデバイスにコンテナ イメージのソースコードをダウンロードし、コンテナ イメージを構築します。
  2. コンテナ イメージをビルドします。
  3. コンテナ イメージを一元管理されたコンテナ イメージ リポジトリに保存します。
  4. そのイメージの新しいインスタンスをデプロイする必要がある場合は、ランタイム環境で各デバイスにコンテナ イメージをダウンロードします。

この戦略では、コンテナ イメージの構築に必要な各ハードウェア アーキテクチャのインスタンスを少なくとも 1 つプロビジョニングします。重要な本番環境では、複数のインスタンスを使用することにより、環境のフォールト トレランスを向上させ、複数のビルドジョブを同時実行する際にビルド時間を短縮できます。

この戦略には 2 つの利点があります。まず、各ビルドジョブを 1 回だけ実行し、結果のコンテナ イメージを Container Registry などの一元管理されたコンテナ イメージ リポジトリに保存できます。また、ランタイム環境にあるハードウェア アーキテクチャによく似たビルディング フリート内のデバイスにテストスイートを実行できます。この戦略の主なデメリットは、コンテナ イメージを構築するタスクを実行する専用のインフラストラクチャとツールをプロビジョニングして維持する必要があることです。通常、各ビルドタスクは設計上、多くのリソースや時間を消費しないため、このインフラストラクチャ サイトはほとんどの時間アイドル状態になります。

マルチアーキテクチャ コンテナ イメージを構築する

3 番目の戦略では、次の図に示すように、汎用パイプラインを使用して、マルチアーキテクチャ コンテナ イメージを構築します。

ソースコード リポジトリから汎用マルチアーキテクチャ パイプラインへのパスを構築。

ビルドごとに次の操作を行います。

  1. コンテナ イメージのソースコードをダウンロードします。
  2. コンテナ イメージをビルドします。
  3. コンテナ イメージを一元管理されたコンテナ イメージ リポジトリに保存します。
  4. そのイメージの新しいインスタンスをデプロイする必要がある場合は、ランタイム環境で各デバイスにコンテナ イメージをダウンロードします。

この戦略の主な利点は、専用のハードウェアやツールをプロビジョニングして維持する必要がないことです。たとえば、既存の継続的インテグレーション / 継続的デプロイ(CI / CD)パイプラインとツールを使用して、マルチアーキテクチャ コンテナ イメージをビルドできます。エネルギー効率の高いハードウェア アーキテクチャ(ARM ファミリーなど)と比べて、パフォーマンスが高い汎用ハードウェア アーキテクチャ( x86_64 など)を使用することによるメリットもあります。

この戦略は、DevOps の原則を採用する、広範な取り組みの一環ともなります。たとえば、特殊なハードウェア用の CI / CD パイプラインを実装できます。

マルチアーキテクチャ コンテナ イメージを構築するためのパイプラインを実装する

このセクションでは、3 つ目の戦略であるマルチアーキテクチャ コンテナ イメージの構築に従う CI / CD パイプラインのリファレンス実装について説明します。

リファレンス実装には次のコンポーネントがあります。

  • コンテナ イメージのソースコードを管理するソースコード リポジトリ。たとえば、Cloud Source RepositoriesGitLab リポジトリを使用できます。
  • Cloud Build などのコンテナ イメージを構築する CI / CD ランタイム環境。
  • コンテナとコンテナ イメージを管理するプラットフォーム。Docker などのマルチアーキテクチャ コンテナ イメージをサポートします。
  • Container Registry などのコンテナ イメージ レジストリ。イメージを必要とするノードの近くにコンテナ イメージを保存する場合は、コンテナ イメージ レジストリ(Docker Registry など)を現在の環境で実行できます。

このレファレンス アーキテクチャは、Moby BuildKitQEMU を使用し、マルチアーキテクチャ Docker コンテナ イメージを構築します。このケースでは、Moby BuildKit は、QEMU ハードウェア エミュレーションにより利用可能なアーキテクチャを自動的に検出し、Linux カーネルbinfmt_misc 機能に登録された適切なバイナリを自動的に読み込みます。

次の図は、このリファレンス アーキテクチャでサポートされる各マルチアーキテクチャ コンテナ イメージビルドを担うテクニカル スタックを示しています。

このマルチアーキテクチャのリファレンス アーキテクチャに関連するコンポーネント。

このリファレンス アーキテクチャでは Docker イメージ マニフェストを使用するため、ターゲット ハードウェア アーキテクチャごとにコンテナ イメージタグを指定する必要はありません。複数のアーキテクチャで同じタグを使用できます。たとえば、マルチ アーキテクチャ コンテナ イメージの 1.0.0 バージョンを作成する場合、ハードウェア アーキテクチャごとに一意のタグ(1.0.0-x86_641.0.0_ARMv7 など)は必要ありません。構築するすべてのハードウェア アーキテクチャで同じ 1.0.0 タグを使用し、Docker イメージ マニフェストを使用して各コンテナ イメージを正しく識別します。

次の例では、公式の Alpine Linux イメージのイメージ マニフェストを示しています。ここには、そのコンテナ イメージの特定バージョンがサポートするアーキテクチャの情報が示されています。

{
   "schemaVersion": 2,
   "mediaType": "application/vnd.docker.distribution.manifest.list.v2+json",
   "manifests": [
      {
         "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
         "size": 528,
         "digest": "sha256:ddba4d27a7ffc3f86dd6c2f92041af252a1f23a8e742c90e6e1297bfa1bc0c45",
         "platform": {
            "architecture": "amd64",
            "os": "linux"
         }
      },
      {
         "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
         "size": 528,
         "digest": "sha256:401f030aa35e86bafd31c6cc292b01659cbde72d77e8c24737bd63283837f02c",
         "platform": {
            "architecture": "arm",
            "os": "linux",
            "variant": "v7"
         }
      },
      {
         "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
         "size": 528,
         "digest": "sha256:2c26a655f6e38294e859edac46230210bbed3591d6ff57060b8671cda09756d4",
         "platform": {
            "architecture": "arm64",
            "os": "linux"
         }
      }
   ]
}

コンテナ イメージを構築するための自動化されたパイプラインを設計する場合は、各コンテナ イメージの要件を満たしているかどうかを検証する包括的なテストスイートを組み込むことをおすすめします。たとえば、Chef InSpecServerspecRSpec などのツールを使用して、ビルド パイプラインのタスクの 1 つとしてコンテナ イメージに対するコンプライアンス テスト スイートを実行できます。

コンテナ イメージを構築するためのパイプラインを最適化する

コンテナ イメージを構築するためのパイプラインを検証して統合してから、パイプラインを最適化します。Google Cloud への移行: 環境の最適化には、環境の最適化に関するガイダンスが記載されています。現在の環境の状態より効率を良くために採用できる最適化フレームワークについて説明しています。最適化フレームワークに沿って、イテレーションを繰り返して環境の状態を変えます。

各最適化イテレーションの最初のタスクの 1 つは、その一連のイテレーションの要件と目標の確立です。たとえば、デプロイ プロセスをモダナイズし、手動デプロイ プロセスから完全に自動化されたコンテナ化プロセスに移行するという要件の 1 つがあります。デプロイ プロセスのモダナイゼーションの詳細については、Google Cloud への移行: 手動デプロイから自動かつコンテナ化されたデプロイへの移行をご覧ください。

次のステップ