デプロイに全集中!新サービス Cloud Deploy

Ryo Nakamaru
google-cloud-jp
Published in
11 min readSep 22, 2021

お待たせいたしました、お待たせし過ぎたかもしれません。みんなー!やっと Google Cloud でデプロイのためのマネージド サービスがでてきたよー!!!

Cloud Deploy という謎サービスがリリースされました。現在 Preview ながら、実際にみなさんの環境で体験いただけます。以下はその解説ですが、そんなことより早く使いたい!という方はこちらからどうぞ。

Cloud Deploy とは

  • アプリケーションを実行環境へ継続的デリバリー (CD) するためのもの
  • 任意の継続的インテグレーション (CI) システムと連携できる
  • CD に関する重要な指標、データが容易に可視化できる
  • 現在サポートするデプロイ対象サービスは GKE のみ

使い方は

  1. 事前に “パイプライン” としてデプロイ先や順序、方法を決めておいて
  2. ソフトウェアが書けたら成果物を “リリース” としてまとめ
  3. 最初のデプロイ先( “ターゲット” )へリリースをロールアウト
  4. 問題があれば任意のリリースへロールバック
  5. 問題がなければ次のターゲットへ “プロモーション”

が基本です。シンプルな例は後述しますが、(開発 / 運用 / 管理者のように)チームが分かれている場合は、例えばこんな感じで使えます。

リリース準備、デプロイ、承認ができそうな雰囲気感じますね

なぜいま、CD に特化したサービスを?

そもそも Google Cloud で CI / CD パイプラインといえば、これまでは Cloud Build を中心にご案内していました。そこで、なぜいま Cloud Deploy なのか、どんな改善を期待いただけるのかを先にお伝えします。

CI だけの世界

大きなプロジェクトになると起こりがちな話ですが、ところで
CI のパイプライン内でデプロイまで実行するのは理想的でしょうか?
それどころか本来実現したいことへの足枷になってはいないでしょうか?

  • 秒でデプロイ(= リードタイムを短く)したい
  • そんなことより、問題があったら、秒でロールバックしたい
  • 少しずつロールアウトして様子をみたい
  • (ビルド・テスト結果ではなく)デプロイの履歴がみたい
  • CI の権限がわたしのそれよりはるかに大きいんですが 🤔

CI だけで、デプロイまで実装しようとすると難しさを感じる例です。
$ kubectl apply なら 2 秒なのに、CI 経由だと 30 分・・なんてことは?

CI と CD の分離

前段で示唆された期待とのギャップは、本来目的の違うひとつの方法 (CI) で、複数の役割 (CD まで) を兼務しているからこその歪みともいえます。昨今の技術やその思想に注目すると、それを CI と CD の関心の分離で解決しようという動きがあります。CI、CD それぞれが目指す理想を、より適切なもので実現する世界観ですね。

Cloud Build はこれからもデプロイの実行基盤としては重要なのですが、 実現したいことによっては Cloud Deploy へその役割をオフロードすることで全体としてより柔軟な、スケールする CI / CD が構成できます。

Cloud Deploy ウォークスルー

実際のコマンドや画面をはさみつつ、Cloud Deploy を使うとソフトウェア デリバリーがどうなるのかをみていきましょう。以下、イメージをもっていただく意図なので、一部設定値に整合性がありません。実際に動かす場合はこちらをご利用ください)

1. パイプラインの作成

Cloud Deploy のパイプラインにはステップやタスクといった概念はなく、あくまで “どこにどういう順序でデプロイするか” を決めておく単位です。パイプラインの構成要素は以下です。

  • デプロイ先となる “ターゲット”
  • 各ターゲットに対し、どのようにして環境差分をもたせるか
  • どういう順序でデプロイするか

例えば

apiVersion: deploy.cloud.google.com/v1beta1
kind: Target
metadata:
name: dev
gke:
cluster: projects/prj-id/locations/asia-northeast1-a/clusters/gke1
---
apiVersion: deploy.cloud.google.com/v1beta1
kind: Target
metadata:
name: prod
gke:
cluster: projects/prj-id/locations/asia-northeast1-a/clusters/gke1
---
apiVersion: deploy.cloud.google.com/v1beta1
kind: DeliveryPipeline
metadata:
name: sample
serialPipeline:
stages:
- targetId: dev
profiles: ["development"]
- targetId: prod
profiles: ["production"]

という設定ファイル (clouddeploy.yaml) だとすると、その意味は

  • ターゲットは 2 環境 devprod
  • (名前空間で分ける要件と仮定して)デプロイ先はどちらも gke1
  • ステージの並びをみるに、dev がうまくいったら prod にデプロイ
  • 環境差分は developmentproduction というプロファイルで制御

となります。
実際にパイプラインを作ってみると、画面上には箱が 2 つできます。

$ gcloud beta deploy apply --file=clouddeploy.yaml
この時点はもちろん、なにもデプロイされていません

2. リリース準備

単一 git リポジトリからの CD に慣れてしまった方には思い出してほしい(?)のですが、ソフトウェアを製品として出荷するにあたっては、バージョンをふり、一緒に出荷したい成果物をまとめていましたよね。Cloud Deploy による CD は、まず「任意の数の成果物を “リリース” としてまとめる」ことから始まります。

