Google Cloud Platform IT

CloudBuildでArtifact Registryにイメージをプッシュする

2023年5月1日

gcp

Cloud Build

Cloud Build → Artifact Registry
https://cloud.google.com/build/docs/building/store-artifacts-in-artifact-registry?hl=ja
dockerfileでのビルドだとできなそうだったけど、以下の記事でできるっぽい
https://cloud.google.com/build/docs/build-push-docker-image?hl=ja
https://cloud.google.com/free/docs/aws-azure-gcp-service-comparison?hl=ja

Cloud Buildによる自動化テストの実施

▼ Cloud Buildでのテスト
source repositoriesはあくまでコードのバージョン管理でgithubに近い。
cloud buildはgithub actionに近い。CI/CDツール。
cloud buildはテスト実行が可能?
https://qiita.com/k-tky/items/91c67ed43710f8a3e1fd
テストをするにはcloudbuild.yamlファイルで引数などを指定しないといけない?dockerfileとかではダメ?

https://medium.com/@dictav/cloud-build-%E3%81%A8-docker-%E3%81%A7%E3%83%93%E3%83%AB%E3%83%89%E3%82%92%E8%87%AA%E5%8B%95%E5%8C%96%E3%81%99%E3%82%8B-142cd7b5eae9
ここにある通り、やっぱビルドまでであればdockerfile、cloudbuild.yamlのどちらかで良いが、テスト自動化するなら、cloudbuild.yamlを作らないとダメらしいね。

cloudbuild.yamlファイルでは、
① step: ビルド
② step: arfifactへのpush
という処理でcloudbuild.yamlを記載する。

ん?ビルドまでとは言いつつもビルドだけするメリットってあるんだっけ?
ビルドすることで、どこかにcloud runとかに直接作成ができるんだっけ?
ビルドしてイメージを一旦保存することができるのがartifactでそこからもデプロイできるけど、ビルドだけだとデプロイはできる?

Artifact registryの説明

https://cloud.google.com/artifact-registry?hl=ja
Container Registry の進化形である Artifact Registry は、組織がコンテナ イメージと言語パッケージ(Maven や NPM など)を 1 か所で管理できる場所になりました。これは Google Cloud のツールとランタイムと完全に統合されており、ネイティブのアーティファクト プロトコルのサポートが付属します。これにより、CI / CD ツールと簡単に統合して自動化パイプラインを設定できるようになりました。
(mavenって懐かしいなw)
dockerイメージとかをここに格納して
cloud functions
kubernetes
Cloud run
app engine
compute engine
にデプロイする

Artifact registryでは、

▼ googleコメント(Cloud IAMの後ろにあるので、リポジトリごとに制御が可能になるって感じやな。)
Artifact Registry では、Cloud IAM を通した、きめ細かいアクセス制御を行っています。 そのため、Container Registry とは違い、プロジェクトにすべてのイメージを保存するのではなく、リポジトリごとのアクセス制御が可能

検証

dockerfileではartifactまではプッシュはできないらしい。
でもcloudbuild.yamlではそれが可能。

https://github.com/yoshida-1992/test-cloud-build

イメージはcloud storageに保存することもできますし、
artifact registryに保存することも可能です。
プッシュ先をどっちに指定するかによります。

cloudbuild.yamlの中で
${PROJECT_ID}などとありますが、
これはビルドした瞬間に自動的にGCPが値を入れてくれる機能です。
使える変数は以下でまとまってますので、ぜひご参照ください。
リンク

 

以下の手順で検証してみます!

  • ① GCPのCloud Buildにてトリガー設定を行う。
  • ② Githubのリポジトリにプログラムをpush
  • ③ プッシュしてそれをCloud Buildがトリガー検知して処理を実行する(ビルド)
  • ④ Artifact Repositoryにイメージをプッシュする
  • ⑤ 仮想的に簡単な自動化テスト(CI/CD)を行い、console.logでcloud loggingにて処理が実行できているかを確認する
  • ⑥ Cloud Runにてイメージを適用して、デプロイする

自分なりにCI/CDツールがどんなものなのか知りたかったので、一旦自動化テストも含めた検証をしてみます!

 

以下の手順で検証してみます!

① GCPのCloud Buildにてトリガー設定を行う。

まず今回検証したいGithubリポジトリを作成します。
そして、そのリポジトリをCloud Buildにてトリガー設定しましょう。
このトリガー設定をすることによって、対象のリポジトリにプッシュされたとき(変更がされたとき。Github内で直にコードを変更してもそれはプッシュとみなされるので。)に、それをCloud Buildが検知をしてトリガー処理を実施するような構成のイメージです。

 

