Cloud BuildでDockerイメージをビルド

Google Cloud Buildは、CI/CDをホストするサービスです。
Artifact Registryと統合されており、GKEで動作させるdockerイメージをビルドする用途に適しています。また、ほかにもJavaビルドなどにも対応しています。

Cloud Buildは日ごとの無料枠を提供しているため、実験的な小規模ビルドであれば無料枠におさまるでしょう。 コスト面では長期運用した際にArtifact Registry側でかかるストレージコストを多少意識した方が良いでしょう。
実運用の際には旧世代のイメージを削除する操作がおそらく必要です。

また、docker buildコマンドをホストしているため、ビルド過程の大半はdockerのビルドプロセスと同じです。

用意するもの

  1. gcloudコマンド(Google Cloud SDK) & GCPアカウント
  2. dockerイメージビルド用リソース(Dockerfileなど、docker buildと同じもの)
  3. YAML形式のビルド設定ファイル

既存のdockerビルドリソースを移行する場合、YAML設定ファイルを追加作成するだけで利用開始できるケースも多くありそうです。

ビルド設定ファイル

dockerイメージをビルドするためのビルドステップの定義は、以下のような形式になります。

steps:
- name: 'gcr.io/cloud-builders/docker'
  args: ['build', '-t', 'pkg.dev/project-name/repo-name/image-name', '.']
images: ['pkg.dev/project-name/repo-name/image-name']

steps.nameはContainer Builderが実行するイメージです。dockerのビルドにはgcr.io/cloud-builders/dockerを用います。
steps.argsは、コマンドライン引数です。gcr.io/cloud-builders/dockerイメージがdockerコマンドを提供しているため、この例の組み合わせでは

docker build -t pkg.dev/project-name/repo-name/image-name .

がCloud Build上で実行されます。

Dockerfileなど.が指すリソースは、後述のgcloud buildsコマンドで転送します。

imagesはArtifact Registryにプッシュするイメージを指定します。この項に設定したイメージはGKEで実行可能です。また、asia-docker.pkg.devなどのpkg.devファミリーも指定可能です。

キャッシュを利用する

Cloud Buildはデフォルト指定ではDockerイメージビルドにキャッシュを利用せず、毎回すべてのレイヤを新規ビルドします。
キャッシュを利用するためには、--cache-fromオプションをargsに追加します。
詳細な書式は、公式ドキュメントの ビルドを高速化する際のおすすめの方法を参照してください。

キャッシュで注意すべき点として、初回ビルド時にはContainer Registryにキャッシュが存在していないためエラーになることです。少なくとも一度は--cache-fromオプションを指定せずにビルドしておく必要があります。

gcloud buildsコマンド

ビルド実行は、

$ gcloud builds submit ./ --config build-step.yaml

のようにgcloudコマンドで指定すると即開始します。

configオプションには先ほど作成したyamlファイルを指定します。
また、Dockerfileなどビルドに必要なリソースは、引数としてディレクトリを指定します。この例では、./のとおりカレントディレクトリに存在しているファイル一式を圧縮・転送します。

DockerfileのCOPYディレクティブなども、ここで転送したリソースを利用可能です。
転送除外したいファイルは .gcloudignoreファイルで指定できますが、転送したいリソースだけを単にサブディレクトリに整理しておく手もあります。

その他のオプションは 公式リファレンスを参照してください。

ビルド用サービスアカウントの必要権限

サービスアカウント向けの権限は人が操作する際に必要な権限と異なります。

CloudBuildを自動化する際のサービスアカウントは、「Cloud Buildサービスエージェント・Service Usageユーザー・ログ書き込み」の3種のロールを指定すると動作します。

公式ドキュメントの説明とは異なる点と、目的別のロールになっていない点には注意が必要です。
またロギングについては ビルドログの保存と管理に解説がありますが、サービスアカウントはデフォルトのログ出力先に書けない挙動となっているため、多くのシナリオでは追加の設定が必要でしょう。

比較的簡素な方法は、Cloud Loggingのみにログ出力する構成です(ビルド時オプション)。

GCPのIAMは一見無関係なエラーに見え、ドキュメントの記述が正確でなく、和訳がサービス表記と異なるため迷宮入りしがちです。
gcloud builds submit --verbose=debugオプションを指定すると具体的なエラー内容が出力されます。

ArtifactRegistryへのアクセス権

CloudBuildは同一プロジェクトのArtifactRegistryへのアクセス権は設定済みです。
他プロジェクトのレジストリにアクセスしたい場合には、そのプロジェクトのIAMに「ArtifactRegistry読み取り」などの適切な権限を追加する必要があります。

サービスアカウントのIDは、 Google Cloud サービスのデフォルトの権限にリストされているもののうち、[email protected]です。

PROJECT-NUMBERは普段使う機会がないため分かりづらいのですが、プロジェクトIDではなくクラウドコンソールのダッシュボードに記載されている数値です。
ArtifactRegistryにアクセスするのは、CloudBuildを呼び出したユーザーのアカウントでもないことに注意が必要です。

Docker Hubのミラー

Google Artifact Registryは Docker Hubの公式リポジトリをミラーしています。Cloud Buildから見てネットワークが近いというキャッシュのメリットのほか、長い目でみるとDocker Hubの継続性への疑問をヘッジする面でも有効と考えられます。

主要な公式イメージは、Docker Hubのlibraryに集められているため、以下のコマンドを実行することにより、mirror.gcr.io上のイメージ識別子を取得できます。

$ gcloud container images list --repository=mirror.gcr.io/library
中馬崇尋
Chuma Takahiro