Kekeの日記

エンジニア、読書なんでも

継続的デリバリーのためのGoCD on Kubernetes

f:id:bobchan1915:20190512212637p:plain

動機

GoCDって「Go」が一般性の高い言葉が故に、躓いたときに調べるのが面倒だなと思って避けてきました。

しかし、技術選定をする上で、一度は触っておかければならないと思ったので調査してみます。

いくつかの図は、本サイトから引用させていただいています。

アジェンダ

本記事のアジェンダは以下の通りです。

GoCD

GoCDについて大まかに纏めてみます。

目的としては、他のCDツールとの差分マップを頭の中で構築することです。

GoCDとは

公式サイトは以下の通りです。

www.gocd.org

GoCDとは、総合的なパイプラインデザインができる、チームへの可視化と操作のためにストリームマップを重視する継続的デリバリーのためのツールです

機能

継続的デリバリーツールと言われても、たくさんあるので選定には何かできるのかを知る必要があります。

1. 複雑なワークフローをモデリング

f:id:bobchan1915:20190512213305p:plain
Model complex workflows

並列かつ逐次実行でき、依存関係を簡単に定義できることで、早いフィードバックを可能にして、デプロイしたいものをデプロイできます。

ファンイン、ファンアウト、どちらも正しく終えられます。

2. 信頼のあるリモートのアップデート

f:id:bobchan1915:20190512213415p:plain
Promote trusted artifacts

差分によってパイプラインは紐づいており、何がデプロイされるのかが分かります。

3. ワークフローが機能するかをテストできる

f:id:bobchan1915:20190512213621p:plain
See how your workflow really works

E2Eでワークフローを可視化できることがGoCDの真なる力である。

一目で変化をしることができて、何かうまく行かなかったときはそれ自体も見ることができる。

4. どのバージョンも、いつでもデプロイできる

f:id:bobchan1915:20190512213732p:plain
Deploy any version, any time

マニュアルトリガーも用意されているので、手動でも可能です。Production環境へのPushの信頼性を向上して、自立性の高いチームを作ることができます。

5. テストを実行して、理解する

f:id:bobchan1915:20190512213850p:plain
Run and grok your tests

どのデプロイメントパイプラインの一部分も検証をすることができます。テストを実行することができて、GoCDのAgentは並行、およびクロスプラットフォーム実行を可能にします。テストレポーティングも充実しています。

6. ビルドの差分を検出する

f:id:bobchan1915:20190512214021p:plain
Compare builds

どんなデプロイメントの、ビルドを比較することができます。ファイルと、コミットメッセージを任意の二つのビルドで比較をできます。パイプラインが壊れているときは、使うことができません。

7. ボトルネックを排除する

f:id:bobchan1915:20190512214238p:plain
Eliminate bottlenecks

GoCDのAgentはボトルネックを排除して、並列実行を提供します。

8. 設定を管理する

f:id:bobchan1915:20190512214329p:plain
Keep configuration tidy

GoCDのテンプレートシステムによって、簡単にパイプラインの設定を再利用することができます。

9. チームを信頼して、責任感を持つ

f:id:bobchan1915:20190512214419p:plain
Trust your team; be responsible

GoCDは、監視可能なデプロイメントをサポートして、ユーザーに対して適切にパイプラインの設定を渡すことができます。

10. プラグイン機能

f:id:bobchan1915:20190512214438p:plain
Plugins

Embulkなどにも象徴されるように、たくさんのプラグインが用意されていて、私たち自身も作成をすることができます。

特徴

GoCDとは、どのような特徴があるのでしょうか。

1. E2E 可視化

f:id:bobchan1915:20190512213005p:plain
複雑なパイプラインを可視化できる

GoCDでは、最初から最後まで一つのストリームマップで可視化をします。

2. Cloud Native Deployments

f:id:bobchan1915:20190512213038p:plain
Cloud Nativeデプロイ

KubernetesをはじめとするCloud Native技術に対して親和性を持っていて、GoCDのCDワークフローをそれらの環境へデプロイできます。

