はじめに
第1章 Spinnakerとは
第2章 Spinnakerのインストール
第3章 Google Kubernetes Engine のデプロイ
第4章 Google App Engineのデプロイ
第5章 Canary Release
第6章 Amazon EKSにSpinnakerをインストール
第7章 Jenkinsとの連携
第8章 GCPにおけるGitOps継続的デリバリー
第9章 AWSにおけるGitOps継続的デリバリー
付録A GCPアカウントの作成
付録B AWSアカウントの作成、初期設定
本書は、Spinnakerを使ったKuberntesやGoogle App Engineアプリケーションのデプロイ、カナリアリリースについて詳しく解説しています。本書はアプリケーション開発者、SRE、DevOps、インフラエンジニアといった方々を対象にしています。本書で取り扱うGoogle Cloud Platform(GCP)やAmazon Web Services(AWS)、Spinnakerについてはできる限り図を用いて解説しているため、初心者でも本を読み進めながら手を動かして理解できると思います。
SpinnakerはOSSの継続デリバリーツールです。AWS、GCP、Microsoft Azureなど、特定のクラウドに固定されず、またKubernetes、仮想マシン、PaaS(Google App Engine)など様々な環境に対応できるように開発されています。クラウドネイティブ界隈で話題となっているSpinnakerですが、まだまだ導入事例が少ないため、ドキュメントが足りなかったり、バグを踏んだりと思うようなことができないことがしばしばあります。地道にドキュメントやソースコードを紐解いていけばいずれは使えるようになりますが、ハードルが高いと言わざるを得ません。せめて最初のとっかかりだけでも、一連のデプロイフローの構築だけでも解説してくれる本が欲しいと思ったことから、本書を執筆するに至りました。同じような想いがある方、Spinnakerを聞いたことがあるから触ってみたい方には本書が適していると思いますので、ぜひお手に取って、手を動かしてもらえれば幸甚です。
どなたにも読んでいただきたいのですが、以下に該当する方であればよりこの本の目的に一致すると思います。
・Spinnakerについて聞いたことがあるけど試したことが人
・Spinnakerを試してみたけどドキュメントがわかりにくくて挫折した人
・Kubernetes、Google App Engineのデプロイについて悩んでいる人
・カナリアリリースをやってみたい人
・Google Cloud Platformに触れてみたい人
・Amazon Elastic Kubernetes Service(Amazon EKS)でSpinnakerを使ってみたい人
本書ではGCPおよびAWSにおいて実行環境が異なります。GCPはCloud Shell、AWSはAWS Cloud9というクラウド開発環境で操作するため、お手元のPCはWindows、MacOS、Linuxのいずれも構いません。本書でインストールしたSpinnakerのバージョンは次のとおりです。
・Halyard 1.26.0
・Spinnaker 1.17.0
本書はGCPおよびAWSにSpinnakerをインストールします。GCPの場合は次のサービスを利用します。
・Cloud Load Balancing
・Cloud Memorystore for Redis
・Cloud Storage
・Google Kubernetes Engine1
・Google App Engine
リージョンやインスタンスタイプによりますが、私が試したところ1日に約$20請求されました。GCPをはじめて登録した人は$300の無料枠がもらえるので、2週間程度なら削除せずに動かしても無料枠に収まるでしょう。もし支払いをしたくない方は、使わないリソースを削除して節約に努めましょう。「2.5 リソースの削除」で削除方法を説明します。
AWSは以下の料金が請求されます。残念なことに無料枠外であるため、使った分だけ請求されます。使わない場合は「6.11 リソースの削除」を参考にリソースを削除して支払い金額を押さえるように努めましょう。
・Amazon EC2 Cloud9(t2.micro): $0.011/時間
・Amazon EKS クラスタ: $0.20/時間
・Amazon EC2 ノード(t3.large×3): $0.25/時間
・Elastic Load Balancer ×2: $0.054/時間
本書ではいくつかのサンプルコードを使用します。
Guestbook application on Kubernetes(第3章、第5章、第8章)
https://github.com/kubernetes/examples/tree/master/guestbook
Photo Album Example(第4章)
https://github.com/GoogleCloudPlatform/appengine-photoalbum-example
サンプルコードはGitHubに公開しています。
https://github.com/ohsawa0515/techbookfest7-spinnaker-sample.git
本書を執筆するにあたり、参考にさせていただいた本やサイトです。
・『Spinnaker』 https://www.spinnaker.io/
・北山 晋吾・早川 博(2019年)『Kubernetes実践ガイド クラウドネイティブアプリケーションを支える技術』株式会社インプレス
・『Continuous Delivery With Spinnaker』 https://www.spinnaker.io/publications/ebook/
会社の同僚である赤羽智幸さんに、レビューおよび技術書典7の売り子にとしてご協力いただきました。入稿まで時間がない中で的確な指摘をいただき、誠にありがとうございます。
執筆期間中に、休日も育児と家事に専念してくれた妻と、休日もあまり遊んであげられなくて辛い思いをさせてしまった息子には心からの謝罪と、その協力に心から感謝します。
本書に記載された内容は、情報の提供のみを目的としています。したがって、本書を用いた開発、製作、運用は、必ずご自身の責任と判断によって行ってください。これらの情報による開発、製作、運用の結果について、著者はいかなる責任も負いません。
本書に記載されている会社名、製品名などは、一般に各社の登録商標または商標、商品名です。会社名、製品名については、本文中では©、®、™マークなどは表示していません。
本書籍は、技術系同人誌即売会「技術書典」で頒布されたものを底本としています。
Spinnaker(スピネーカー)1はオープンソースの継続的デリバリーツールです。元々はNetflixで開発されていましたが、2015年にオープンソースとして公開されました。現在ではGoogleをはじめMicrosoft、Oracleなど多くの企業が開発に参加しています。2019年3月に設立されたContinuous Delivery Foundation(CDF)2にホストされているプロジェクトのひとつでもあります。CDFは開発者、エンドユーザー、ベンダー間のコラボレーションを促進し、継続的インテグレーション・継続的デリバリーおよびDevOps手法の普及、ベストプラクティスの定義を目的とした団体で、Jenkins3、Jenkins X4、Tekton5もホストされています。
Spinnakerには次のような特徴があります。
Amazon Web Services(AWS)、Google Cloud Platform(GCP)、Microsoft Azure、Openstack、Oracle Cloudといった多くのIaaSに対応しています。また、コンテナオーケストレーションツールであるKubernetes以外にも、Amazon EC2、Google Compute Engine(GCE)といった仮想マシンやGoogle App Engine(GAE)にも対応しています。
ステージと呼ばれる任意のアクションをパイプライン上で定義することで、デプロイフロー(パイプライン)を構築できます。条件分岐や手動承認、別のパイプライン呼び出しなど柔軟に設定できます。設定はすべてGUI(Webブラウザー)で行えるため、コマンド操作が苦手な人でも設定できます。
SpinnakerはBlue/Green Deployment6を標準でサポートしています。Blue/Green Deploymentを実装した方であれば分かると思いますが、インスタンスやクラスタの入れ替え処理に加え、エラー処理やロールバックなどしっかり実装するとなるとかなりの労力が必要になります。さらに複数のクラウドやプラットフォームに対応となるとさらに困難になるでしょう。そうした複雑な処理でも設定ひとつでクラウドやプラットフォームにそって「いい具合に」デプロイしてくれます。もちろんロールバックなども対応できます。
また、追加設定が必要になりますが、一部のサーバーのみをデプロイするCanary Releaseにも対応しています。既存アプリケーションと新バージョンのアプリケーションのレイテンシーやエラー数を集計、比較することでスコア化してリリースすべきかを自動的に判定する自動カナリア分析機能も備えています。
Spinnakerでは仮想マシンのイメージ作成や仮想マシン・コンテナのデプロイ、スケーリングといったアプリケーション管理機能を、Bake、Deploy、Clusterといった抽象化した用語で表現します。同じような機能や概念でもIaaSによって名前が異なるため、抽象化することでマルチクラウドでも同じ用語でクラウドリソースを取り扱うことができます。
アプリケーション管理機能によって、クラウドリソースの表示、変更などの操作を司ります。重要な概念として、Instance、Server Group、Cluster、Applicationがあります(図1.1)。
仮想マシン(Virtual Machine; VM)を表します。AWSであればAmazon EC2、GCPであればGCE、KubernetesであればPodを指します。
Instanceをグループ化したものです。AWSであればAuto Scaling Group、GCPであれば Managed Instance Group、KubernetesであればReplicaSetを指します。
Server Groupにはデプロイ可能なアーティファクト7(VMイメージ、Dockerイメージ、マニフェスト)、インスタンス数、オートスケーリングポリシーから構成されています。
Server Groupを論理的にグループ化したものです。Spinnaker上でグルーピングされたものにすぎないため、AWSやGCPには一致する概念がありません。
Clusterをグループ化したもので、パイプラインやインフラストラクチャから構成されています。Spinnakerの思想として、通常はマイクロサービス1つにつき、1つのApplicationとします。また、開発、ステージング、本番といった環境ごとにApplicationを分離せず、ひとつのApplicationにまとめます。これは多くの場合、環境ごとにデプロイするパイプラインがあり、ステージング環境へのデプロイがトリガーとなって本番環境へのデプロイパイプラインが実行されることを想定して、ひとつのApplicationに複数のパイプラインを含めます。
Applicationを構成するインフラストラクチャーとしては、先ほど説明したCluster、Server Groupの他に、FirewallとLoad Balancerも含まれます(図1.2)。
TCPなどの通信プロトコルや、ポート、IPアドレスを指定することで、ネットワークトラフィックアクセスを制御します。AWSであればセキュリティグループ、GCPであればファイアウォールルールを指します。
Server Group内のインスタンス間のトラフィックを負荷分散します。また、必要に応じてヘルスチェック8を有効化し、インスタンスまたはサービスの状態をチェックします。
Spinnakerは、デプロイやインフラストラクチャーに対する制御などのフローをPipelineという形で構築、管理します。Pipelineは実行するアクションを定義するStageと、パイプラインの開始を制御するTrigger、パイプラインの開始、成功、失敗時に通知するNotificationから構成されています。
Stageはそれ自体が独立したアクションを記述しており、組み立てることでパイプラインを形成します。また、パイプラインにそって、ステージからステージへとパラメータを渡すこともできます。
Stageは基盤となるインフラストラクチャーを構築するInfrastructure Stage、外部システムとの連携を行うExternal Systems Integrations、パイプラインの流れを制御するControlling Flowの3つに分類されます。
Infrastructure Stageはリソース作成、変更、削除など基盤となるインフラストラクチャーを構築するステージです。
主なステージは次のとおりです。
・Bake(VMイメージ、Dockerイメージの生成)
・Find Image From Tag(リソースに付与されたタグからイメージを特定し、後続ステージで利用する)
・Deploy(Blue/Green Deployment、マニフェスト適用など)
・Cluster のスケールアップ、ダウン、ロールバック、無効化
・Server Group のクローン、有効、無効、リサイズ、破棄
・Run Job(コンテナを実行)
・Script(Jenkins上でジョブ実行)
External Systems Integrationsは外部システムとの連携を担うステージです。継続的インテグレーション(Continuous Integration; CI)サービスをトリガーとして、パイプラインを実行することができます。
Spinnakerと連携できるCIサービスは次のとおりです。
・Jenkins
・Travis CI
・Wercker
・Concourse CI
Webhookからトリガーすることもできます。SpinnakerにHTTP POSTリクエストを送ることで、任意のパラメータをパイプラインに渡すこともできます。
Controlling Flowはパイプラインの流れを制御するステージです。主なステージは次のとおりです。
・Check Preconditions(条件分岐)
・Manual Judgement(手動承認)
・Wait(指定された秒数を待機)
・Pipeline(別のパイプラインを実行)
トリガーはパイプラインの開始を制御します。
時間ベースのトリガーとしては、
・Manual(手動実行)
・Cron(時間指定)
があります。
イベントベースのトリガーとしては主に次に挙げるものがあります。
・Git(GitHub、GitLab)
・CIサービス(Jenkins など)
・Docker Registry(Docker Hub、Amazon ECR、Google Container Registry など)
・Pipeline(別のパイプラインを実行)
・Google Cloud Storage(GCS)9
・Pub/Sub(Cloud Pub/Sub、Amazon SNS など)
イベントベースのトリガーはアーティファクトをパイプラインに渡すことができます。たとえば、GCSはアーティファクトをGCSバケットに置くと、そのイベントを検知してGCSバケット名やファイル名がパイプラインに渡ります。GitHubはGit Pushなどリポジトリーの変更に基づいてリポジトリー名やブランチ名などがパイプラインに渡ります。
パイプラインの開始、成功、失敗を通知することができます。また、各ステージでも通知が可能なので、デプロイステージになった場合にSlackで開発者にメンションして知らせることもできます。
対応している通知先は次のとおりです。
・Slack
・SMS(Twilio)
・Pub/Sub
Pub/Subを活用することで、上記以外の通知先にも対応できますし、Spinnakerから別システムへの連携もできます。