DevOps、アジャイル開発のための CI / CD パイプライン

 

デザイン パターン詳細

Google Cloud での CI / CD

解決する課題・使い所 

ここでは、Google Cloud プロダクトを利用した CI / CD により、アプリケーションを高速にビルド、デプロイするパターンを紹介します。Google Cloud のマネージド サービスを活用することで、ビルド環境の構築、運用といった時間を削減することも利点として挙げられます。

コンテナのビルド、管理 

一度ビルドしたコンテナは、実行環境を選ばずに稼働できます。例えばよく利用される Docker の場合、Docker がインストール済みの環境であれば、どこでもコンテナを動作させることが可能となります。マネージドのビルド環境だけでなく、作成されたイメージを保持するコンテナ レジストリやアプリケーションで利用する maven や npm などのパッケージも、Google Cloud のマネージド サービス上で管理することが可能です。

セキュリティ 

コンテナをビルドする上で、セキュリティの観点も外せません。CI パイプラインの中でコンテナ セキュリティを担保するためには何を意識しなければならないでしょうか。

  1. コンテナの脆弱性スキャンは行われているか
  2. 検証プロセスを通過したイメージが展開されているか

コンテナの脆弱性をスキャンして継続的にデプロイすることは、DevSecOps を実現するためにも大切な要素です。脆弱性のスキャン機能や、検証済みのイメージだけデプロイを許可するルールを強制することも、Google Cloud マネージド サービスで完結することが可能です。 

デプロイの管理 

継続的デリバリー(CD)とは、ユーザーの手に、安全かつ迅速に、継続的に製品を提供することが出来る機能です。継続的にデプロイが行われないと、複数の機能の統合、テストなどが蓄積し、リリース前の状態で停滞してしまいます。これを避けるため、常にデプロイ可能な状態にしておくことがビジネスに求められます。 

デプロイを自動化することで、開発から運用まで一連のサイクルを回すことが可能となります。そのため、CD におけるビジネスフローや戦略も考慮した方が良いでしょう。 

また、近年 GitOps という手法が採用されています。GitOps とは、Git リポジトリ にあるソースコードを SSoT(Single Source of Truth 唯一の信頼できる情報)として扱い、コミットをトリガーとして処理を起動する手法で、Kubernetes の世界においては、マニフェストが自動的にワークロードに反映されるような手法です。これを実現する Google Cloud マネージド サービスも存在しています。

関連する主な Google Cloud プロダクトは以下になります。 

アーキテクチャ 

【CI】Cloud Build のトリガーとカスタム ビルダーの作成 

Google Cloud で CI を構築するには、Cloud Build を利用します。 トリガーを作成することで、ソースコードの変更を検知し、自動的にビルドを開始することが可能です。連携可能なソースは、Cloud Source RepositoriesGitHub または Bitbucket です。

ビルドの構成ファイルには、Dockerfile、または、YAML や JSON ファイル形式でパイプラインを記述します。イメージをビルドし、レジストリへアップロードするだけで良い場合は、Dockerfile だけで構築可能です。

パイプラインには、公開イメージ、サポート対象のビルダーまたはコミュニティ提供のビルダーが利用可能です。これらから提供されていない機能が必要な場合、カスタム ビルダーの作成が可能です。

ブランチやタグ毎に別のトリガーを作成することもでき、柔軟に様々なビルドパターンをカバーすることが可能です。また、Cloud Identity and Access Management(IAM) で権限を制御することで、最小権限のアクセス管理が導入可能です。

 

【Secure CI】セキュアなソフトウェア サプライチェーン 

次に、脆弱性スキャン済みの検証されたイメージだけを、Google Kubernetes Engine(GKE) クラスタへ展開するフローを紹介します。Cloud Build のカスタム ビルダーで、セキュリティ関連のサービスと連携することで実現します。次の図はサービス連携の全体フローとなっており、各サービスについてここで説明します。

1
  • Git リポジトリ(Code)
    • ビルド対象のアプリケーション コードがコミットされ、特定のブランチ、タグに対してのイベントをトリガーに、Cloud Build を実行します。
      コンテナ作成に利用するベース イメージについては、マネージド ベースイメージが Google Cloud から提供されています。これは、入手可能な最新のパッチを使用して、セキュリティの脆弱性に対するパッチが自動的に適用されるベースコンテナ イメージです。中でも、distroless は言語を重視した必要最小限のイメージとなっており、軽量イメージを作成するのに適しています。
  • Cloud Build
    • ビルドしたイメージをレジストリにアップロードした後の、脆弱性スキャン、Binary Authorization との連携も、Cloud Build のパイプラインで実行可能です。各機能については後述します。
      開発環境やステージング環境においては、脆弱性スキャンによって検証されたコンテナ イメージを自動で展開できるようにしておくと、継続的にセキュリティの検査が行われた状態を保つことができます。本番環境へのデプロイは自動で展開せず、QA が承認するまで待機する、といったフローも実現可能です。
  • GCR vulnerability scanning
    • Container Registry にアップロードされたイメージに対し、脆弱性スキャンを実施します。このサービスを Container Analysis といいます。Container Analysis API は、Linux ディストリビューションのパッケージ脆弱性スキャンをサポートし、次のソースから CVE データを取得します。
    • 脆弱性を検知した場合、CVSS スコアと重大度がリスト化されます。スコアを基準に、CI パイプラインで成功または失敗の判定を行うことも可能です。オープンソースで提供している gke-binary-auth-tools というツールを利用することも出来ます。後述の Binary Authorization と組み合わせたパイプラインの構築方法は、こちらをご参照ください。
      また、脆弱性はデプロイ前にチェックする必要がありますが、新たな脆弱性が見つかる可能性があるため、イメージはデプロイ後にもチェックする必要があります。脆弱性スキャンは、過去 30 日間にレジストリから取得されたイメージを継続的にスキャンします。イメージに脆弱性が見つかるたびに、Pub/Sub 経由で通知を受け取れます。
  • Binary Authorization 
    Binary Authorization は、信頼できるコンテナ イメージのみが Google Kubernetes Engine(GKE) にデプロイされることを保証する、デプロイ時のセキュリティ管理サービスです。Container Analysis を使用して、認証プロセスで使用される信頼できるメタデータを保存します。作成する認証者ごとに、1 つの Container Analysis メモを作成する必要があります。それぞれの証明書が、このメモのオカレンスとして保存されます。
    有効化するには、Binary Authorization の設定以外に、新規 or 既存の Google Kubernetes Engine(GKE)クラスタに対して適用させる必要があります。Binary Authorization は、次に説明する Anthos Config Management によって有効化することも可能です。
    有効化したクラスタに対し、未検証のイメージをデプロイするとエラーになり、新しいイメージが展開されることはありません。 

