Google Cloud 入門:Cloud Deploy ハンズオン
概要
初めて Cloud Deploy を使う方向けに、Cloud Deploy の概念と使い方をまとめた。使い方では、Cloud Run サービスのデプロイに焦点をあて、以下の機能について説明した。
- Cloud Run サービスのデプロイ、ロールバック
- リリースの破棄
- カナリアリリース
Cloud Deploy とは
デリバリーパイプラインとデプロイターゲットを定義し、アプリケーションの配信を自動化するマネージドサービス。
デリバリーパイプラインによってリリースのライフサイクルを管理し、リリースを作成することで更新したアプリケーションをデプロイする。
Cloud Deployを使うことで様々なデプロイ手法を扱い易くできる。
- デリバリーパイプライン:各ターゲットにアプリケーションを配信するワークフロー。上図では配信順序が dev→stg→prod となる。
- ターゲット:アプリケーションをデプロイする特定のランタイム環境。Cloud Run 環境などがある。
- リリース:デプロイされる内容。Cloud Run YAMLファイルなど。
Cloud Run サービスをデプロイする
Cloud Deploy を使って Cloud Run サービスにデプロイするための流れを記載する(参考:Cloud Deploy を使用してアプリを Cloud Run にデプロイする)。
構築するデリバリーパイプラインとターゲットは、prod環境のみの構成とする。
用意するファイルは次のとおり。
.
├── clouddeploy.yaml
├── run-service-prod.yaml
└── skaffold.yaml
デリバリーパイプライン・デプロイターゲットの作成
デリバリーパイプラインとデプロイターゲットの定義を clouddeploy.yaml に記載する。
apiVersion: deploy.cloud.google.com/v1
kind: DeliveryPipeline
metadata:
# デリバリーパイプラインの名前
name: sample-delivery-pipeline
description: main application pipeline
serialPipeline:
stages:
- targetId: sample-target
profiles: [prod]
---
apiVersion: deploy.cloud.google.com/v1
kind: Target
metadata:
# ターゲットの名前
name: sample-target
description: Cloud Run production service
run:
location: projects/sample-project/locations/asia-northeast1
デリバリーパイプライン名を sample-delivery-pipeline
、ターゲット名を sample-target
としている。
gcloud deploy apply コマンドを実行すると、定義したデリバリーパイプラインとターゲットが作成される。
gcloud deploy apply --file=clouddeploy.yaml \
--region=asia-northeast1 \
--project=sample-project
Terraform を使う場合
Terraform を使ってデリバリーパイプラインとターゲットを作成する場合、google_clouddeploy_delivery_pipeline でデリバリーパイプラインを定義し、google_clouddeploy_target でターゲットを定義する。
resource "google_clouddeploy_delivery_pipeline" "default" {
location = "asia-northeast1"
name = "sample-delivery-pipeline"
description = "main application pipeline"
serial_pipeline {
stages {
profiles = ["prod"]
target_id = google_clouddeploy_target.default.target_id
}
}
}
resource "google_clouddeploy_target" "default" {
location = "asia-northeast1"
name = "sample-target"
description = "Cloud Run production service"
execution_configs {
# デプロイアーティファクトを格納するGCSバケット(デフォルトのパス)
artifact_storage = "gs://asia-northeast1.deploy-artifacts.sample-project.appspot.com"
execution_timeout = "3600s"
# デプロイを実行するサービスアカウント(デフォルトのサービスアカウント)
service_account = "sample-project-id-compute@developer.gserviceaccount.com"
usages = ["RENDER", "DEPLOY"]
}
run {
location = "projects/sample-project/locations/asia-northeast1"
}
}
リリースの作成
run-service-prod.yaml に Cloud Run の構成を定義する。
これは YAML を使って Cloud Run をデプロイする時に使うものと同じもの。
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
name: run-service-prod
spec:
template:
spec:
containers:
# my-app-imageは変数。リリース作成コマンド実行時に値を渡して解決する。
- image: my-app-image
次に、skaffold.yamlを作成する。
Cloud Deployは skaffold を使ってターゲットにデプロイするため、基本的にはこのファイルが必要になる。必要な記述はヘッダー、使用するマニフェストファイル(Cloud Runサービス定義YAMLのファイル名)、ターゲット環境である(参考:Cloud Deploy を機能させるには何が必要ですか?)。
apiVersion: skaffold/v4beta11
kind: Config
metadata:
name: deploy-run-quickstart
profiles:
- name: prod
manifests:
rawYaml:
- run-service-prod.yaml
deploy:
cloudrun: {}
apiVersion
は skaffold のレファレンスに記載されている Schema Versions の中から、使用するバージョンを選択する。
profiles.name
には、clouddeploy.yamlのprofiles
で指定した名前であるprod
を指定することで、sample-target
に run-service-prod.yaml
を適用している。
ここまででリリースを作成する準備が整った。
リリースを作成するには、gcloud deploy releases create コマンドを実行する。
gcloud deploy releases create sample-release-001 \
--delivery-pipeline=sample-delivery-pipeline \
--skaffold-file=skaffold.yaml \
--images my-app-image=gcr.io/cloudrun/hello:latest \
--project=sample-project \
--region=asia-northeast1
--delivery-pipeline
に先ほど作成したデリバリーパイプライン名を指定する。
--images
に my-app-image
変数の値として gcr.io/cloudrun/hello:latest
を指定しており、これは Cloud Run URLにアクセスした時にリビジョン名などを表示してくれるチュートリアル用のイメージ、
コマンド実行後しばらくすると、Cloud Run サービスとリリースが作成される。
作成されたCloud Run サービスのURLを叩くと以下のような楽しげな画面が表示され、動作していることが確認できる。
リリースの名称を変えて、再度リリース作成コマンドを実行する。
gcloud deploy releases create sample-release-002 \
--delivery-pipeline=sample-delivery-pipeline \
--skaffold-file=skaffold.yaml \
--images my-app-image=gcr.io/cloudrun/hello:latest \
--project=sample-project \
--region=asia-northeast1
実行すると、2個目のリリースと Cloud Runの新しいリビジョンが作成される。
Cloud RunのURLを叩くと、新しいリビジョンで動作していることが確認できる。
ロールバックする
リリースしたものに不具合が発覚した場合、前回の安定版に即座に戻すためにロールバックを行う。
gcloud deploy targets rollback コマンドを実行すると、前回のリリースをターゲットに反映することができる(参考:ターゲットのロールバック)。
gcloud deploy targets rollback sample-target \
--delivery-pipeline=sample-delivery-pipeline \
--region=asia-northeast1 \
--project=sample-project
実行すると、Cloud Run サービスの前回リビジョンにトラフィックが向けられており、Cloud Run URL にアクセスすると前回リビジョンが表示される。
ちなみに --release
でリリースを特定すると、前回よりも前のリリースにロールバックすることができる。
gcloud deploy targets rollback sample-target \
--delivery-pipeline=sample-delivery-pipeline \
--release=old-release \
--region=asia-northeast1 \
--project=sample-project
リリースを破棄する
一度作成したリリースは破棄することができる。リリースを破棄したいケースには次のようなものがある。
- リリースにバグがある
- リリースにセキュリティの問題がある
- リリースに含まれている機能が非推奨になった
リリースを破棄すると、そのリリースにはロールバックされないようにできる。
例えば、次のようにリリースが4つ作成されており、現在の状態が sample-release-004
で、sample-release-003
に問題が見つかったためこのリリースを破棄したいとする。
リリースを破棄するには、gcloud deploy releases abandon を実行する(参考:リリースを破棄する)。
gcloud deploy releases abandon sample-release-003 \
--delivery-pipeline=sample-delivery-pipeline \
--region=asia-northeast1
実行すると、sample-release-003
が放棄された。
この状態でsample-release-003
にロールバックしようとしても、破棄されているためロールバックできなくなっている。
gcloud deploy targets rollback sample-target \
--delivery-pipeline=sample-delivery-pipeline \
--release=sample-release-003 \
--region=asia-northeast1 \
--project=sample-project
ERROR: (gcloud.deploy.targets.rollback) Cannot perform rollback. Release projects/sample-project/locations/asia-northeast1/deliveryPipelines/sample-delivery-pipeline/releases/sample-release-003 is abandoned.
カナリアリリースする
カナリアリリースとは、すでにデプロイされているバージョンと新しいバージョンの間でトラフィックを分割するアプリケーションの段階的なロールアウトのこと。
これにより、アプリケーションの新しいバージョンをすべてのユーザーに配布する前に、そのバージョンの信頼性を確認できる。
Cloud Deploy を使ったカナリアリリースのやり方を下記に記載する。
デリバリーパイプライン・デプロイターゲットの作成
標準デプロイの時に使った clouddeploy.yaml のパイプラインステージの strategy プロパティを次のように変更する(参考:カナリアデプロイを構成する)。
serialPipeline:
stages:
- targetId: sample-target
profiles: [prod]
strategy:
canary:
runtimeConfig:
cloudRun:
automaticTrafficControl: true
canaryDeployment:
# カナリアの増分を表すパーセント値のカンマ区切りのリスト
percentages: [25, 50, 75]
verify: false
ここでは新バージョンへ流すトラフィック割合を、25% → 50% → 75% → 100% の順に増やしている(percentages
に100を含めない)。
gcloud deploy applyコマンドを実行して、カナリア構成をデリバリーパイプラインに反映する。
gcloud deploy apply --file=clouddeploy.yaml \
--project=sample-project \
--region=asia-northeast1
リリースの作成
標準デプロイの時に使った skaffold.yaml と Cloud Run YAML をそのまま使用できる。
(Cloud Run YAML はtraffic スタンザが使えないこと以外は通常の Cloud Run サービス定義ファイルと同じ)
gcloud deploy releases create コマンドを実行してリリースを作成する。
gcloud deploy releases create sample-release-005 \
--delivery-pipeline=sample-delivery-pipeline \
--skaffold-file=skaffold.yaml \
--images my-app-image=gcr.io/cloudrun/hello:latest \
--project=sample-project \
--region=asia-northeast1
コンソール画面でリリースの詳細を見ると、現在のロールアウトフェーズが canary-25 になっており、後続にcanary-50, canary-75, stableが控えていることが分かる。stableはトラフィック割合が100%を指す。
Cloud Runのリビジョンを確認すると、新バージョンのトラフィックは25%、前回バージョンは75%になっており、バージョン間でトラフィック分割されていることが分かる。
実際にCloud RunのURLに何度かアクセスすると、どちらかのバージョンが表示される動きになっている。
カナリアフェーズを進める
gcloud deploy rollouts advance コマンドでカナリアフェーズを進めることができる。
コマンド引数にロールアウト名を指定する。
gcloud deploy rollouts advance canary-release-001-to-sample-target-0001 \
--release=canary-release-001 \
--delivery-pipeline=sample-delivery-pipeline \
--region=asia-northeast1
実行するとロールアウトが canary-50 フェーズになり、トラフィック割合は前回リリースが50%、今回リリースが50%となる。
もう一度上記コマンドを実行すると canary-75フェーズになり、さらに実行すると stableフェーズとなり最新のリビジョンにだけトラフィックが流れる。
オートカナリアリリースする
先ほどは手動でカナリアフェーズを進めたが、今度は時間経過とともにロールアウトが自動で進行するように設定する。
設定方法はドキュメント「Cloud Deploy でのリリースプロモーションとロールアウト進行の自動化」を参考にした。
Automation リソース
ロールアウトの自動化を行うには Cloud Deploy の Automation リソースを作成する必要があり、これは clouddeploy.yaml に次のような形式で定義する。
apiVersion: deploy.cloud.google.com/v1
kind: Automation
metadata:
name: [PIPELINE_NAME]/[PURPOSE]
labels:
annotations:
description: [DESCRIPTION]
suspended: true | false
serviceAccount: [SERVICE_ACCOUNT_ID]
selector:
- target:
id: [TARGET_ID]
rules:
- [RULE_TYPE]:
name:[RULE_NAME]
[RULE-SPECIFIC_CONFIG]
-
PIPELINE_NAME
:自動化を使用するデリバリー パイプラインの名前。Automation は特定の1つのデリバリーパイプラインに属する形で作成される。 -
PURPOSE
:Automation を表す任意の名前。 -
DESCRIPTION
:Automation の説明。 -
SERVICE_ACCOUNT_ID
:Automation の実行に使用されるサービスアカウント。ロールアウトフェーズを進めるための権限が必要。 -
TARGET_ID
:Automation が使用されるターゲットID 。 -
RULE_TYPE
:Automation で使用される自動化ルールの名前で、promoteReleaseRule
またはadvanceRolloutRule
を設定する。今回はロールアウトの自動化なのでadvanceRollout
となる。 - [RULE-SPECIFIC_CONFIG]:構成は
RULE_TYPE
によって変わるが、advanceRollout
の場合はid
、sourcePhase
、wait
を指定する(参考:advanceRollout 自動化ルールを構成する)。-
id
:ルールに付ける名前。 -
sourcePhase
:ロールアウトを自動的に進行させる起点となるフェーズ。指定されたいずれかのフェーズが正常に終了すると、そのフェーズから次のフェーズに自動的にロールアウトが進行する。この項目はオプションであり、省略するとロールアウトのすべてのフェーズが自動的に進行する。 -
wait
:ロールアウトの準備が整った後、ロールアウトを進めるのを待機する時間(分単位)。
-
形式の詳細については「構成スキーマリファレンス:自動化の定義」を参考。
デリバリーパイプラインに Automation リソース定義を追加する
上記Automationリソースの説明を踏まえ、「カナリアリリースする」で作成した clouddeploy.yaml に次のような Automation 定義を追記する。
apiVersion: deploy.cloud.google.com/v1
kind: DeliveryPipeline
metadata:
# デリバリーパイプラインの名前
name: sample-delivery-pipeline
description: サンプル用のデリバリーパイプライン
serialPipeline:
stages:
- targetId: sample-target
profiles: [prod]
strategy:
canary:
runtimeConfig:
cloudRun:
automaticTrafficControl: true
canaryDeployment:
# カナリアの増分を表すパーセント値のカンマ区切りのリスト
percentages: [25, 50, 75]
verify: false
---
apiVersion: deploy.cloud.google.com/v1
kind: Target
metadata:
# ターゲットの名前
name: sample-target
description: Cloud Run production service
run:
location: projects/sample-project/locations/asia-northeast1
++ ---
++
++ apiVersion: deploy.cloud.google.com/v1
++ kind: Automation
++ metadata:
++ name: sample-delivery-pipeline/auto-canary
++ description: カナリアリリースを自動進行させる
++ suspended: false
++ # ロールアウトフェーズを進行するサービスアカウント
++ serviceAccount: sample-sa@sample-project.iam.gserviceaccount.com
++ selector:
++ - target:
++ id: sample-target
++ rules:
++ - advanceRolloutRule:
++ name: "advance-rollout"
++ wait: 1m
ターゲット sample-target
に対して Automation を定義し、advanceRolloutRule
によってロールアウトが自動化されるようにしている。
また、sourcePhase
を指定しないことで全てのフェーズが自動的に進行されるように設定した。
gcloud deploy apply コマンドで、先ほど記載した Automation 定義を反映する。
gcloud deploy apply --file=clouddeploy.yaml \
--project=sample-project \
--region=asia-northeast1
実行すると、デリバリーパイプラインの「自動」タブに auto-canary
が作成された。
リリースを作成する
標準デプロイと同じ skaffold.yaml と Cloud Run YAML を使用し、リリースコマンドを実行する。
gcloud deploy releases create auto-canary-001 \
--delivery-pipeline=sample-delivery-pipeline \
--skaffold-file=skaffold.yaml \
--images my-app-image=gcr.io/cloudrun/hello:latest \
--project=sample-project \
--region=asia-northeast1
実行すると、まず canary-25 フェーズになる。
1分経過すると、自動で canary-50 フェーズに進行する。
次の1分後には canary-75 になり、さらに 1分後にstableへとロールアウトが進んだ後にリリースが完了する。
所感
Cloud Deploy を使うと様々なデプロイ手法を簡単に扱えて、マネージドサービスなので自前でリリース基盤を構築・管理する必要が無いのが魅力。
機能も日々進化しているため、自分たちのサービスのリリース基盤に合うかどうか検討する価値はあると感じた。
Discussion