GitHub Actions で Cloud Deploy 経由で Cloud Run をカナリアデプロイする
目標
GitHub Actions で Cloud Deploy 経由で Cloud Run をカナリアデプロイするための設定をまとめる。
今回の成果物は以下のレポジトリに格納されています。
Cloud Deploy
Cloud Run のマニフェストを作成する
今回は Nginx をデプロイするだけのシンプルなマニフェストを利用します。
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
name: sample
labels:
cloud.googleapis.com/location: asia-northeast1
spec:
template:
metadata:
annotations:
autoscaling.knative.dev/maxScale: '1'
run.googleapis.com/startup-cpu-boost: 'true'
spec:
containerConcurrency: 80
containers:
- name: nginx
image: nginx
ports:
- name: http1
containerPort: 80
resources:
limits:
cpu: 1000m
memory: 512Mi
startupProbe:
timeoutSeconds: 240
periodSeconds: 240
failureThreshold: 1
tcpSocket:
port: 80
Scaffold を定義する
全体
apiVersion: skaffold/v4beta7
kind: Config
metadata:
name: sample
deploy:
cloudrun: {}
profiles:
- name: dev
manifests:
rawYaml:
- service.yaml
詳細
Cloud Run のマニフェストとして利用するため以下の設定を追加します。
deploy:
cloudrun: {}
今回は環境は 1 つのみなので dev
という profile を作成しています。
dev
profile には対象の Cloud Run のマニフェストをレンダリングするように指定しています。
Cloud Deploy のパイプラインを定義する
全体
apiVersion: deploy.cloud.google.com/v1
kind: DeliveryPipeline
metadata:
name: cloud-run-cloud-deploy
description: Cloud Run with Cloud Deploy
serialPipeline:
stages:
- targetId: sample
profiles: [dev]
strategy:
canary:
runtimeConfig:
cloudRun:
automaticTrafficControl: true
canaryDeployment:
percentages: [5, 90]
verify: false
---
apiVersion: deploy.cloud.google.com/v1
kind: Target
metadata:
name: sample
run:
location: projects/tetsuya28-playground/locations/asia-northeast1
requireApproval: true # デプロイの承認を必要とする
詳細
Scaffold で作成した dev
profile を利用するステージを作成します。
このステージでは Cloud Run のリビジョンの更新にカナリアリリースを行うための設定を追加しています。
以下の設定では 5% → 90% → 100% の順番で新しいリビジョンに自動的にトラフィックが移っていきます。
serialPipeline:
stages:
- targetId: sample
profiles: [dev]
strategy:
canary:
runtimeConfig:
cloudRun:
automaticTrafficControl: true
canaryDeployment:
percentages: [5, 90]
verify: false
Cloud Run のデプロイ先を tetsuya28-playground
プロジェクトの asia-northeast1
( 東京 ) リージョンに指定します。
apiVersion: deploy.cloud.google.com/v1
kind: Target
metadata:
name: sample
run:
location: projects/tetsuya28-playground/locations/asia-northeast1
また、パイプラインの最初に承認を要求するために以下の設定を追加しています。
requireApproval: true # デプロイの承認を必要とする
GitHub Actions
ここまでの設定で Cloud Deploy の設定は完了したのでこれらを GitHub Actions で実行するための構成について整理します。
Pipeline
Cloud Deploy の pipeline 自体を変更した場合に GitHub Actions で pipeline を更新します。
GitHub Actions から Google Cloud への認証は既に完了していることを前提としています。
OIDC を利用した認証の仕組みは Google Cloud 公式でも紹介されています。
- uses: google-github-actions/setup-gcloud@v2
- run: |
gcloud deploy apply --file gcp/cloud-run/cloud-deploy.yaml --region asia-northeast1
Pipeline の更新はそのまま gcloud
コマンドを利用しています。
Deploy
設定した pipeline に対してリリースを行う際は Google Cloud が公式で提供している action を利用します。
リリース名はユニークにする必要があり、 63 文字までしか利用できないため sha short を利用します。
- name: Set short git commit SHA
run: |
calculatedSha=$(git rev-parse --short ${{ github.sha }})
echo "COMMIT_SHORT_SHA=$calculatedSha" >> $GITHUB_ENV
利用する pipeline の名前とリージョンと scaffold を指定します。
イメージの更新などもここで行う必要がありますが、今回は特に更新せずに nginx
コンテナに nginx
イメージを利用する設定を記載しています。
- uses: google-github-actions/create-cloud-deploy-release@v1
with:
name: ${{ inputs.called_by }}-${{ env.COMMIT_SHORT_SHA }}
delivery_pipeline: cloud-run-cloud-deploy
region: asia-northeast1
skaffold_file: gcp/cloud-run/scaffold.yaml
images: |
nginx=nginx
この状態で GitHub Actions を実行すると Cloud Deploy 上でリリースが作成されます。
承認
を実行することで実際にリリースが始まります。
以下はカナリアリリースの最初の 5% が実行されている状態です。
実際に Cloud Run では最新のリビジョンに 5% だけトラフィックが流れていることを確認できます。
最後に
Cloud Run へのデプロイに Cloud Deploy を利用する方法について試してみましたが、比較的直感的に組むことができ、少人数からの開発でも重宝しそうなサービスでした。
また Cloud Deploy はデフォルトで Four Keys[1] のメトリクスなども可視化してくれるは嬉しいですね。
今後はカナリアデプロイをさらに発展させたプログレッシブデプロイも Cloud Deploy で組んで実際のサービスへの導入も進めていきたいと思います。
Discussion