1クール続けるブログ

とりあえず1クール続けるソフトウェアエンジニアの備忘録

SpinnakerのPipeline Expressionsで他stageの情報を取ってくる

SpinnakerのPipeline Expressions

KubernetesAmazon ECSを絡めたCI/CDでは既にデファクト感のあるSpinnakerですが、日本語の記事が少ないのと公式ドキュメント自体も不足はしてないのですが若干物足りない部分があります。KubernetesのBlue/Green Deployを構築した際にPipeline Expressionsで他stageの情報を取ってくるということをしたんですが、ちょっと分かりづらかったので記事に残しておきます。

とはいえ下記のページ見ていただければ十分とも思います。

Pipeline Expressions Guide - Spinnaker

やりたいこと

以下のような流れでパイプラインを構築したいと考えました。項目はStageの単位と対応しています。 providerはKubernetes V2です。

  • 新しいReplicaSetをDeploy(ただしPod数は1)。
  • Enableし新しいReplicaSetにもTrafficが流れるようにする。
  • manual judgement。このままデプロイを続けるかRollbackするか選択させる。
  • Continue
    • 新しいReplicaSetを本番相当までスケールアウト
    • 古いReplicaSetをDisableしTrafficが流れないようにする
    • 古いReplicaSetのサイズを0にする
  • Rollback
    • 新しいReplicaSetをDisableにする
    • 新しいReplicaSetをdeleteする <- ここが問題になった

ScaleやEnableは、対象をstaticとdynamicに分かれます。staticは固定値かつ既に存在するReplicaSetしか選べないので今回の用途に合いません。Dynamicでは、NewestやSecond Newest等の選択肢があります。逆にそれらの選択肢からしか選べません。常に現在動いているReplicaSetが最新のものである前提でないとPipelineの設定がうまくいきません。そのためRollbackではReplicaSetを削除する必要があります。
このDeleteのstageなんですが、ScaleやEnableと違って削除するリソースをNewestやSecond Newestから選べません。namespace/リソースタイプに加え、リソースの名前もしくはラベルを直接指定する必要があります。リソースの名前を指定するのが手っ取り早そうなのですが、なぜかPipeline Expressionsを記述してSaveしても消えてしまったので、タグの方で実装しました。

Pipeline ExpressionsでDeploy時のラベル情報をとってくる

Spinnakerはデプロイ時にこちらが指定したマニフェストに更に情報を付加するので、最終成果物からラベルを取ってくる必要性があります。 結論から言うと以下です。

${ #stage("Deploy new ReplicaSet").context["outputs.manifests"][0].metadata.labels["moniker.spinnaker.io/sequence"].toString() }

Key名moniker.spinnaker.io/sequenceだけ取ってきていますが、他のラベルに関しては固定値のため取ってくる必要性がありません。 この情報は、http://localhost:8084/pipelines/${PIPELINE_ID}で取ってこれるJSONをベースにアクセスしていきます。PIPELINE_IDは、パイプライン実行結果のDetailを選択し展開されたウィンドウの右下のSourceをクリックして飛ぶURLに含まれています…というか先程のURLそのものになっています。 #stage("ステージ名")でstages配列の中の指定したstageのJSONをルートにしてアクセスできます。outputs.manifestsのようにKeyに.(ドット)が含まれる場合にはmap形式でアクセスしないとだめです。

Pipeline Expressionsをテストする

以下のようにcurlを叩くことでテストできます。

curl  http://localhost:8084/pipelines/${PIPELINE_ID}/evaluateExpression \
-H "Content-Type: text/plain" \
--data '${ #stage("Deploy new ReplicaSet").context["outputs.manifests"][0].metadata.labels["moniker.spinnaker.io/sequence"].toString() }'

まとめ

お家でSpinnkerを試せるような環境が作れれば良いのだけれど…。 お家でKubernetes触りたいときには、Katacodaで今まで動かしていたので、minikube+Spinnakerに自分のPCのスペックが足りるかどうか。