Spinnaker と Kubernetes Engine を使用した継続的デリバリー パイプライン

このチュートリアルでは、Google Kubernetes Engine(GKE)、Cloud Source Repositories、Cloud Build、Spinnaker for Google Cloud を使用して、継続的デリバリー パイプラインを作成する方法について説明します。サンプルアプリを作成した後、これらのサービスを自動的にビルド、テスト、デプロイするように構成します。アプリコードを変更すると、継続的デリバリー パイプラインがトリガーされ、新しいバージョンが自動的に再ビルド、再テスト、再デプロイされます。

State of DevOps で、ソフトウェア デリバリーのパフォーマンスを向上させると認められた機能が報告されています。このチュートリアルは、次の機能について説明します。

パイプライン アーキテクチャ

次の図は、継続的デリバリー パイプラインのアーキテクチャを示しています。

デベロッパーとユーザーのためのパイプラインのアーキテクチャ。

アプリの更新を継続的にユーザーに配布するには、ソフトウェアを確実にビルド、テスト、更新する自動プロセスが必要です。コードに加えた変更は、アーティファクトの作成、単体テスト、機能テスト、本番環境ロールアウトで構成されたパイプラインに自動的に届けられる必要があります。場合によっては、コードの変更をユーザーベース全体に配布する前にユーザーのサブセットにのみ適用し、実際の動作を確認したいケースもあるでしょう。こうしたカナリアテストのいずれかで不十分なことが判明した場合は、ソフトウェアの変更を自動プロセスですばやくロールバックできる必要があります。

GKE と Spinnaker を使用すると、安定的な継続的デリバリー フローを作成することができます。これにより、ソフトウェアを開発して検証したらすぐに出荷できるようになります。最終的には迅速なイテレーションが目標になりますが、アプリの更新が本番環境ロールアウトの候補になる前に、必ず一連の自動検証を受けるようにする必要があります。特定の変更を自動化プロセスで検査し、アプリ全体を手動で検証して、その後プレリリース テストを実施することも可能です。

アプリが本番環境用として準備が整ったとチームで判断できたら、チームメンバーの 1 人が本番環境デプロイメント用として承認することができます。

アプリ デリバリー パイプライン

このチュートリアルでは、次の図に示す継続的デリバリー パイプラインを構築します。

アプリ デリバリー パイプラインのアーキテクチャ。

このパイプラインの手順の概略は次のとおりです。

  1. デベロッパーがコードを変更してリポジトリに push します。

  2. Cloud Build によって、変更が検出され、Docker イメージのビルドとテストが行われてから Spinnaker にイメージが push されます。

  3. Spinnaker はイメージを検出すると、そのイメージを Canary にデプロイして、Canary デプロイメントのテストを行います。手動で承認すると、Spinnaker によってそのイメージが本番環境にデプロイされます。

目標

  • Cloud Shell を起動して、Spinnaker for Google Cloud Platform をデプロイし、環境をセットアップする。
  • サンプル アプリケーションをデプロイするために GKE クラスタを作成する。
  • サンプルアプリのダウンロード、Git リポジトリの作成、Cloud Source Repositories へのアップロードを行う。
  • Docker イメージをビルドする。
  • アプリが変更されたときに Docker イメージを作成するためのトリガーを作成する。
  • 確実かつ継続的にアプリを GKE にデプロイするように Spinnaker パイプラインを構成する。
  • コード変更をデプロイしてパイプラインをトリガーし、本番環境へのロールアウトを監視する。

費用

このチュートリアルでは、Google Cloud の課金対象となる以下のコンポーネントを使用します。

  • GKE
  • Cloud Load Balancing
  • Cloud Build
  • Cloud Source Repositories
  • Container Registry

料金計算ツールを使うと、予想使用量に基づいて費用の見積もりを出すことができます。

新しい Google Cloud ユーザーは無料トライアルをご利用いただける場合があります。

始める前に

  1. Google アカウントにログインします。

    Google アカウントをまだお持ちでない場合は、新しいアカウントを登録します。

  2. Cloud Console のプロジェクト セレクタページで、Cloud プロジェクトを選択または作成します。

    プロジェクト セレクタのページに移動

  3. Google Cloud プロジェクトに対して課金が有効になっていることを確認します。プロジェクトに対して課金が有効になっていることを確認する方法を学習する

  4. GKE, Cloud Build, and Cloud Source Repositories API を有効にします。

    API を有効にする

環境の設定

このセクションでは、チュートリアルを実施するために必要なインフラストラクチャを構成します。

Cloud Shell を使用して Spinnaker for Google Cloud をデプロイする

このチュートリアルでは、Cloud Shell からすべてのターミナル コマンドを実行します。

