cdどうも、もうすぐ大学卒業の@timtimtim1026です。コメントなどがございましたらDMなり、リプライしてください。Calendarの14日目の記事になっています。本記事この記事では、CircleCIを使ってSpinnakerのデプロイメントパイプラインをデプロイする方法を解説します。twitter.com今回の目的としては、CircleCIを使いながら継続的デリバリー(以下、CD)を構築する一例を知ってもらうことです。そのなかで紹介するCircleCIの知識が何かしら役に立てられればいいなと思います。考え方としては、今回使うCircleCIやSpinnakerに限らずあらゆるCDにも、CIにも言えることなのでSpinnakerだけに限った話ではありません。実は、以前(2018年4月ごろ)にSpinnakerを用いて宣言的継続的デリバリーというものを提案しました。継続的デリバリーのためのデプロイメントパイプラインも宣言的に、かつ、イミュータブルにしようというアイデアでした。www.1915keke.comこの記事はデプロイメントパイプラインをCircleCIを使ってデプロイするための記事なので注意してください。コードの更新からデプロイまで以下のような流れがあるフローだと本記事では赤枠の箇所に対応しています。コンテンツ本記事では以下のセクションで構成されています。最終的なWorkflowそのあとの話Mergeによるデプロイメントパイプラインの更新アプリケーションが運ばれる流れCI/CDの恩恵まとめSpinnakerとはSpinnakerとはオープンソースな高速に安全に継続的デリバリーをするプラットフォームです。公式サイトは以下のサイトにあるのでご覧ください。Templateというものがあります。Templateという再利用可能なモジュールのようなものに、設定値を渡すとPipelineを生成することができます(もちろんいきなりPipelineを作ることもできます)。Templateによって生成されたPipelineはImmutableであり、宣言的なデプロイメントパイプラインを作ることができます。CircleCIを使うことによって自動化をすることができます。GitOpsのような考えに近いのですが、設定ファイルをリポジトリに書いて、CIによって適宜Pipelineをデプロイします。ブランチごとにfilterしたりできますが、宣言的に継続的にデプロイメントパイプラインを配置して、それに沿ってデプロイすることができるわけです。デプロイメントパイプラインとは少し深くデプロイメントパイプラインに注目します。デプロイメントパイプラインとは要求された環境へ移行する一連の過程のことです。再度、Slack通知などデプロイといってもいろんな過程があります。Spinnakerでは宣言的に書いて、容易にカナリアデプロイやBlue/Greenデプロイ、Red/Blackデプロイをすることができます。継続的デリバリーの観点だと、デプロイまで携わってないチームメンバーがいるなら継続的デリバリーはできていないです。すべての更新がすぐさまデリバリーする必要があります。以下の画像は実際にSpinnakerで定義してみたパイプラインです。古いサーバーを削除して、「カナリアデプロイが成功したこと」をSlackに通知で構成されています。仮にカナリアで何かしらのバグがあって、システムが落ちるようなことがあっても、トラフィックを切って元の安全なバージョンを使い続けることができ、逆にうまくデプロイできたら古いバージョンを削除して、安全にバージョンアップをすることができます。Templateのテンプレート機能を用いるとPipeline自体がImmutableになるので安全で運用がしやすいです。SpinnakerのCLIツールCIからデプロイをするので今回はroerというSpinnaker公式CLIツールを使います。実はCLIツールには二つ種類があってroerspinがあります。GUIからでもデプロイメントパイプラインを定義することはできます。このCLIツールを少し紹介してみます。Roergithub.com現在はメンテナンスモードで開発は行われていません。安定性を求めるならば、このCLIツールを選定してもいいかもしれません。サブコマンドもpipeline、pipeline-templateなど、やりたいことと機能が一致しており、使いやすい点もポイントかなと思います。この記事ではroerを使います。use.と書いてあり、まだプロダクション環境で使うのは控えた方がいいでしょう。CLIツールといえどSpinnaker自体の機能はroerを使っても変わらないため、サポートの状況を見る必要があります。github.comしかしながら、こちらをフィードしておくといいかもしれません。roerからデプロイするここからはValueを渡して、実際にSpinnakerのデプロイメントパイプラインを構築するための方法を解説します。ローカル環境から試すまず、最初にCIではなくてローカル環境からデプロイする方法を解説します。CIで実践する前にローカルで実行できると、あとからわかりやすくなると思います。roerでは以下のようなYAMLファイルを書きます。今回は.spinnaker/config.ymlに保存していますがファイル名と保存先は任意です。SpinnakerのインスタンスなりVMからポート転送してlocalhost:8084でアクセスできるものとします。Templateを用意します。Templateを参照しています。深くはSpinnakerの機能なので解説しません。saveコマンドを使って以下のようにデプロイすることができます。/go/src/github.com/KeisukeYamashita/advent-article/.spinnaker/config.yml環境変数SPINNAKER_APIでリクエスト先を指定することになっていて、設定されていないとエラーになります。どのようにCircleCIでやるのか手順としては簡単です。ローカル環境でやらせているものをCircleCIにやらせたらいいのです。GithubのPushがトリガーになります。手順をおって説明します。SpinnakerのAPIサーバーにCircleCIからアクセスをするまず、sshでCircleCIからGCPにアクセスをするのでサービスアカウントが必要になりますのでGCPのコンソールで作成してください。サービスアカウント秘密鍵(json)を作成してクリップボードにコピーします。pbcopyそしてCircleCIのSecretにGCLOUD_SERVICE_ACCOUNTに保存します。CircleCIではContextsで設定をすることができます。詳しいドキュメントは以下のリンクで確認してください。circleci.com簡単にいうと環境変数などをKey-Valueで渡せるものです。Contexts名はgcloud-contextと指定します。これがKeyとなります。ここで追加でzone情報も追加しました。次にCircleCIのJobとして定義します。アンカーで定義しているので抜粋しました。アンカー名はgcloud_authです。-fN簡単に説明するとechoでファイルにサービスアカウントキーを書き出すgcloudをアクティベートsshで接続し、ポート転送をしているサービスアカウントは最低限の権限だけ渡すようにしてください。デプロイメントパイプラインをデプロイする以下のようにデプロイします。アンカー部分を取り出したものです。deploy_pipelineとアンカーを名付けました。saveをしています。Jobを定義、WorkflowにまとめるCircleCIでは一つのタスクのまとまりとしてJobとして定義します。Jobを以下のように定義しました。deploy_spinnaker_pipelineが一つのJobです。*kill_gcloud_sshここでは勝手にroerのテストを挟んでいます。Testはroerのtestコマンドを叩いて実行しています。以下のようにWorkflowにまとめます。develop今のところ、簡単ですが流れとしてはこのようになっています。ここではfiltersによってブランチでフィルタリングをかけています。requiresによって並列ジョブと逐次ジョブを指定することができ、スケジューリングすることができます。順序性がなければ並列化してワークフローを速く終えることができます。circleci.comまた、build_and_test_and_deployはtestが成功したときに走るように設定しています。RegistryにPushすることを追加してもいいかもしれません。Registryを設定することもできるので、トリガーを発せられるようになります。developまたSlackに通知を送るwebhookも指定します。Webhookを使っていて、URLをさらにContextで渡しています。用途としては、ワークフローの途中経過をフィードバックしたいからです。最終的なWorkflowGithubにデプロイメントパイプラインのリポジトリをPushすると以下のようにWorkflowがはしります。build_image_and_push_gcrによってデプロイしたパイプラインでのトリガーとなって、Spinnakerによってデプロイされるようになっています。最終的な流れとしては以下のようになっています。そのあとの話Mergeによるデプロイメントパイプラインの更新デプロイメントパイプラインはブランチごとなど、必要に応じて定義できて、実行できます。今回だと.spinaker/config.ymlのように設定ファイルでしかないので、ブランチ間の差分を読むことによってデプロイメントパイプラインの差分がわかります。config.ymlファイルがデプロイメントパイプラインを宣言的にすべてを記述しているのでGitOpsということができます。configを読めばデプロイメントパイプラインがわかるconfigを書けばデプロイメントパイプラインを宣言できるその仕組みを今回、CircleCIにやってもらったわけです。アプリケーションが運ばれる流れデプロイメントパイプラインとアプリケーションの更新が同時である必要はないですが、今回は説明のために同時に説明します。エンジニアがアプリケーションに対して差分をPushしたとします。この差分にはデプロイメントパイプラインの更新アプリケーションの更新があったとします。次にその差分がMasterブランチにマージされてCIがトリガーされたとします。ここからが醍醐味なのですが、まずデプロイメントパイプラインの更新をします。差分が追加されました。これによってデプロイメントパイプラインは最新の差分を含んでいることになります。次にGCRに新しいアプリケーションのイメージをPushします。すると今回だとGCRの更新によってSpinnakerがトリガーされるので、トリガーされてアプリケーションはデプロイメントパイプラインを流れていきます。するとあとは自らが定義したデプロイメントパイプラインの出力先(例えばKubernetesクラスタ)などにデプロイされるだけです。この一連の流れをCircleCIとCDツールをもってして実現することができます。インフラもサーバーのこともよくわからない新米デザイナーがいたとしましょう。HTMLやCSSを軽くいじってPushして、チームリーダーにマージしてもらいました。CI/CDを敷いているおかげで、何もインフラなどは知らないのにデプロイをする(=開発した成果物を届ける)ことができます。Slack通知などの通知によるフィードバックはもちろんのことながらSpinnaker自体のGUIでもフィードバックを得られます。知らないというだけでなくて、安全に、チームだれもが、フィードバックを得ながらデプロイしていく、価値をユーザーに届けられるプラットフォームが実現したというわけです。まとめ今回はSpinnakerでやりましたが、CDのデプロイメントパイプライン自体をデプロイするためにCIを使う方法を紹介しました。CDやGitOpsについて記事をアップします。CDについて興味が出てきた人はぜひ見てみてください。ありがとうございました。私は以前、ポートフォリオサイトを作成しました。Pocket...2018-12-23Concourseで継続的デリバリー。»プロフィール学生エンジニア。忘れてしまうので備忘録です。flaskでServerlessにホストするTelepresence概論スターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。