② Githubのリポジトリにプログラムをpush

今回は以下のようなファイル構成をローカルに用意しました。
この状態でローカルからgitでプッシュをしてみます。

 

そうすると実際にプッシュがされて、Cloud Buildにてトリガー検知していることがわかりました。
もしエラーの場合は、トリガーの履歴にて赤字で表示されるのですぐわかります。

 

③ プッシュしてそれをCloud Buildがトリガー検知して処理を実行する(ビルド)

そうすると実際にプッシュがされて、Cloud Buildにてトリガー検知していることがわかりました。
もしエラーの場合は、トリガーの履歴にて赤字で表示されるのですぐわかります。

 

④ Artifact Repositoryにイメージをプッシュする

そして先ほどの処理が成功するとArtifact Registryにイメージがプッシュされていることがわかります。

実はここで注意点。
Dockerfileが設定ファイルとしてしまうと、ビルドしかせず、Artifact Registryへはプッシュは行われません。
cloudbuild.yamlを設定ファイルとして実行する必要があります。
なのでデフォルトでこのcloudbuild.yamlを使うのが良いのではと思ってます!(全然初心者なので皆さん教えてください!)

 

⑤ 仮想的に簡単な自動化テスト(CI/CD)を行い、console.logでcloud loggingにて処理が実行できているかを確認する

これは自分がCI/CDツールがどんなものなのかあまり知ら図、CloudBuildにはそのような機能がついているので、ぜひ検証してみたかったのでやってみます!
テストをするにあたって、テスト実行ファイルに渡すデータは以下として、実際に処理が回るかどうか検証してみます。

今回はconsole.logでテストで渡した値を計算して吐き出す処理です。
cloud loggingにて値が問題なく表示されていればOKです!