Spinnaker for Google Cloud Platform を使用すると、Google Cloud 向けに最適化され、本番環境に対応した構成で Spinnaker をセットアップして管理できます。Spinnaker for Google Cloud は、リソース(GKE、Memorystore、Cloud Storage バケット、サービス アカウント)を設定し、Spinnaker を Cloud Build などの関連サービスと統合して、Spinnaker のインストールに使用する Cloud Shell ベースの管理環境をヘルパーや一般ツール(spinhal など)とともに提供します。

  1. Cloud Shell で Spinnaker for Google Cloud を開きます。これにより、Cloud Shell 環境に Spinnaker for Google Cloud リポジトリのクローンが作成され、詳細なインストール手順が起動します。

    Cloud Shell に移動

  2. Git を構成します。以前に Git を構成したことがある場合は、この手順をスキップできます。

    git config --global user.email "EMAIL_ADDRESS"
    git config --global user.name "USERNAME"
    

    次のように置き換えます。

    • EMAIL_ADDRESS: Git メールアドレス
    • USERNAME: Git ユーザー名
  3. 環境変数を設定して、Spinnaker をインストールする Cloud プロジェクトを定義します。

    DEVSHELL_PROJECT_ID=YOUR_PROJECT_ID
    

    YOUR_PROJECT_ID は、このチュートリアルで選択または作成したプロジェクトで置き換えます。

  4. Spinnaker for Google Cloud をインストールします。

    PROJECT_ID=${DEVSHELL_PROJECT_ID} ~/cloudshell_open/spinnaker-for-gcp/scripts/install/setup_properties.sh
    ~/cloudshell_open/spinnaker-for-gcp/scripts/install/setup.sh
    
  5. Cloud Shell を再起動して、新しい環境設定を読み込みます。

    Cloud Shell の再起動メニュー オプション。

  6. Spinnaker に接続します。

    ~/cloudshell_open/spinnaker-for-gcp/scripts/manage/connect_unsecured.sh
    
  7. Cloud Shell で [ウェブでプレビュー] アイコンをクリックし、[ポート 8080 でプレビュー] を選択します。

    Cloud Shell ウェブ プレビュー

  8. ようこそ画面が表示されてから、Spinnaker UI が表示されるはずです。

    Spinnaker のようこそ画面。

    Spinnaker UI。

アプリケーション デプロイ用の GKE クラスタを作成する

ある GKE クラスタをビルドやデプロイなどに使用したら、アプリケーションの実行には他の GKE クラスタを使用するのが一般的です。このセクションでは、別の GKE クラスタ app-cluster を作成してサンプル アプリケーションをデプロイします。

  1. Cloud Shell で、新しい GKE クラスタを作成します。

    ZONE=us-east1-c
    gcloud config set compute/zone $ZONE
    gcloud container clusters create app-cluster \
    --machine-type=n1-standard-2
    
  2. 新しい GKE クラスタを Spinnaker に追加します。デフォルト値はそのまま使用できるはずです。

    ~/cloudshell_open/spinnaker-for-gcp/scripts/manage/add_gke_account.sh
    

    出力例と値:

    Please enter the context you wish to use to manage your GKE resources: gke_spinnaker-246920_us-east1-c_app-cluster
    Please enter the id of the project within which the referenced cluster lives: spinnaker-246920
    Please enter a name for the new Spinnaker account: app-cluster-acct
    

  3. kubernetes コンテキストを Spinnaker クラスタに変更します。

    kubectl config use-context gke_${DEVSHELL_PROJECT_ID}_${ZONE}_spinnaker-1
    
  4. 構成の変更を Spinnaker に push して適用します。

    ~/cloudshell_open/spinnaker-for-gcp/scripts/manage/push_and_apply.sh
    

Docker イメージのビルド

このセクションでは、アプリ ソース コードの変更を検出して Docker イメージをビルドしてから、Container Registry に push するように Cloud Build を構成します。

ソースコード リポジトリを作成する

  1. Cloud Shell で、サンプル ソース コードをダウンロードします。

    cd ~
    wget https://gke-spinnaker.storage.googleapis.com/sample-app-v4.tgz
    
  2. ソースコードを展開します。

    tar xzfv sample-app-v4.tgz
    
  3. ディレクトリをソースコードに変更します。

    cd sample-app
    
  4. ソースコード リポジトリへの最初の commit を行います。

    git init
    git add .
    git commit -m "Initial commit"
    
  5. コードをホストするリポジトリを作成します。

    gcloud source repos create sample-app
    git config credential.helper gcloud.sh
    
  6. 新しく作成したリポジトリをリモートとして追加します。

    export PROJECT=$(gcloud info --format='value(config.project)')
    git remote add origin https://source.developers.google.com/p/$PROJECT/r/sample-app
    
  7. コードを新しいリポジトリのマスター ブランチに push します。

    git push origin master
  8. コンソールにソースコードが表示されることを確認します。

    [ソースコード] ページに移動

