CI/CD 手軽改善!DORA metrics × Cloud Deploy 実践例
はじめに
こんにちは。クラウドエース株式会社で Application Modernization の設計開発を担当している水野と中原です。
今回は、CI/CD 手軽改善!DORA metrics × Cloud Deploy 実践例 についてご紹介します。
GitHub Actions や Cloud Build を使用して CI/CD を実装している人は増えてきていると思います。
ですが、「ビジネス改善に繋がる指標を決め、どう CI/CD を改善すれば良いか」までできている人はどれくらいいるでしょうか?
そんな人に向けて、DORA metrics と Cloud Deploy を使用して手軽に CI/CD を改善する方法をご紹介します。
DORA metrics とは
DORA metrics とは、DORA という DevOps を軸に調査・研究をしている Google のチームが提案している「4つのキー指標」です。Four Keys とも呼ばれています。
このキー指標を使用することで、ビジネス改善に繋がる DevOps 活動がしやすくなります。
引用:CI / CD の改善に役立つ? Skaffold & Cloud Deploy
詳細な内容については、Google nak さんの記事がまとまっているのでこちらをご覧ください。
Cloud Deploy とは
Cloud Deploy とは、CD(継続的デリバリー)に特化した Google Cloud のフルマネージドサービスです。Cloud Deploy を使用することによりデプロイフローの自動化を簡単に実現できます。
また、Cloud Deploy は、内部で Skaffold を利用しています。
Skaffold は、コンテナ開発・ビルド・デプロイのための OSS コマンドラインツールです。環境に依存しないアーキテクチャであるため、ローカル環境でデリバリーパイプラインを使用することも可能です。
こんなデリバリーパイプラインが組める
Cloud Deploy を利用することで以下のようなパイプラインを簡単に組むことができます。
デプロイ戦略(マルチターゲット、カナリア等)、ロールバック、デプロイ検証、デプロイフック、承認、通知、等のさまざまな機能を一元的に管理できます。
上記の例では、以下の流れになっています。
- Git の操作(PR 更新、ブランチへの push 等)をトリガーに CI を起動(コンテナイメージは CI で push)
- CI から Cloud Deploy を起動する
- 評価環境にイメージを自動リリース
- デプロイ前後に必要な処理(デプロイ検証、デプロイフック)を行う(デプロイフックで DB スキーママイグレーションやテスト等を実施)
- 4 が成功すると自動で Promote され、承認者へ Slack 通知がいく(手動テスト等をしたい場合は、Promote を手動にすれば OK)
- 承認者が承認すると、次の Stage へ Promote
- 本番環境へカナリアリリースを開始
- 1 分ごとにフェーズ(10% -> 50% -> 100%)を自動移行
つまづきポイント
Cloud Deploy は非常に便利なツールなのですが、以下の点でつまづきやすいです。
- アーキテクチャが少し複雑
- 管理する構成ファイルの数が多い
逆にここを理解できれば、実装の難易度がグンと下がります。
そのため、この 2 点を整理します。
Cloud Deploy のアーキテクチャ
Cloud Deploy は以下のようなアーキテクチャを採用しています。
疎結合なアーキテクチャをとることで、柔軟な構成を組むことを可能にしています。
必要な構成ファイル
複数の yaml ファイルを作成する必要があります。
各 yaml ファイルの役割は以下です。詳細は実装例の部分でご紹介します。
DORA metrics × Cloud Deploy のメリット
メリットは、DORA metrics のキー指標のうちの2つは Cloud Deploy で自動計装できる点です。計測→改善
をより手軽に行うことができる便利な機能ですね。
以下は、Cloud Deploy のコンソール画面です。
右下の赤枠内にある「デプロイの頻度」と「デプロイの失敗率」に着目してください。これは4つのキー指標である「デプロイ頻度」と「変更による失敗率」に相当します。実装なしに計測してくれるのは嬉しいですね。
他の指標に関しても、Cloud Deploy 以外のサービスを使うことで計測が可能です。
計装方法は Google Cloud の 公式ブログ をご参照ください。
実装例
Cloud Deploy では、以下 3 種類の構成ファイルを作成することで、デリバリーパイプラインを構築できます。
-
clouddeploy.yaml (パイプライン管理)
: デリバリーパイプラインを定義する (実行順序、Rollback 等)。 -
*.yaml (マニフェスト)
:デプロイするアプリケーションのマニフェストを定義する。(service-staging.yaml, service-prod.yaml等) -
skaffold.yaml (成果物管理)
: マニフェスト群をまとめて定義する。また、デプロイ検証やデプロイフック等の処理もここで定義する。
ひとつずつおさえていきましょう。
clouddeploy.yaml
clouddeploy.yaml
には、以下の内容を記述します。
-
DeliveryPipeline
: 各環境のデプロイ方式や、デプロイの順番を記述します。 -
Target
: デプロイ先のサービスを記述します。 -
Automation
: デリバリーパイプラインの自動化を記述します。
以下は、clouddeploy.yaml
の例です。
apiVersion: deploy.cloud.google.com/v1
kind: DeliveryPipeline
metadata:
name: release-delivery-pipeline
description: Delivery pipeline for application release
serialPipeline: # パイプラインステップ定義
stages:
- targetId: run-staging-target # 評価 Stage
profiles: [staging]
strategy:
standard: # 通常デプロイ
verify: true # デプロイ検証
predeploy: # デプロイフック
actions: ["staging-predeploy-action"]
postdeploy: # デプロイフック
actions: ["staging-postdeploy-action"]
- targetId: run-prod-multi-target # 本番 Stage
profiles: [prod]
strategy:
canary:
runtimeConfig:
cloudRun:
automaticTrafficControl: true
canaryDeployment: # カナリアデプロイ
percentages: [10, 50]
verify: false
postdeploy:
actions: ["prod-postdeploy-action"]
---
apiVersion: deploy.cloud.google.com/v1 # ターゲット定義
kind: Target
metadata:
name: run-staging-target # serialPipeline.stages.targetId の値と合わせる
description: Cloud Run staging service
run: # Cloud Run のリージョン定義
location: projects/[project_name]/locations/asia-northeast1
---
apiVersion: deploy.cloud.google.com/v1 # ターゲット定義
kind: Target
metadata:
name: run-prod-multi-target # serialPipeline.stages.targetId の値と合わせる
description: Cloud Run production service in Tokyo and Osaka
requireApproval: true # 承認フラグ
multiTarget:
targetIds: [ run-prod-tok, run-prod-osa ] # kind が Target になっている metadata.name の値と合わせる
---
apiVersion: deploy.cloud.google.com/v1 # ターゲット定義
kind: Target
metadata:
name: run-prod-tok
description: Cloud Run production service in Tokyo
run: # Cloud Run のリージョン定義
location: projects/[project_name]/locations/asia-northeast1
---
apiVersion: deploy.cloud.google.com/v1 # ターゲット定義
kind: Target
metadata:
name: run-prod-osa
description: Cloud Run production service in Osaka
run: # Cloud Run のリージョン定義
location: projects/[project_name]/locations/asia-northeast2
---
apiVersion: deploy.cloud.google.com/v1 # 自動化定義
kind: Automation
metadata:
name: promote-staging-automation
description: Promote to prod
suspended: false
serviceAccount: sa-cicd@[project_name].iam.gserviceaccount.com
selector:
- target:
id: run-staging-target # serialPipeline.stages.targetIdと値を合わせる
rules:
- promoteRelease:
name: "promote-prod"
wait: 1m # 自動 Promote するタイミング
toTargetId: "@next" # Promote する Stage
上記のコードを見ると、以下のようなことがわかります。
-
DeliveryPipeline
には、staging
とprod
の 2 つのステージがあります。- 順序は、
staging
からprod
となっています。 -
staging
では、通常のデプロイを行い、prod
では、カナリアリリースを行っています。 -
staging
では、検証を行い、prod
では、検証を行わないように設定されています。 - デプロイ前後にカスタムアクションが行われます。
- 順序は、
-
Target
には、staging
、prod-multi
、prod-tok
、run-prod-osa
の 4 つのターゲットがあります。-
prod-multi
が、prod-tok
とprod-osa
に紐づくことで、マルチターゲットでデプロイされます。 - 各 Target は、
Cloud Run
にデプロイされます。 -
prod-multi
は事前に承認が必要です。
-
-
Automation
には、自動化が記述されています。-
staging
が成功すると、1 分後に自動でprod
に Promote されます。
-
clouddeploy.yaml
のスキーマの詳細については、公式ドキュメントを参照してください。
DeliveryPipeline
項目 | 説明 | 備考 |
---|---|---|
targetId | ターゲットの ID | Target.metadata.name と一致する必要あり |
profiles | デプロイに使用するプロファイル | |
strategy | デプロイ戦略 | standard: スタンダードデプロイ, canary: カナリアデプロイ |
Target
項目 | 説明 | 備考 |
---|---|---|
metadata.name | ターゲットの名前 | |
description | ターゲットの説明 | |
requireApproval | 承認が必要かどうか | true: 承認が必要, false: 承認が不要 |
run.location | サービスのリージョン |
Automation
項目 | 説明 | 備考 |
---|---|---|
metadata.name | 自動化の名前 | |
description | 自動化の説明 | |
suspended | 自動化が停止しているかどうか | true: 停止, false: 開始 |
serviceAccount | 自動化を実行するサービスアカウント | |
selector | 自動化の対象 | Target.metadata.name と一致する必要あり |
rules | 自動化のルール |
*.yaml
*.yaml
には、環境ごとのデプロイ設定を記述します。
今回は、run-service-staging.yaml
の例を示します。
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
name: deploy-run-service-staging
spec:
template:
spec:
containers:
- image: my-app-image
上記のコードを見ると、以下のようなことがわかります。
-
run-service-staging.yaml
には、my-app-image
がデプロイされます。(my-app-image
は Cloud Deploy を起動するgcloud deploy releases
コマンドの--images
フラグで指定するイメージ名)
Service
項目 | 説明 | 備考 |
---|---|---|
metadata.name | サービスの名前 | |
spec.template.spec.containers.image | サービスのイメージ |
skaffold.yaml
skaffold.yaml
には、以下の内容を記述します。
-
profiles
: 環境ごとのデプロイ設定を記述します。 -
deploy
: デプロイ先のサービスを記述します。 -
verify
: デプロイ検証を記述します。 -
customActions
: デプロフックを記述します。
apiVersion: skaffold/v4beta7
kind: Config
metadata:
name: deploy-run
profiles:
- name: staging
manifests:
rawYaml:
- run-service-staging.yaml
- name: prod
manifests:
rawYaml:
- run-service-prod.yaml
deploy:
cloudrun: {}
verify:
- name: verification
container:
name: verification-something
image: ubuntu
command: ["/bin/sh"]
args: ["-c", 'echo "something"' ]
customActions:
- name: staging-predeploy-action
containers:
- name: predeploy-something
image: ubuntu
command: ["/bin/sh"]
args: ["-c", 'echo "something"' ]
- name: staging-postdeploy-action
containers:
- name: postdeploy-something
image: ubuntu
command: ["/bin/sh"]
args: ["-c", 'echo "something"' ]
- name: prod-postdeploy-action
containers:
- name: postdeploy-something
image: ubuntu
command: ["/bin/sh"]
args: ["-c", 'echo "something"' ]
上記のコードを見ると、以下のようなことがわかります。
-
profiles
には、staging
とprod
の 2 つのプロファイルがあります。-
staging
では、run-service-staging.yaml
がデプロイされます。 -
prod
では、run-service-prod.yaml
がデプロイされます。
-
-
deploy
には、Cloud Run
にデプロイされます。 -
verify
には、デプロイ後の検証が記述されています。-
verify
を使用する場合は、clouddeploy.yaml
のDeliveryPipeline
のstrategy
内で指定する必要があります。 - ここでの例では、echo が実行されるだけなので、実際には、テストコードが実行されることが想定されます。
-
-
customActions
には、デプロイ前後のデプロフックが記述されています。-
customActions
を使用する場合は、clouddeploy.yaml
のDeliveryPipeline
のstrategy
内で指定する必要があります。 -
predeploy-action
では、デプロイ前のアクションが記述されています。 -
postdeploy-action
では、デプロイ後のアクションが記述されています。
-
skaffold.yaml
のスキーマの詳細については、公式ドキュメントを参照ください。
Config
項目 | 説明 | 公式ドキュメント |
---|---|---|
metadata.name | 設定の名前 | skaffold |
profiles | プロファイル | cloud deploy, skaffold |
deploy | デプロイ | cloud deploy, skaffold |
verify | 検証 | skaffold |
customActions | デプロイ前後のアクション | skaffold |
Cloud Deploy を起動する gcloud コマンド
以下のようなコマンドを CI 上で実行することで Cloud Deploy のパイプラインを起動できます。
gcloud deploy releases create ${RELEASE_NAME} --project=${PROJECT_ID} --region=${GOOGLE_CLOUD_REGION} --delivery-pipeline=${PIPELINE_NAME} --images=${IMAGE_NAME}=${GOOGLE_CLOUD_REGION}-docker.pkg.dev/${PROJECT_ID}/${ARTIFACT_REGISTRY_DIR}/${IMAGE_NAME}:${CI_COMMIT_TAG} --skaffold-file=./clouddeploy/skaffold.yaml
おわりに
今回は、CI/CD 手軽改善!DORA metrics × Cloud Deploy 実践例 についてご紹介しました。
少しでもビジネス改善に繋がるような CI/CD 手法として何かご参考になれば嬉しいです。
Discussion