Spinnaker for Google Cloud Platformを試す

# 記事の内容

[Spinnaker for Google Cloud Platform](https://cloud.google.com/blog/products/devops-sre/introducing-spinnaker-for-google-cloud-platform-continuous-delivery-made-easy)をお試しでインストールからお掃除までやってみます

Spinnakerとはなにかという話は本記事では触れませんのでご注意ください。
参考: [Spinnaker公式](https://www.spinnaker.io/)

# Spinnaker for Google Cloud Platformとは

次の「Introducing Spinnaker for Google Cloud Platform」で7/23にアナウンスがありました。
(以下、Spinnaker for GCPと呼びます)

https://cloud.google.com/blog/products/devops-sre/introducing-spinnaker-for-google-cloud-platform-continuous-delivery-made-easy

今までGCP上でSpinnakerを構築するには、GCE上にマーケットプレイスのアプリをデプロイする以外は、GKE上にHelmでインストールしたりHalyardでインストールする必要がありました。

今回のSpinnaker for GCPを使うと
・Secure installation
・Automatic backups
・Integrated auditing and monitoring
・Simplified maintenance
といった構築・運用におけるメリットがあると、記事では紹介されています。

マネージドサービスとまではいきませんが、ある程度をGCP側に任せてSpinnakerをプロビジョニングできます。

# 読むべき資料

アナウンス記事以外には次の資料を読むと良いでしょう。

・Spinnaker for GCP公式ドキュメント
https://cloud.google.com/docs/ci-cd/spinnaker/spinnaker-for-gcp

・Spinnaker for GCPのREADME
https://github.com/GoogleCloudPlatform/spinnaker-for-gcp/blob/master/README.md

# 構築にあたっての注意点

公式が提供しているサービスとはいえ、Spinnakerやそれに付随する知識は必要です。
(例: Spinnkarのアーキテクチャ、Halyardの使い方、Spin CLIの使い方など)

GKEには`アプリケーション`というメニューがあり、ドキュメント上ではそのアプリケーションメニューから参照可能と書いてあります。
...が、実際の構築作業は`Cloud Shell`上で行います。
そのため、ボタンポチポチで簡単に作れるというイメージがあると、少しイメージが違っています。

なお、構築作業が終わった後は、GKEのアプリケーションメニューから参照可能になります。

Spinnakerの構築はHelm Chartでも手動でも、基本はHalyardがSpinnakerの構築を行ってくれますが、
Spinnaker for GCPも同様にHalyardがSpinnakerの構築を行ってくれます。
つまり、Halyardをラップして周辺リソース(Redis, PubSub, Functions, IAMなど)も含めてプロビジョニングしてくれるツールこそがSpinnaker for GCPといえます(個人的な認識です)

それでは実際の構築作業になります。

# 構築作業編

まずは作業場になる「Cloud Shell」を開きます。
一番簡単な方法は[Spinnaker for GCPのリポジトリ](https://github.com/GoogleCloudPlatform/spinnaker-for-gcp/blob/master/README.md
)から「Open in Google Cloud Shell」を開くことです。

普通にCloud Shellを開いて、Spinnaker for GCPのリポジトリをCloneした上で次のコマンドからでも開始できます。

```
cloudshell launch-tutorial ~/spinnaker-for-gcp/scripts/install/provision-spinnaker.md
```

Cloud Shellの画面右枠にGCPプロジェクト選択画面が表示されるので、
プロジェクトを作成するか既存のプロジェクトを選択します。

<img width="349" alt="スクリーンショット 2019-07-23 11.58.23.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314463/c9a099bb-4266-772a-56f4-afedfa7b4def.png">

<img width="339" alt="スクリーンショット 2019-07-23 12.45.01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314463/d193f333-69cb-b6b6-0520-d455bf0d2dc0.png">

画面に打つべきコマンドと説明が表示されるので、指示にしたがって進めます。

まずはPROJECT IDを設定して、インストール用のプロパティを編集します。

```
$ PROJECT_ID=<GCP PROJECT ID> \
    ~/spinnaker-for-gcp/scripts/install/setup_properties.sh

$ cloudshell edit ~/spinnaker-for-gcp/scripts/install/properties
```

<img width="743" alt="スクリーンショット 2019-07-23 12.19.35.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314463/65fe7ab7-3a25-d411-dd70-5b1c618288e0.png">

GKEクラスタは新規に作成させるか既存のクラスタにインストールさせるかをプロパティの値で選択可能です。
ネットワークは存在するものを指定する必要があります。

今回はGKEクラスタ(spinnaker-1)を新規作成します。

編集完了後に、次のコマンドでインストール作業開始します。

```
$ ~/spinnaker-for-gcp/scripts/install/setup.sh
```

プロビジョニングはそこそこ時間がかかります。
待ちましょう。

インストール作業が完了し、GKEクラスタの中身を確認すると
Spinnakerのコンテナが動いていることが分かります。

```
$ gcloud container clusters get-credentials spinnaker-1 --zone asia-northeast1-a
```

```
$ kubectl get ns
NAME          STATUS   AGE
default       Active   32m
halyard       Active   30m
kube-public   Active   32m
kube-system   Active   32m
spinnaker     Active   30m

$ kubectl get pods -n spinnaker
NAME                                READY   STATUS    RESTARTS   AGE
spin-clouddriver-84d5db9ddf-skr5d   1/1     Running   0          15m
spin-deck-bb65bb7bb-cgfwb           1/1     Running   0          15m
spin-echo-6576df789f-gf5sv          1/1     Running   0          15m
spin-front50-676bd4b56f-hhhj9       1/1     Running   0          15m
spin-gate-5bd4b78c9c-c88cz          1/1     Running   0          15m
spin-igor-fdbdf6ccf-ssnps           1/1     Running   0          15m
spin-kayenta-77477679c4-m8x8l       1/1     Running   0          15m
spin-orca-78fc5bd6c7-l2r44          1/1     Running   0          15m
spin-rosco-67fc956f55-cktbw         1/1     Running   0          15m
```

Spinnakerで利用するRedisはPodとして起動していません。
[Memorystore](https://cloud.google.com/memorystore)や[Pub/Sub](https://cloud.google.com/pubsub/)などのマネージドサービスが裏で使われています。

このインストール作業が完了しても、まだSpinnakerにはアクセスできません。
外(Cloud Shellやブラウザ)からアクセスできるように、道を開ける必要があります。

次のコマンドでPort-fowardingすることで、Cloud ShellのWebプレビューでの確認ができるようになります。

```
$ ~/spinnaker-for-gcp/scripts/manage/connect_unsecured.sh
```

次の方法で外部IPを払い出してSpinnakerにアクセスする方法もありますが、30-60分ほどプロビジョニングに時間がかかるようです。
今回は試しません。

```
$  ~/spinnaker-for-gcp/scripts/expose/configure_endpoint.sh
```

Port-forwardingが完了したら、Webプレビューから画面(Deck)にアクセスできます。

<img width="257" alt="スクリーンショット 2019-07-23 14.23.43.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314463/711919cf-03a9-f3da-c6ce-46f61dff75ee.png">

<img width="1362" alt="スクリーンショット 2019-07-23 12.48.56.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314463/2265743d-6420-5a7f-5085-7b23451195fd.png">

これで構築自体は完了しました。

構築が完了すると、GKEのアプリケーションメニューからもSpinnakerが確認できます。

<img width="672" alt="スクリーンショット 2019-07-23 13.33.18.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314463/3de750a3-8f09-7bbf-948c-327905a86b1a.png">

# Spinnaker Management編

構築後のSpinnakerのバージョンアップや設定更新などは別の章立てになっています。
次のコマンドでCloud Shellのコンソールを更新し、GCPプロジェクトを選択してきます。

```
$ ~/spinnaker-for-gcp/scripts/manage/update_console.sh
```

プロジェクト選択画面になるので、GCPプロジェクトを選択します。

<img width="333" alt="スクリーンショット 2019-07-23 14.29.22.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314463/26ea218b-8c70-d6c8-e6ce-69fbda62e301.png">

またコマンドと指示が表示されるので、従って進めます。

<img width="343" alt="スクリーンショット 2019-07-23 14.30.18.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314463/a2a5ae9f-310c-ceb7-d031-c22cb91fc1a0.png">

```
$ PROJECT_ID=<GCP_PROJECT_ID> ~/spinnaker-for-gcp/scripts/manage/check_cluster_config.sh
```

Spinnakerの設定(Halyardの設定)をCloud Shell上にPullします。

```
$ ~/spinnaker-for-gcp/scripts/manage/pull_config.sh
```

`hal`コマンドを使えるようになりました(いつの間に...)
次のコマンドでSpinnakerの設定を確認できます。

```
$ hal config
```

Configを編集して更新する場合はhalコマンドではなく、次のスクリプトを動かすようです(今回は省略)
Spinnaker for GCPを使っていても、設定を後から変更したいというニーズは普通にあると思うので、変更できる余地があるのは良いですね。

> As with provisioning Spinnaker, don't use  hal deploy connect when managing Spinnaker. Also, don't use hal deploy apply. Instead, use the push_and_apply.sh command shown below.

```
$ ~/spinnaker-for-gcp/scripts/manage/push_and_apply.sh
```

別GKEクラスタにアプリケーションをデプロイするためには、ServiceAccountを追加する必要があります。
Service AccountをSpinnakerに追加する場合は次のコマンドを打つと追加されます。

> ServiceAccountについてはこちらを参照とのこと
> https://www.spinnaker.io/setup/install/providers/kubernetes-v2/gke/

```
# Add Spinnaker account for GKE
$ ~/spinnaker-for-gcp/scripts/manage/add_gke_account.sh
```

> GCEにServiceAccountを追加する場合
> ~/spinnaker-for-gcp/scripts/manage/add_gce_account.sh
>
> GAEにServiceAccountを追加する場合
> ~/spinnaker-for-gcp/scripts/manage/add_gae_account.sh

今回は「add_gke_account.sh」を追加しませんでしたが、事前にkubeconfigを取得して「~/.hal/default/credentials」に配置しておく必要がある気がします(未検証)。

> If you add a Kubernetes account that references a kubeconfig file, that file must live within the '~/.hal/default/credentials' directory on your Cloud Shell VM. The kubeconfig is specified using the  --kubeconfig-file argument to the hal config provider kubernetes account add and ...edit commands.

# お掃除編

リソースを掃除するには、まず次のコマンドを実行します。
次のコマンド自体はリソースを掃除するためのコマンドを表示するためのコマンドです。

```
$ ~/spinnaker-for-gcp/scripts/manage/generate_deletion_script.sh
```

コマンドを実行すると、全てのリソース(GKE, Redis, Pub/Sub, IAMなど)を削除するためのコマンドが表示されるので、指示に従って実施します。

```
$ ~/spinnaker-for-gcp/scripts/manage/delete-all_<GCP PROJECT ID>_spinnaker-1_spinnaker-1.sh
```

# 所感

最後に所感を載せて終わりたいと思います。

これまで
・Halyard
・Helm
くらいしか構築手段がない中で、Spinnakerの構築・運用の知識が求められてきました。
Spinnaker for GCPもSpinnakerの知識は必要ですが、打つべきコマンドがわかっている分、
迷うことは少ないのかなと思います。

自前で立てると、データストレージ(例えばRedis)の管理もやる必要がありますが、
Spinnaker for GCPだとマネージドサービスを使っているので管理対象もある程度パブリッククラウドに任せられるところも良いと感じました。

これを機にSpinnakerを使った事例が増えると大変嬉しいです。

以上