3. 複雑なワークフローを定義できる

f:id:bobchan1915:20190512213058p:plain
複雑なパイプラインもモデル化できる構造

GoCDのモデル構造によって複雑なワークフローのフィードバックを速く、並列実行し、依存関係をマネジメントできます。

4. 高度なトレーサビリティ

f:id:bobchan1915:20190512213140p:plain
ビルドの差分が分かる

トレーサビリティによって、パイプライン自体が破壊された場合はその原因を変更によって検出することができます。

概念

いくつかの概念が出てくるので、理解しておいてください。

1. タスク

f:id:bobchan1915:20190512214911p:plain
タスクとはアトミックな処理単位

タスクとは、(普通は)アトミックな処理単位のことです。

例えばgo buildなどがその一つであり、公式ドキュメントではant compileが挙げられています。

2. ジョブ

f:id:bobchan1915:20190513030823p:plain
ジョブとは複数のタスクから構成される順序のあるまとまり

ジョブとは、複数のタスクから構成される順序があるまとまりのことです。

もちろん包含するタスクが失敗すると、ジョブが失敗したと見なされます。

ここのジョブやタスクの概念はCircleCIをはじめとするCIツールによく見られるので理解しやすいと思います。

タスクはそれぞれ独立しており、他のタスクに影響を与えることはありません。

3. ステージ

f:id:bobchan1915:20190513031219p:plain
ステージとは、並列処理できる複数のジョブを含む他のステージとは独立に動作することのできる単位

ステージとは、並列処理できる複数のジョブを含む他のステージとは独立に動作することのできる単位です。

それぞれのジョブの成功、失敗は、ステージに含まれる他のジョブへ影響はしません。

4. パイプライン

f:id:bobchan1915:20190513031428p:plain
パイプラインとは、複数のステージが、順番に実行されるワークフローを定義するもの

パイプラインとは、複数のステージが、順番に実行されるワークフローを定義するものです。

5. マテリアルとトリガー

f:id:bobchan1915:20190513031623p:plain
Gitマテリアル

マテリアルとは、パイプラインが実行される起因となるものです。例えばgitがあげられる。GoCDは変更をポーリングしており、新しいコミットが見つかるとパイプラインがトリガーをされます。

また、トリガーだけを見るとタイマートリガーもあります。それは定期的に設定した時間に対して実行をするようなものです。

f:id:bobchan1915:20190513031727p:plain
タイマートリガー

6. パイプライン依存マテリアル

マテリアルは、パイプライン内のステージが他のパイプラインのマテリアルに使われるときに非常に効力を発します。

例えば、以下のような種類があります。

f:id:bobchan1915:20190513032118p:plain
Last stageパイプライン依存マテリアル

f:id:bobchan1915:20190513032148p:plain
途中ステージのパイプライン依存マテリアル

7. ファンアウトとファンイン

ファンアウト、ファンインのデザインパターンは、ストリーム処理の界隈でもよく言われる話です。

パイプラインでも同様です。

f:id:bobchan1915:20190513032316p:plain
ファンアウト

f:id:bobchan1915:20190513032328p:plain
ファンイン

8. バリューストリームマップ(VSM)

f:id:bobchan1915:20190513032550p:plain
VSMの例

VSMとは、パイプラインのE2Eの可視化されたものです。

9. 成果物(Artifacts)

f:id:bobchan1915:20190513032925p:plain
成果物

ジョブは、ファイルやディレクトリというような成果物を作成することができます。その成果物は、他のユーザーやパイプラインの下流のステージでも使えるようにGoCDは管理をしてくれます。

10. 成果物のフェッチ

f:id:bobchan1915:20190513033207p:plain
成果物のフェッチ

GoCDは"成果物をフェッチするタスク"という特別なタスクがあり、祖先パイプラインのどんな成果物も使うことができます。

11. Agent

どこでタスクや、ジョブ、パイプラインは実行されるのでしょう。

GoCD AgentはGoCDエコシステムでのワーカーです。

