Google Cloud Deploy を触ってみた

GCP の継続的デリバリのための新しいサービスとして、Google Cloud Deploy (以下、Cloud Deploy) が登場しました。

どんなものか触ってみました。

Google Cloud Deploy とは

デリバリパイプラインからマニフェストレンダリング (YAML の生成) を分離することで、よりシンプルに継続的デリバリを実現するためのマネージドサービス、と理解しています。

マニフェストレンダリングとデプロイには Skaffold が使用されています。

この記事の執筆時点 (2021年9月27日) では Preview のサービスとなっています。

Google Cloud の中の人の紹介ブログは こちらこちら

Cloud Deploy によるデプロイの流れ

詳しくは公式ドキュメントを参照頂ければと思いますが、ざっと書くと以下のような流れになります。

  1. デリバリパイプラインとターゲットを YAML で記述する
  2. デリバリパイプラインとターゲットを Cloud Deploy に登録する
  3. Cloud Deploy に登録されたパイプラインを指定してリリースを作成する
  4. リリース作成時にマニフェストレンダリングが行われ、ターゲット毎のマニフェストとソースファイルが GCS に格納される
  5. リリース作成後、パイプラインの最初のターゲットに自動でロールアウトが開始される (Skaffold を使ってターゲットにマニフェストが適用される)
  6. ロールアウトに成功すると、次のターゲットへの promote (ロールアウトの作成) が行える

マニフェストレンダリングはリリース作成時のみに行われ、以後の各ターゲットへのロールアウトと分離されているところがポイントですね。
ターゲット毎のマニフェストの差分を Skaffold の Profile で定義できるため、環境毎のイメージタグの使い分けなどが簡単に管理できそうです。

補足

  • ターゲットランタイム (リリースのロールアウト先) は現在のところ GKE のみ対応
  • パイプラインは直列な定義のみをサポートしており、複数のターゲットに同時並行でロールアウトすることはできない
  • マニフェストレンダリング、およびターゲットへのデプロイを行う Skaffold の実行環境には Cloud Build を用いる
  • 実行環境の Cloud Build にはプライベートワーカープールも利用可能
  • ターゲット毎に手動承認プロセスの要否を設定できる
  • 現状は GCP コンソールからリリースやターゲットを設定することができない (リリースの promote やロールアウト失敗時の再デプロイはコンソールから実行可能)
  • リリース作成時に、ソースファイル (Skaffold の Config、レンダリング元となる Kubernetes マニフェスト、パイプライン定義) がまとめてスナップショットされるため、途中でパイプラインが変更されても「このリリースがどのパイプライン定義に基づいているか」が追跡できる

気になったポイント

実際の開発に Cloud Deploy を導入することを想定したとき、気になりそうなポイントをいくつか挙げてみます。

限定公開クラスタでの利用

ターゲットランタイムが限定公開クラスタの場合、 (パブリックエンドポイントの有無に関わらず) Cloud Build はプライベートワーカープールを使うほうが良さそうだという印象を受けました。

Cloud Deploy からターゲットランタイムへのデプロイは、Cloud Build からの skaffold apply として実行されるため、実際には Cloud Build からクラスタへのアクセスを考える必要があります。

Cloud Deploy は特に指定しなければデフォルトの Cloud Build ワーカープールで実行されますが、パブリックエンドポイントを持つ限定公開クラスタの場合は、アクセス元 (Cloud Build) の IP アドレスが動的に変化するためマスター承認済みネットワークの設定が難しくなります (マスター承認済みネットワークを設定しない、あるいは動的に書き換えるといった対応が必要になりそうですが、いずれも容易な選択肢ではないように思います) 。
そのため、パブリックエンドポイントがある限定公開クラスタであっても、Cloud Build はプライベートワーカープールを設けてプライベート IP アドレスからコントロールプレーンにアクセスするほうがアクセス制御がやりやすそうです。

プライベートエンドポイントのみの限定公開クラスタを利用する場合、今後は Cloud Build にプライベートワーカープールを選択することが多いと思いますので、その場合は問題にならないですね。

構成方法はこちらが参考になります。                                                                                                                                                                                                                                                                                                                                                                                 

Skaffold のバージョン管理

Cloud Deploy がサポートする Skaffold のバージョンは、現在のところ 1.24.0 となっています。
90日毎に新しいバージョンを追加して、以後のリリースのデフォルトバージョンとなります。
今のところ、Cloud Deploy がレンダリングやデプロイで使用する Skaffold のバージョンを指定することはできません。

サポートのリストに追加された Skaffold バージョンは 12 か月間+α のあいだサポートされるようですが、マニフェストレンダリングなどでバージョン間の不整合が起きる可能性を回避したいと考えるとローカルの開発環境と Skaffold のバージョンを合わせておくほうが望ましいと思いますので、Cloud Deploy の Skaffold バージョンの更新に合わせて 3か月毎に開発環境の Skaffold のバージョンを更新する運用が必要になりそうです。

今後期待したいアップデート

国内リージョン対応

東京、大阪リージョンではまだ使えませんでした。

Cloud Deploy (のデリバリパイプライン)とターゲットランタイムが同一のリージョンである必要は無いようですが、デリバリパイプラインを配置したリージョンに応じて Cloud Deploy インスタンスが決まるため、ターゲットランタイムと同じリージョンにデリバリパイプラインを配置したいというケースはありそうです。

VPC Service Controls 対応

現在は未対応となっています

ビルドアーティファクトを格納している Artifact Registry や GCS が VPC SC で保護されているというケースはあると思いますし、Cloud Build をプライベートワーカープールで利用する場合はこちらも VPC SC で保護したいケースがあると思いますので、今後の対応を期待したいですね。

API メソッドの一覧を見ると、promote や承認も個別の権限として定義されているため、VPC SC に対応すれば Ingress/Egress Policy と併せて柔軟な権限制御が行えそうです。

デプロイ戦略の選択肢の拡充

現状はレンダリングされたマニフェストクラスタへ単純に展開するため、Cloud Deploy 単体によるデプロイは Inplace(Rolling Update)になります。

一方で、本番環境では Blue/Green や Canary を使って稼働中のバージョンのアプリケーションを変更することなくリリースしたいというケースも少なくないと思いますので、そうしたデプロイ戦略を Cloud Deploy で簡単に扱えると嬉しいなと思います。

また、発展形として Progressive Delivery のサポートにも期待したいですね。
デプロイ後のアプリケーションのメトリクスに基づいてリリースの良し悪しを判定し、必要に応じて自動でロールバックするような仕組みがあると便利です。