0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【GCP】DockerイメージをCloudBuild でbuild してCloudRun にdeploy する

Posted at

はじめに

Streamlit のサービスをCloudRunにデプロイするCI/CDを作ろう、と思ったら大変でした。
最初はGithub Actions で頑張ったのですがハマってしまい、結局、CloudBuild で実現しました。

Gemini先生がたくさん教えてくれたのですが、それでも肝心なところはうまくいきませんでした。主に権限の設定あたりです。メモを残しておきます。

内容

何をするか

まず最初にできたこと

  • ターミナルから docker build, docker push で Google Cloud のArtifact Registry に push すること。
  • ターミナルから cloudbuild.yaml を gcloud submit で指定して build/push する
  • gcloud deploy run で Cloud run にdeploy する。
  • github repository にpush すると cloudbuild で docker build/push し CloudRun に deploy する。

必要だったことは、Artifact Registryと service account の両方に権限の設定です。

  • Artifact Registgry の作成
  • そのArtifact Registryにサービスアカウントへアクセス権を与えること。
  • サービスアカウントに Artifact への書き込み権限を与えること

ファイル構成

同じディレクトリに全てを置いてあります。

tree .
.
├── Dockerfile
├── app.py
├── cloudbuild.yaml
├── compose.yaml
├── pages
│   ├── 1_something.py
│   └── 2_foo.py
└── requirements.txt

Docker関係

pip のときroot だと警告が出たので、仮想環境で実行するようにしています。

FROM python:3.12-slim

WORKDIR /app

COPY requirements.txt .
RUN bash -c "python3 -m venv .venv && source .venv/bin/activate && \
    pip install --upgrade pip && \
    pip install -r requirements.txt"