Agentは公式ドキュメントは以下のようなコンピュータの図で現れます。

f:id:bobchan1915:20190513033909p:plain
Agentの図

GoCD Serverに対してGoCDは実行したジョブなどを報告します。そしてGoCD Serverは他のAgentからの報告もまとめて、パイプラインやステージの情報を可視化します。

12. リソース

Agentとジョブは、リソースによって強化することができます。リソースとは、タグのことで、どのAgentが特定のJobを実行するのに適しているかを優先順位づけをできるものです。

f:id:bobchan1915:20190513034947p:plain
Agentにつけられたリソース

そしてリソースがつけられたAgentがあると、以下のように分配されます。

f:id:bobchan1915:20190513035045p:plain
Agentとジョブとリソースの一例

13. 環境

パイプラインをグループ化して独立させることは簡単です。

環境にはルールがあって

  • 環境は一つ以上のパイプラインからなる
  • Agentはどの環境にも含まれない、または複数の環境に含まれてもいい
  • 環境に属するAgentはそのパイプラインのジョブのみを実行することができる
  • 任意の環境に所属しているAgentはどの環境にも属さないパイプラインのジョブは実行できない

です。つまるところ、パイプラインとAgentを繋ぐのが環境ということです。

f:id:bobchan1915:20190516231637p:plain
環境

14. 環境変数

環境、パイプライン、ジョブ、あらゆるレベルで環境変数は定義でき、階層構造のようになっています。

そして、具体的な対象(環境よりパイプライン、パイプラインよりジョブ)になるほど上書きができます。

以下の図ですぐ理解できると思います。

f:id:bobchan1915:20190516231649p:plain
環境変数の階層構造

実践編

それでは、実践してみましょう。

1. GoCDのインストール

今回はHelmを使ってやっていきます。

helm install --name gocd-app --namespace gocd stable/gocd

2. WebUIにアクセスする

以下のようにしてWebUIへアクセスをします。

ip=$(kubectl get ingress --namespace gocd gocd-server -o jsonpath="{.status.loadBalancer.ingress[0].ip}")
open "http://$ip"

すると以下のような画面が現れるはずです。タブにもあるように、ここではグループ化したパイプライン一覧画面になっています。 

f:id:bobchan1915:20190520033347p:plain
GoCDのダッシュボード

試しに再生ボタンを押してみるとAgentが作成される様子がわかります。

NAME                                              READY   STATUS    RESTARTS   AGE
gocd-agent-02d39fb4-5ed9-4ceb-abdf-fe89144c07e8   1/1     Running   0          24s
gocd-app-server-78f6f4f657-5sxjk                  1/1     Running   0          11m

そして、以下のようにタスクが終了しています。

f:id:bobchan1915:20190520033550p:plain
成功したTask

3. Pipelineを定義する

以下のように、New Pipelineボタンを押してパイプライン作成画面へ移行してください。

f:id:bobchan1915:20190520033859p:plain
New Pipelineを押す

すると、以下のように作成画面が現れます。適当に名前をつけます。

f:id:bobchan1915:20190520034132p:plain
Pipelineの名前をつける

そしてMaterialを設定します。

f:id:bobchan1915:20190520034237p:plain
Materialの設定

次にStageを設定します。以下のように一つ一つ設定をしていきます。

f:id:bobchan1915:20190520041947p:plain
Stageを定義する

そしてパイプラインを設定します。

f:id:bobchan1915:20190520042231p:plain
完成したパイプライン

このCDは使わないので、もう調べたくない....

ってことで終わります!!!

まとめ

機能としてはGoCDは非常に優れているの感じました。

というのも、Environment、Environment VariableやAgentなど概念がそれぞれわかりやすく、また高機能でできることが多いからです。しかし、その反面、非常にドキュメント自体も長く、目を通さなければならないことが多いです。またUIでぽちぽち設定することが多く、Pipeline as CodeやInfracture as Codeは達成しづらいような状況です。

まだまだ他のアプリケーションをいじっていこうと思います。

参考文献

www.gocd.org