では具体的に、どうやって成果物をまとめるのか。
Cloud Deploy は Skaffold ( https://skaffold.dev/ ) を内部的に利用します。

Skaffold は

  • Kubernetes のローカル開発環境としてものすごーく便利なのですが
  • 実はデプロイまでのさまざまなフェーズを支援する機能があり
  • デプロイには Kubectl / Kustomize / Helm などから慣れたものが選べ
  • Cloud Deploy 内部では skaffold renderコマンドが採用されている

のが特徴です。
が、難しいことはいったん忘れて以下を skaffold.yaml として保存、

apiVersion: skaffold/v1
kind: Config
deploy:
kubectl:
manifests:
- k8s-*

ファイル名に k8s- というプリフィックスをつけつつ、ひとつの製品群として一緒にデプロイしたいものを Kubernetes マニフェストとして並べてみましょう。例えばこんなものを、k8s-echo-pod.yaml として保存します。

apiVersion: v1
kind: Pod
metadata:
name: getting-started
spec:
containers:
- name: echoserver
image: k8s.gcr.io/echoserver:1.4

これらを例えば v0–3–2 という名前の “リリース” にまとめるにはこれ。

$ gcloud beta deploy releases create v0-3-2 \
--delivery-pipeline=sample

3. 最初のターゲットへデプロイ

リリースを作ると、実はそれがトリガーになり、自動的に最初のターゲットへデプロイが始まります。もう少し厳密に言うと、ここは 2 段階あり

  1. パイプライン上の全ターゲット向けにマニフェストがレンダリングされ
  2. 問題なければ最初のターゲットにデプロイが始まります。
新しいリリース、v0–3–2 が dev 環境へデプロイされている様子

今回詳細には触れませんが

  • プロファイル(実際には Skaffold Profiles のこと)で環境差分をもつ
  • リリース作成時に環境別のマニフェストをレンダリングする
  • Skaffold が複数のデプロイツールをサポートしている

ことにより、Cloud Deploy は汎用的なマネージド サービスでありながら、プロジェクト固有の事情を鑑みた柔軟なデリバリーが実現できます。

4. リリースのロールバック

新しいリリース v0–3–2に問題があった場合、例えば以下のコマンドを実行すると dev 環境のリリースは v0–3–0 にロールバックされます。直前の v0–3–1 が失敗しており、最後の問題なかったリリースにもどるためです。
(もちろん任意のリリースを指定するオプションもあります)

$ gcloud beta deploy targets rollback dev --delivery-pipeline=sample

5. プロモーション

せっかく複数の環境を用意してテストをしているからには、極力環境間で同一のソフトウェア・設定を利用したいですよね。Cloud Deploy は

  • リリースという単位で成果物を管理し
  • “プロモーション” により同一リリースを各環境に展開

する仕組みでした。

コマンドラインからの指示は少々味気ないのですが

$ gcloud beta deploy releases promote \
--delivery-pipeline=sample --release v0-3-0

以下は、プロモーションを判断するときに表示される画面です。

  • 左側からは現在 prod では v0-2-2 が稼働中だとわかり
  • 右側からは dev にロールアウト済みの v0-3–0prod へのデプロイ(プロモーション)候補として提案されていることがわかります

タブを切り替えると、本番環境のマニフェストを比較し、何が変わるのかといった Diff も一目瞭然です。実際にはイメージ名だけ変わるケースも多そうですが、環境変数や Secret のチェックなどは捗りそうです。

Cloud Run for Anthos を有効化しておくとサーバーレスなサービスも容易に扱えます!

おまけながら、ターゲットごとに承認を要求することもできます。

apiVersion: deploy.cloud.google.com/v1beta1
kind: Target
..
requireApproval: true

承認する場合は以下のようなコマンドです。

$ gcloud beta deploy rollouts approve ${ROLLOUT_NAME} \
--delivery-pipeline=sample

まとめ

Cloud Deploy の機能はいかがでしたか?
改めて振り返ると

  • 成果物をリリースとしてまとめる機能がある
  • リリースはプロモーションすることで次の環境に展開される

といった機能は馴染みのない方も多いかと思います。

しかしそんな概念が敢えて導入された背景や、忘れていたかもしれない、みなさんが本来目指していた継続的デリバリーの理想を考慮すると、相応に検討の価値があったりはしませんか?

今回紹介していない

  • そもそも CI からはどう繋げるイメージなの?
  • 環境間での同一イメージ利用をより確実にするための機能
  • 複数プロファイルを使った環境差異管理
  • ローカル開発環境と美しく繋がる様
  • 脆弱性診断と組み合わせたソフトウェア サプライチェーンの強化

あたりは今後ご紹介できればと思います。
また、GA のタイミングで現時点ではまだ見えていない、いくつかの機能がリリースされそうです。お楽しみに!

--

--

Ryo Nakamaru
google-cloud-jp

Application modernization specialist, Customer Engineer at @GoogleCloud. Opinions are my own, NOT the views of my employer.