ビルドトリガーを構成する

次の図は、このセクションで作成するトリガーです。

Spinnaker のワークフロー

Git タグをソース リポジトリに push するたびに Docker イメージのビルドと push が行われるように Cloud Build を構成します。Cloud Build はソースコードを自動的にチェックアウトして、リポジトリ内の Dockerfile から Docker イメージをビルドし、そのイメージを Container Registry に push します。

  1. Cloud Console の [Cloud Build] セクションで、[トリガー] をクリックし、[トリガーを作成] をクリックします。

    [トリガー] ページに移動

  2. 次のトリガー設定を指定します。

    • 名前: sample-app-tags
    • イベント: [新しいタグを push する] を選択します。
    • リポジトリ: sample-app
    • タグ(正規表現): v.*
    • ビルド構成: /cloudbuild.yaml
  3. [作成] をクリックします。

    トリガーを作成するときのトリガー設定。

これ以降、文字「v」が先頭に付いている Git タグをソースコード リポジトリに push すると、Cloud Build が自動的にアプリをビルドして、Docker イメージとして Container Registry に push します。

Spinnaker で使用するために Kubernetes マニフェストを準備する

Spinnaker は、クラスタにデプロイするために Kubernetes マニフェストにアクセスする必要があります。このセクションでは、Cloud Build での CI プロセス中にマニフェストを保存する Cloud Storage バケットを作成します。マニフェストが Cloud Storage に保存されると、Spinnaker はパイプラインの実行中にマニフェストをダウンロードして適用できます。

  1. バケットを作成します。

    export PROJECT=$(gcloud info --format='value(config.project)')
    gsutil mb gs://$PROJECT-kubernetes-manifests
    
  2. バケットに対するバージョニングを有効にして、マニフェストの履歴を取得します。

    gsutil versioning set on gs://$PROJECT-kubernetes-manifests
    
  3. Kubernetes デプロイ マニフェストで正しい Google Cloud プロジェクト ID を設定します。

    sed -i s/PROJECT/$PROJECT/g k8s/deployments/*
    
  4. リポジトリへの変更を commit します。

    git commit -a -m "Set project ID"
    

デプロイメント パイプラインの構成

これでイメージが自動的にビルドされるようになりました。それらを Kubernetes クラスタにデプロイする必要があります。

次の図は、デプロイメント パイプラインの手順を示しています。

デプロイメント パイプラインを構成する

統合テストに備えてスケールダウンされた環境にデプロイします。統合テストに合格したら、コードを本番環境サービスにデプロイするための変更を手動で承認する必要があります。

デプロイメント パイプラインを作成する

  1. spin を使用して Spinnaker でアプリを作成します。

    spin application save --application-name sample \
                          --owner-email example@example.com \
                          --cloud-providers kubernetes \
                          --gate-endpoint http://localhost:8080/gate
    

    次に、継続的デリバリー パイプラインを作成します。このチュートリアルでは、v で始まるタグが付いた Docker イメージが Container Registry に到着したことを検出するようにパイプラインが構成されます。

  2. Cloud Shell の新しいタブで、ソースコード ディレクトリで次のコマンドを実行し、パイプラインの例を Spinnaker インスタンスにアップロードします。

    export PROJECT=$(gcloud info --format='value(config.project)')
    sed s/PROJECT/$PROJECT/g spinnaker/pipeline-deploy.json > pipeline.json
    spin pipeline save --gate-endpoint http://localhost:8080/gate -f pipeline.json
    

イメージをビルドする

次の手順で最初のイメージを push します。

  1. Cloud Shell でソースコード フォルダに移動します。
  2. Git タグを作成します。

    git tag v1.0.0
  3. タグを push します。

    git push --tags
  4. [Cloud Build] で [履歴] をクリックし、ビルドがトリガーされたことを確認します。トリガーされていない場合は、前のセクションでトリガーが適切に構成されたことを確認します。

    [ビルド履歴] に移動

    ビルド履歴

パイプラインの実行を表示する

作成した構成は、Spinnaker パイプラインをトリガーするためにプッシュされる新しくタグ付けされたイメージの通知を使用します。前のステップでは、タグを Cloud Source Repositories に push しました。これによって、Cloud Build でイメージの構築と Container Registry への push がトリガーされます。これで、トリガーされたパイプラインを確認できるようになります。

  1. [パイプライン] をクリックして、パイプラインのページに戻ります。

  2. [詳細] をクリックして、パイプラインの進行状況の詳細を表示します。このセクションで、デプロイメント パイプラインのステータスとそのステップを確認できます。青色のステップは現在実行中です。緑色は正常に完了したステップ、赤色は失敗したステップを示します。ステージをクリックして、その詳細を表示します。

    3~5 分後に統合テストフェーズが完了し、デプロイメント続行のための手動承認をパイプラインから要求されます。

  3. [Push to production] の上にポインタを置き、[Continue] をクリックします。

    ロールアウトが本番環境フロントエンドと本番環境バックエンドのデプロイメントに進みます。これは数分後に完了します。

  4. Spinnaker UI の上部で [Infrastructure] > [Load Balancers] をクリックして、アプリを表示します。

    ロードバランサが選択された [Infrastructure] プルダウン リスト。

  5. ロードバランサのリストを下にスクロールし、[sample-frontend-production] の下の [Default] をクリックします。

    デフォルトのロードバランサ

  6. 右側の詳細ウィンドウを下にスクロールし、Ingress IP のクリップボード ボタンをクリックしてアプリの IP アドレスをコピーします。Spinnaker UI からの上り IP リンクはデフォルトで HTTPS を使用しますが、アプリケーションは HTTP を使用するように構成されています。

    アプリの IP アドレスを含む詳細ペイン。

  7. アドレスをブラウザに貼り付けて、アプリの本番環境バージョンを表示します。

    アプリの本番環境バージョン。

    これで、アプリをビルド、テスト、デプロイするためのパイプラインを手動でトリガーしました。

コードの変更によるパイプラインのトリガー

このセクションでは、コードの変更、Git タグの push、レスポンスでのパイプライン実行の監視を通して、パイプラインをエンドツーエンドでテストします。"v" で始まる Git タグを push すると、新しい Docker イメージをビルドして Container Registry に push するための Cloud Build がトリガーされます。Spinnaker は新しいイメージタグが "v" で始まることを検出すると、イメージをカナリアにデプロイしてテストを実行し、同じイメージをデプロイメント内のすべてのポッドにロールアウトするためのパイプラインをトリガーします。

  1. アプリケーションの色をオレンジ色から青色に変更します。

    cd ~/sample-app
    sed -i 's/orange/blue/g' cmd/gke-info/common-service.go
    
  2. 変更にタグを付け、ソースコード リポジトリに push します。

    git commit -a -m "Change color to blue"
    git tag v1.0.1
    git push --tags
    
  3. 新しいビルドが Cloud Build のビルド履歴に表示されます。

  4. [パイプライン] をクリックして、パイプラインがイメージのデプロイを開始するのを監視します。

  5. カナリア デプロイを観察します。デプロイが一時停止し、本番環境へのロールアウトを待機している間に、アプリが表示されているタブを更新してください。バックエンドのうちの 4 つがアプリの以前のバージョンを実行しており、カナリアを実行しているバックエンドは 1 つだけです。10 回更新するごとにアプリの新しい青色バージョンが表示されます。

  6. テストが完了したら、[Spinnaker] タブに戻り、デプロイを承認します。

  7. パイプラインが完了すると、アプリは次のスクリーンショットのようになります。[バージョン] フィールドが v1.0.1 になりました。

    更新されたアプリの本番環境バージョン。

    これで、アプリを本番環境全体に正常にロールアウトできました。

  8. 必要に応じて、前回の commit を元に戻して、この変更をロールバックできます。ロールバックすると新しいタグ((v1.0.2)が追加され、v1.0.1 をデプロイするときに使用したのと同じパイプラインを通してタグが戻されます。

    git revert v1.0.1
    git tag v1.0.2
    git push --tags

クリーンアップ

このチュートリアルで使用したリソースについて、Google Cloud Platform アカウントに課金されないようにする手順は次のとおりです。

  1. Spinnaker for Google Cloud を削除します。

    cd ~
    ~/cloudshell_open/spinnaker-for-gcp/scripts/manage/generate_deletion_script.sh
    ~/cloudshell_open/spinnaker-for-gcp/scripts/manage/delete-all_${DEVSHELL_PROJECT_ID}_spinnaker-1_spinnaker-1.sh
    
  2. GKE クラスタを削除します。

    gcloud container clusters delete app-cluster --zone=us-east1-c
    
  3. リポジトリを削除します。

    gcloud source repos delete sample-app
    
  4. バケットを削除します。

    export PROJECT=$(gcloud info --format='value(config.project)')
    export BUCKET=$PROJECT-kubernetes-manifests
    gsutil -m rm -r gs://$BUCKET
    
  5. コンテナ イメージを削除します。

    export PROJECT=$(gcloud info --format='value(config.project)')
    gcloud container images delete gcr.io/$PROJECT/sample-app:v1.0.0
    gcloud container images delete gcr.io/$PROJECT/sample-app:v1.0.1
    
  6. 上記のオプションのロールバック ステップで v1.0.2 を作成した場合は、そのコンテナ イメージを削除します。

    gcloud container images delete gcr.io/$PROJECT/sample-app:v1.0.2
    

次のステップ