Artifact Registry アセットをサーバーレスで組織やプロジェクト間にわたりリリースする
Guillermo Noriega
Infrastructure Cloud Consultant
Vipul Raja
Infrastructure Cloud Consultant
※この投稿は米国時間 2024 年 5 月 21 日に、Google Cloud blog に投稿されたものの抄訳です。
Artifact Registry や Container Registry の画像を、さまざまなプロジェクトや組織の間で自動的にコピーする方法があればいいと考えたことはありませんか。この記事では、Google Cloud のサーバーレス コンポーネントを使用してこの操作を行うための専用プロセスと、Infrastructure as Code(IaC)へのデプロイ方法について説明します。
この記事では、Python のコーディングの知識と、ターミナルでコマンドを実行する方法についての基本的な理解、および Hashicorp Configuration Language(HCL)すなわち Terraform for IaC の知識を前提としています。
このユースケースでは、最低 1 つのコンテナ イメージが Artifact Registry リポジトリに存在し、頻繁に更新され、組織間で更新を外部の Artifact Registry リポジトリに伝播する必要があります。イメージは外部の組織にリリースされますが、依然としてプライベートで、公共からの使用はできないようにします。
この方法がどのように動作するかを明確に示すため、最初にアーキテクチャの個別のコンポーネントを取り上げてから、互いに結び付けることにしましょう。
以前に解説したように、該当する Artifact Registry(AR)リポジトリは 2 つあります。わかりやすくするため、以下ではこれらを「ソース AR」(イメージが定期的にビルドされ更新される AR で、信用できる情報源)と、「ターゲット AR」(別の組織やプロジェクトにあり、イメージが使用され、定期的に伝搬される必要がある AR)と呼ぶことにしましょう。アーキテクチャの次のコンポーネントは Cloud Pub/Sub です。ソース プロジェクトには、ソース AR に加えられた更新を自動的にキャプチャしてくれる Artifact Registry Pub/Sub トピックが必要です。Artifact Registry API が有効なとき、Artifact Registry はこの Pub/Sub トピックを自動的に作成します。このトピックは「gcr」と呼ばれ、Artifact Registry と Google Container Registry(使用されている場合)との間で共有されます。Artifact Registry は、トピックへの次の変更についてメッセージをパブリッシュします。
-
イメージがアップロードされた
-
新しいタグがイメージに追加された
-
イメージが削除された
トピックは自動的に作成されますが、そのトピックのメッセージを使用するには、Pub/Sub サブスクリプションを作成する必要があります。このためには、アーキテクチャの次のコンポーネントである Cloud Run が必要です。Cloud Run のデプロイを作成します。これは、次の動作を行います。
-
Pub/Sub メッセージの全体を解析する
-
メッセージの内容を比較し、ソース AR の変更からターゲット AR の更新が必要になるかどうかを検証する
-
検証の条件が満たされたら、Cloud Run サービスが最新の Docker イメージをターゲット AR に移動する
次に、Cloud Run が Pub/Sub AR トピックとどのように統合されるかを掘り下げましょう。Cloud Run が Pub/Sub メッセージを読み取れるようにするため、EventArc トリガーと Pub/Sub サブスクリプションという 2 つの追加コンポーネントがあります。EventArc トリガーは Cloud Run サービスをトリガーするもので、ワークフローにとって非常に重要です。
上述のコンポーネントに加えて、フローの全体が正しく動作するには以下の前提条件が満たされている必要があります。
-
Cloud SDK がユーザーのターミナルにインストールされており、gcloud コマンドを実行できる必要があります。
-
プロジェクトのサービス アカウント(SA)には、ソース AR の「読み取り」権限が必要です。
-
プロジェクトの SA には、ターゲット AR の「書き込み」権限が必要です。
-
VPC-SC 要件(有効な場合)
-
ジョブを実行している SA からターゲット リポジトリへの外向きアクセス許可
-
「make」コマンドを実行するアカウントの内向きアクセス許可(以下で説明します)と、Artifact Registry または Container Registry の「書き込み」権限
-
ソース リポジトリの Pub/Sub GCR トピックを読み取る内向きアクセス許可
-
[project-name]-sa@[project-name].iam.gserviceaccount.com に、Artifact Registry メソッドの VPC-SC 内向きアクセスを許可する
-
[project-name]-sa@[project-name].iam.gserviceaccount.com に、CloudRun メソッドの VPC-SC 内向きアクセスを許可する
-
var.gcp_project
-
Var.service_account
以下では、この方式を自分で実装するため必要な Python コード、Dockerfile、Terraform コードについて解説します。以下のセクションを読むとき、このソリューションのオープンソース コードがすべて含まれている GitHub リポジトリを開くことをおすすめします。リンクはこちらです。https://github.com/GoogleCloudPlatform/devrel-demos/tree/main/devops/inter-org-artifacts-release
Cloud Run にデプロイするのは、カスタムの Docker コンテナです。これは、次に示すファイルで構成されます。
-
App.py: このファイルには、ソースおよびターゲット コンテナの変数に加えて、Pub/Sub メッセージに基づいて実行がトリガーされる実行コードと、次の Python コードが含まれています。
-
Copy_image.py: このファイルには、イメージをソース AR からターゲット AR にコピーするため必要な gcrane コマンドを実行するために app.py が利用する copy コマンドが含まれています。
-
Dockerfile: このファイルには、gcrane をパッケージ化するため必要な手順と、Cloud Run イメージをビルドするために必要な要件が記載されています。
このアーキテクチャと関連付けられている個別のコンポーネントすべてについて説明したので、これらのコンポーネントを互いに結び付けるフローについて説明します。
エンジニアリング チームが、Docker イメージの新しいバージョンである「Image X」をリリース スケジュールに従いビルドしてリリースし、「latest」タグを追加したと想定します。この新しいバージョンはソース AR の中にあり、新しいバージョンが作成されるとき、AR Pub/Sub トピックは、「Image X」の新しいバージョンがソース AR に追加されたことを反映するようメッセージを更新します。これにより、EventArc トリガーが Cloud Run サービスを自動的に poke し、Pub/Sub サブスクリプションからメッセージをスクレイピングします。
Google の Cloud Run サービスは、App.py イメージに書き込まれているロジックを使用して、ソース AR で起きたアクションが指定された基準(Image X で「latest」タグがある)と一致しているかどうかをチェックします。アクションが一致し、ダウンストリームのアクションが必要なら、Cloud Run は Copy_image.py をトリガーして gcrane コマンドを実行し、ソース AR からターゲット AR へイメージ名とタグをコピーします。
イメージやタグが App.py で指定された基準と一致しない場合(たとえば、イメージ Y のタグが latest である)、Cloud Run のプロセスから HTTP 200 の応答と、「The source AR updates were not made to the [Image X]. No image will be updated.」というメッセージが返され、アクションが行われなかったことを確認します。
注: ソース AR には複数のイメージが含まれている可能性がありますが、ここで重要なのはターゲット AR 内の特定のイメージの更新だけなので、出力応答は Cloud Run サービスに統合して、トラブルシューティングや問題の診断の目的で Google Cloud ログ内で表示できるようにしています。これにより、目的のイメージに属さないイメージが意図せずにパブリッシュされることも防がれます。
別の方式を使用しない理由
-
汎用性: ソースとターゲットの AR が別の組織に存在していた
-
互換性: アーティファクトが Cloud Build のようなソリューションと互換性がある Code / Git リポジトリに存在していなかった
-
セキュリティ: クラウドネイティブのサーバーレス オプションを使用するときに活用できるツールが VPC-SC 境界によって制限されている
-
不変性: Infrastructure as Code とともに完全にデプロイ可能なソリューションにするため
-
スケーラビリティとポータビリティ: 複数の組織に存在するいくつもの Artifact Registry を同時に更新できるようにするため
-
効率性と自動化: リソースが移動されないときは時間ベースの pull メソッドを避ける。整合性を保証するため人手の介入を回避します。
-
クラウド ネイティブ: CI / CD パイプラインや Google Cloud 環境の外部のリポジトリなど、サードパーティ製のツールやソリューションへの依存を軽減する
すべての場所からのイメージが送られてくるアップストリームのプロジェクトが同じ Google Cloud リージョンまたはマルチリージョンに存在する場合、仮想リポジトリが問題解決に向けた優れた代替選択肢です。
IaC でデプロイする方法
-
この問題を解決するために使用した Terraform コードを用意しました。
-
コードでは次の変数が使用されます。これらの変数は置き換えるか、.tfvars ファイル内で宣言し、プロジェクトごとに固有の値を割り当てる必要があります。
-
var.gcp_project
-
Var.service_account
結論として、組織間にわたってアーティファクトをリリースするプロセスをブートストラップする方法はいくつかあります。どの方法にも長所と短所があるため、自分のユースケースを評価して最適な方法を決定してください。ここで考慮すべきことは、アーティファクトを Git リポジトリ内に置くことができるか、ターゲット リポジトリが同じ組織と子組織のどちらに存在するのか、CI / CD ツールが望まれるかどうかです。
ここまで読み進めてきたなら、このソリューションに適切なユースケースがあると思います。このパターンは、他の同様なユースケースにも使用できます。最初に参照すべきいくつかの例を紹介します。
-
他のタイプのアーティファクトを、Kubeflow Pipeline Templates(KFP)などの AR リポジトリからコピーする
-
VPC-SC の背後のバケット オブジェクトをプロジェクトや組織の間でコピーする
その他のリソース
-
ソリューション コードは以下のリンク先をご覧ください。https://github.com/GoogleCloudPlatform/devrel-demos/tree/main/devops/inter-org-artifacts-release
-
GCrane: https://github.com/google/go-containerregistry/blob/main/cmd/gcrane/README.md
-
Pub/Sub GCR 通知の構成: https://cloud.google.com/artifact-registry/docs/configure-notifications