【GitOps】GitOps による Kubernetes マニフェストのデプロイ

最後に、GitOps の手法で Google Kubernetes Engine(GKE) クラスタへ Kubernetes マニフェストをデプロイする方法について説明します。これを実現するために、Anthos Config Management を利用します。

Anthos Config Management によって複数クラスタの状態を同期し、アプリケーションのバージョンについても、一貫してデプロイすることが可能です。

Google Kubernetes Engine(GKE) クラスタに、Config Management Operator をインストールし、Operator が対象の Git リポジトリに対して読み取りが行えるよう構成します。構成後、Kubernetes マニフェストの管理者が行うのは、Git リポジトリに対してコミットを行うだけです。デフォルトでは 15 秒間隔で同期されます。クラスタ内の Operator が、Git リポジトリに対してプル型でアクセスするため、クラスタから Git リポジトリに対してネットワークが繋がりさえすれば利用可能です。

【CD】Cloud Build や OSS を利用した継続的デリバリー

Cloud Build は CI だけでなく、CD においても利用可能です。以下のように、Google Cloud のあらゆる基盤へのデプロイが可能です。 

Cloud Build を利用し、Git の変更をトリガーに CI / CD を組み合わせることも可能ですが、より高度なデプロイ(Blue / Green、Canary デプロイなど)を実践するには、OSS である Argo や Spinnaker を組み合わせると良いでしょう。Spinnaker を組み合わせた詳細については以下をご覧ください。

Argo Project については、前述した GitOps の手法でのリリースを実現する Argo CD や、Blue / Green や Canary デプロイを実現する Argo Rollouts などがあります。これらは、提供されるリソースを Kubernetes にインストールする形となります。

Argo CD は、Git にあるソースを pull 型で自動反映するのはもちろん、各 Kubernetes リソースの関係性や変更の過程を、GUI を提供することで可視化します。

2

Argo Rollout は、前述した機能以外にも高度なデプロイが可能で、特徴的なのは Progressive delivery です。これは、メトリクスを分析しながら徐々にデプロイし、失敗と判定した場合にロールバックするという手法になります。

Argo Rollout で Canary デプロイを行う場合、以下のような記述をします。

strategy:
  canary: canaryService: canary-demo-preview
    steps:
      - setWeight: 20
      - pause: {}                   # 手動でコマンド実行して再開するまで一時停止
      - setWeight: 40
      - pause: {duration: 10}
      - setWeight: 60
      - pause: {duration: 10}
      - setWeight: 80
      - pause: {duration: 10} 

 

これは、20% のトラフィックを新しいアプリに流して、挙動に問題ないことを確認し、さらに 10 秒おきに 20% ずつ増やしていくといった挙動になります。

Google Kubernetes Engine(GKE) に対しては、シンプルにデプロイすることも、上記のように高度な戦略でデプロイすることも可能となってきます。一方、他の Google Cloud マネージドな環境へのデプロイは、権限管理などの面からも Cloud Build との相性が良いです。管理や運用といった点も含め、組織に合ったプロダクトを選択すると良いでしょう。 

 

利点

  • CI / CD をマネージド サービスで実現することで、インフラ管理の煩わしさから解放されます。また、豊富な Builder が公式、コミュニティから提供されているため、プラグインのインストールやバージョン管理などを行う必要もなく、柔軟なパイプラインを構築することが可能です。
  • GitOps の手法を採用することで、Google Cloud だけでなく、オンプレミスや他社クラウドにおいても、一貫したデプロイが容易に実現できます。
  • Google Cloud マネージド サービスとの相性が良く、Cloud Identity and Access Management(IAM)と連携した権限管理が可能です。 

注意事項

  • Cloud Build が実行されるリージョンは選択ができないため、各リージョンで閉じた CI を行いたい場合は、Google Compute Engine(GCE)、または、Google Kubernetes Engine(GKE)上に Jenkins や Spinnaker を構築する、または、リージョン指定が可能なサードパーティーが提供しているツールなどを利用する必要があります。
  • Cloud Build には、ビルドを実行する 2 つの高 CPU 仮想マシンタイプ(8 CPUs / 32 CPUs)が用意されています。デフォルトのマシンタイプは 1 CPU です。 高 CPU 仮想マシンをリクエストすると、ビルドの起動時間が長くなる可能性があります。より高い CPU の仮想マシンをリクエストするには、machineType オプションを追加します。
    ビルドを高速化する際のおすすめの方法 - カスタム仮想マシンサイズを使用する

サンプル コンフィグ

関係するデザインパターン