cloudbuild.yamlで
["compute", "engine]
というコマンドの書き方は、
なんていうんだっけ?
EXEC形式っていうらしいな。
shell形式ではない。

DockerfileのCMDとENTRYPOINTを読み解く(1/3) — Shell形式とExec形式とは何か #docker #dockerfile

dockerfileのfromではOS名:バージョンを指定。
from centos:7
はcentosでバージョンは7を指定ということ。

cloudbuild.yamlの書き方

https://cloud.google.com/build/docs/build-config-file-schema?hl=ja

https://cloud.google.com/build/docs/build-push-docker-image?hl=ja
これみる限り、dockerfileでイメージ作成して、artifact registryにpushできるっぽい。コマンドで。
でもやっぱプッシュするにはビルド構成ファイルであるcloudbuild.yamlが必要らしい。dockerfileだけではダメ。

cloudbuild.yaml

今回は以下のようなcloudbuild.yamlを作成しました。

steps:
  # Docker Build
  - id: "create docker image"
    name: 'gcr.io/cloud-builders/docker'
    args: ['build', '-t', 'asia-northeast1-docker.pkg.dev/${PROJECT_ID}/test-repository/test-docker-image:$COMMIT_SHA', '.'] 

  - id: "push image artifact registry"
  # Arfifact Registryにイメージをpush
    name: 'gcr.io/cloud-builders/docker'
    #args: ['push', 'us-central1-docker.pkg.dev/${PROJECT_ID}/my-docker-repo/myimage']
    args: ['push', 'asia-northeast1-docker.pkg.dev/${PROJECT_ID}/test-repository/test-docker-image:$COMMIT_SHA']

  - id: "create compute engine"
  # Arfifact Registryにpushされたイメージから、compute engineを生成
    name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'
    entrypoint: 'gcloud'
    args: ['compute', 'instances', 'create-with-container', 'compute-engine-from-cloudbuild', '--container-image',  'asia-northeast1-docker.pkg.dev/${PROJECT_ID}/test-repository/test-docker-image:$COMMIT_SHA']
    env:
      - 'CLOUDSDK_COMPUTE_REGION=us-central1'
      - 'CLOUDSDK_COMPUTE_ZONE=us-central1-a'

stepはいわゆる処理の話で、1個ずつ説明をしていきます。

 

Step1: Create Docker Image

step:
 - name: "コンテナイメージ"

nameではGoogleが用意してるコンテナイメージを指定します。
これはこのstepでどんなコマンドを使用したいかなどに関わる話です。コンテナのイメージということなのでdockerを読み込んだり、gcloudを読み込んだりと色々あります。
nameでdockerを読み込めば、このステップではdockerコマンドを用いて何か処理をしたり、gcloudを読み込めばこのステップではgcloudコマンドを用いて何か処理したりなどができます。

- name: 'gcr.io/cloud-builders/docker'
とあれば、gcr.io/cloud-builders/にあるdockerというコンテナイメージを読み込ませます。これによりdockerコマンドが使えるようになります。
ではこのステップでどのようにしてdockerコマンドを使うのでしょうか。
それは
- argsというところで使用します。argsは実行したいコマンドを配列形式で指定します。これはshell形式ではなくEXEC形式と呼ばれる指定方法です。
例えば、dockerコマンドで
docker build -t ...
を実行したいのであれば、nameでdockerを読み込みつつ、
argsでは["build", "-t", ".."]
と記載することで、このステップではdocker build -t ..を実行処理するということになります。

これにより、docker buildつまりdockerfileによってdockerをビルドしてイメージを作成するわけですが、この作成したイメージをどこに置くかを指定し、そこにイメージが置かれます。

 

Step2: push image artifact registry

そして2つ目のステップですね。

- name: 'gcr.io/cloud-builders/docker'
  args: ['push', 'us-central1-docker.pkg.dev/${PROJECT_ID}/my-docker-repo/myimage']

またdockerを読み込んでいるので、dockerコマンドを使います。
そして、docker push us-central1-docker.pkg.dev/${PROJECT_ID}/my-docker-repo/myimage
を実行することになり、
先ほどイメージを置いたところを指定しつつ、artifact registryにpushしていることがわかります。
https://cloud.google.com/artifact-registry/docs/docker/store-docker-container-images?hl=ja

 

Step3: create compute engine

最後3つ目!

- name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'
  entrypoint: 'gcloud'
  args: ['compute', 'instances', 'create-with-container', 'my-vm-name', '--container-image', 'us-central1-docker.pkg.dev/${PROJECT_ID}/my-docker-repo/myimage']

nameにはcloud-sdkと指定してるので、今回はgcloudコマンドを使う想定です。
これにより、argsでは
gcloud compute instances create-with-container my-vm-name --container-image us-central1-docker.pkg.dev/${PROJECT_ID}/my-docker-repo/myimage
を実行すると読むことができます。

これにより、このコマンドを実行すると、
artifact registryにpushしたイメージを用いて、Compute Engineを作成する
ことになります。

dockerにはtagという概念があり、大体はバージョンなどを示すためにつけることが多いです。
tagをつけない場合はデフォルトで、latestという文字がつくようになってます。
今回は$commit_hashを指定しているので、毎回ハッシュ値が入るようになってます。

 

このcloudbuild.yamlファイルによって、
以下のようなstepでビルドからデプロイまでを一気通貫で処理ができるようになりました。

【step概要】

  • ① dockerコマンドでビルドしイメージ作成
  • ② 作成したイメージをartifact registryにpushする
  • ③ artifact registryにあるイメージを用いて、gcloudコマンドでcompute engineを生成

以下のようなエラーが表示されました。

'compute.instances.create' permission for 'projects/yoshida-labo/zones/asia-northeast1-a/instances/compute-engine-from-cloudbuild'

これは、Cloud BuildにはデフォルトでCloud Build用のサービスアカウントが設定されており、そこにはCompute Engineでインスタンスを作成する権限がついていないからです。
Cloud BuildによってArtifact Registryにあるイメージを用いてCompute Engineのインスタンスを作成するので、Cloud BuildからCompute Engineを作成する権限が必要になるということです。
Cloud Buildサービスアカウント

 

Cloud Buildの画面で、左側の設定のところから以下のようなCloud Buildのサービスアカウントの権限設定ができるので、以下のところで必要な権限の付与をします。
今回はCompute Engineへの権限を付与するので、Compute Engineの権限を有効にします。

 

CloudBuildの設定で、管理画面にてcloudbuild.yamlにて代入したい変数を設定することができます。
画面にてキーをAPI_MASTER_KEYとして、値を12345とした時、
cloudbuild.yamlにてこの値を使うためには、$API_MASTER_KEYでアクセスすることができます。

 

Artifct

container registryはイメージを保存するところでした。
そして進化をしてartifact registryという名前になりました。今までcontainer registry自体へのアクセス制御はできましたが、レポジトリに対してのアクセス制限はできませんでした。
しかしartifact registryからはリポジトリ単位でアクセス権限をかけることができました。

-Google Cloud Platform, IT
-

© 2024 Yosshi Labo. Powered by AFFINGER5