COPY app.py .
COPY pages/*.py /app/pages/

EXPOSE 8501
CMD [".venv/bin/streamlit", "run", "app.py", "--server.port=8501"]

ここでdocker build/ run は下記のコマンドで実行できます。

docker build --no-cache -t streamlit-app .
docker run -rm -p 8501:8501 --name my-streamlit-app streamlit-app:latest

これをまとめて管理するために、compose.yaml を書くこともできます。

compose.yaml
version: "3.9"

services:
  streamlit-app:  # service name
    build:
      context: .  # Dockerfile directory
      dockerfile: Dockerfile
      no_cache: true  # (docker build --no-cache)
    ports:
      - "8501:8501"  # port(host):port(container)
    container_name: my-streamlit-app  # container name (docker run --name)
    image: streamlit-app:latest  # image name:tag (docker build -t)

ターミナルで書きコマンドでdocker build/run できます。もちろん、build, up

docker compose up -d --build

Google Cloudでのアカウント

ターミナルで認証を通します。

gcloud auth login

今のconfiguration について調べます。

$ gcloud config configurations list
NAME     IS_ACTIVE  ACCOUNT              PROJECT         COMPUTE_DEFAULT_ZONE  COMPUTE_DEFAULT_REGION
default  True       myname012@gmail.com  my-project
$ gcloud config list
[core]
account = myname012@gmail.com
disable_usage_reporting = True
project = my-project

Your active configuration is: [default]

サービスアカウントの設定

登録しているサービスアカウントの調べてみます。デフォルトのサービスアカウントは下記のようです。

$ gcloud builds get-default-service-account
name: projects/my-cloud-run01/locations/global/defaultServiceAccount
serviceAccountEmail: projects/639188470809/serviceAccounts/012345678901-compute@developer.gserviceaccount.com

このアカウントをCI/CDに使っても良いのですが、別のものを用意することにします。
サービスアカウントの作成は、CUIでもブラウザ(console)からでも実行可能です。

Cloud Build のデフォルトのサービスアカウントの確認

$ gcloud projects describe my-project --format="value(serviceAccounts.email)"

プロジェクトに登録されているサービスアカウントは下記で確認できます。

gcloud iam service-accounts list --project=my-project

Cloud Buildのアカウントを作る。

$ gcloud iam service-accounts create cloudbuild --display-name="Cloud Build service account" --project=my-project
Created service account [cloudbuild].

Artifact Registry の作成

名前が app01 であるArtifact Registry が存在するか確認します。Region は東京にしています。
hogeが今回pushする予定のregistry です。

$ gcloud artifacts repositories list --location=asia-northeast1
Listing items under project my-project, location asia-northeast1.

                                                                                 ARTIFACT_REGISTRY
REPOSITORY               FORMAT  MODE                 DESCRIPTION                   LOCATION         LABELS  ENCRYPTION          CREATE_TIME          UPDATE_TIME          SIZE (MB)
cloud-run-source-deploy  DOCKER  STANDARD_REPOSITORY  Cloud Run Source Deployments  asia-northeast1          Google-managed key  2025-02-07T13:56:33  2025-02-07T13:58:13  210.468
hoge                     DOCKER  STANDARD_REPOSITORY  test                          asia-northeast1          Google-managed key  2025-02-07T14:59:03  2025-02-17T23:40:48  3941.308

もしリポジトリが存在しない場合は、作成する必要があります。作成はconsoleからもできます。

gcloud artifacts repositories create hoge \
    --repository-format=docker \
    --location=asia-northeast1
    --description="foo bar" \
    --immutable-tags \
    --async

imutable-tags のオプションがあると、push されているイメージのタグと同じになるイメージはpush できなくなります。
例えばlatest やv1.0 のように同じtag のモノをpush しようとするとエラーになりました。

あと、大事なのはこのレジストリへの書き込み権限を使用するサービスアカウントに与えることです。

Artifact Registryへのpush (docker コマンド)

DockerのGoogle Cloudとの間でのcredential で意味は理解できていません。が設定が必要です。

docker-credential-gcr ヘルパーがインストールされていなければインストールします。

gcloud components install docker-credential-gcr

良く分かりませんが、下記を実行します。

docker-credential-gcr configure-docker
/home/xt/.docker/config.json configured to use this credential helper for GCR registries

そしてdocker registry に push します。

docker push asia-northeast1-docker.pkg.dev/my-project/hoge/app:tagtag

Artifact Registryへのpush (CloudBuildを利用)

Google Cloud のサービスであるCloud Buildを用いて同じことを行います。
内容をcloudbuild.yaml に書きます。

cloudbuild.yaml
steps:
  - name: 'gcr.io/cloud-builders/docker'
    args: ['build', '-t', 'asia-northeast1-docker.pkg.dev/${PROJECT_ID}/foo1/my-python-app:${COMMIT_SHA}', '.']

  - name: 'gcr.io/cloud-builders/docker'
    args: ['push', 'asia-northeast1-docker.pkg.dev/${PROJECT_ID}/foo1/my-python-app:${COMMIT_SHA}']

  - name: 'gcr.io/cloud-builders/gcloud'
    entrypoint: 'gcloud'
    args: ['run', 'deploy', 'myapp',
            '--image', 'asia-northeast1-docker.pkg.dev/${PROJECT_ID}/foo1/my-python-app:${COMMIT_SHA}', 
            '--region', 'asia-northeast1',
            '--platform', 'managed',
            '--port', '8501',
            '--memory', '1G',
            '--max-instances', '3']

options:
  defaultLogsBucketBehavior: REGIONAL_USER_OWNED_BUCKET
serviceAccount: my_cicd@my-cloud-run01.iam.gserviceaccount.com

環境変数PROJECT_IDはGoogle Cloud 1での project IDであり、COMMIT_SHA は git repository でのcommit の番号で、実行時に代入されます。

option で指定しているのはCloud Build を実行するサービスアカウントで、ターミナルで実行するときはサービスアカウントを指定する必要があります。ただし、指定が無ければdefault のサービスアカウントが使われるそうです。

下記でbuild + push ができました。

gcloud builds submit --config cloudbuild.yaml \
   --service-account projects/my-project/serviceAccounts/github-delivery@my-project.iam.gserviceaccount.com \
   --substitutions COMMIT_SHA=$(git rev-parse HEAD) .

Artifact Registry にあるdocker image の管理

ブラウザ(google cloud console)からいろいろできます。
ターミナルからも操作可能で、Registryにあるimage は下記コマンドで見れました。

$ gcloud artifacts docker images list asia-northeast1-docker.pkg.dev/PROJECT_ID/REPOSITORY_NAME/ --project=my-project

Artifact Registry に利用できる地域を表示します。

gcloud artifacts locations list

例えば今のcommit に対応するimage をregistry から削除するには下記でできました。

gcloud artifacts docker images delete asia-northeast1-docker.pkg.dev/PROJECT_ID/REPOSITORY_NAME/APP:$(git rev-parse HEAD) --quiet

Github 経由のCICD

ブラウザ画面の設定でできます。

まとめ

とりあえずGithub から Docker container を CloudRunにCI/CDの環境は作れました。Cloud側のIAMの設定でかなりはまりましたが、Artifact へのアクセス権さえうまく管理できれば、あとはgeminiさんの言う通りにすれば大丈夫だと思います。

折をみて文章を修正しようと思いますが、とりあえず今はこのあたりで。。
(2025/2/20)

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?