Spinnaker on GKE (導入編)



# ToDo
Halyard on GKE Quickstart - [https://www.spinnaker.io/setup/quickstart/halyard-gke/]
これをそのまま(最新版にして, asia-northeast1-cゾーンで)やってみた。

##  Spinnaker?

**-> CD (Continuous Delivery Platform)**

メリットは
・Immutable Infrastructure *1 の徹底
・予測可能で安全なデプロイ パイプラインの作成
　(cronによってもパイプライン起動可 → k8s jobsの管理にも)

**役割**
![spinnaker_netflix.png](https://qiita-image-store.s3.amazonaws.com/0/190334/a3f0d44f-cb5e-3744-52ab-de6d6a384dae.png)

(引用：参考記事①)

これにより、リリースにおける
**安定したイメージの作成 、デプロイ後のテスト、問題が発生した場合の切り戻し**
などの作業を"ちゃんと"管理できる

この "ちゃんと" の部分を今回は検証したい
→ 今回は導入のみ

### Halyard?
**-> Spinnaker自体のDeploy管理ツール**

Spinnakerは複数のコンポーネント(コンテナ)で形成されているため、Halyardでの管理が推奨されている。
Spinnakerの各コンポーネントのDeploy、Test、Updateの実行が含まれる。

# 必要になるもの
・GCPアカウント
　　・gcloudコマンド (GoogleCloudSDK)
　　・GCE, GKEを使用
　　・以下のAPI有効化
　　　[Google Identity and Access Management (IAM) API](https://console.developers.google.com/apis/api/iam.googleapis.com/overview)
　　　[Google Cloud Resource Manager API](https://console.developers.google.com/apis/api/cloudresourcemanager.googleapis.com/overview)

# 作るもの
![spinnaker_deployment.png](https://qiita-image-store.s3.amazonaws.com/0/190334/a03f522c-4fdc-c3db-f976-6c10ba2df11c.png)


GCEにHalyardを展開、そこからGKEにSpinnakerを展開する

# やってみた

少し時間がかかるので、先にGKEのクラスタを作成しておく
(1.8.4-gke.0, asia-northeast1-c， あとはデフォルト)


左にVM(GCE)作成

```
GCP_PROJECT=$(gcloud info --format='value(config.project)')
HALYARD_SA=halyard-service-account

gcloud iam service-accounts create $HALYARD_SA \
    --project=$GCP_PROJECT \
    --display-name $HALYARD_SA

HALYARD_SA_EMAIL=$(gcloud iam service-accounts list \
    --project=$GCP_PROJECT \
    --filter="displayName:$HALYARD_SA" \
    --format='value(email)')

gcloud projects add-iam-policy-binding $GCP_PROJECT \
    --role roles/iam.serviceAccountKeyAdmin \
    --member serviceAccount:$HALYARD_SA_EMAIL

gcloud projects add-iam-policy-binding $GCP_PROJECT \
    --role roles/container.admin \
    --member serviceAccount:$HALYARD_SA_EMAIL
```

```
GCS_SA=gcs-service-account

gcloud iam service-accounts create $GCS_SA \
    --project=$GCP_PROJECT \
    --display-name $GCS_SA

GCS_SA_EMAIL=$(gcloud iam service-accounts list \
    --project=$GCP_PROJECT \
    --filter="displayName:$GCS_SA" \
    --format='value(email)')

gcloud projects add-iam-policy-binding $GCP_PROJECT \
    --role roles/storage.admin \
    --member serviceAccount:$GCS_SA_EMAIL
```

```
HALYARD_HOST=$USER-halyard-`date +%m%d`

gcloud compute instances create $HALYARD_HOST \
    --project=$GCP_PROJECT \
    --zone=asia-northeast1-c \
    --scopes=cloud-platform \
    --service-account=$HALYARD_SA_EMAIL \
    --image-project=ubuntu-os-cloud \
    --image-family=ubuntu-1404-lts \
    --machine-type=n1-standard-4
```

VM(GCE)にSSHで入る

```
gcloud compute ssh $HALYARD_HOST \
    --project=$GCP_PROJECT \
    --zone=asia-northeast1-c \
    --ssh-flag="-L 9000:localhost:9000" \
    --ssh-flag="-L 8084:localhost:8084"
```

~~最新の安定版 kubectl を入れる。(今回はv1.8.4が入った)~~
→ 試してみたが画面表示されないバグになって、かなり詰まった。
チュートリアル通りここはv1.6.1を入れる。

```
curl -O https://storage.googleapis.com/kubernetes-release/release/v1.6.1/bin/linux/amd64/kubectl

chmod +x kubectl

sudo mv kubectl /usr/local/bin/kubectl
```

安定版halyardを入れる。

```
curl -O https://raw.githubusercontent.com/spinnaker/halyard/master/install/stable/InstallHalyard.sh

sudo bash InstallHalyard.sh

. ~/.bashrc
```


GKE登録

```
GKE_CLUSTER_NAME={YOUR_GKE_CLUSTER_NAME}
GKE_CLUSTER_ZONE={YOUR_GKE_CLUSTER_ZONE}

gcloud config set container/use_client_certificate true

gcloud container clusters get-credentials $GKE_CLUSTER_NAME \
    --zone=$GKE_CLUSTER_ZONE
```

```
GCS_SA=gcs-service-account
GCS_SA_DEST=~/.gcp/gcp.json

mkdir -p $(dirname $GCS_SA_DEST)

GCS_SA_EMAIL=$(gcloud iam service-accounts list \
    --filter="displayName:$GCS_SA" \
    --format='value(email)')

gcloud iam service-accounts keys create $GCS_SA_DEST \
    --iam-account $GCS_SA_EMAIL
```

Spinnaker最新バージョンを使うように設定(今回はv1.5.1が設定された)

```
hal config version edit --version $(hal version latest -q)
```

GCS設定

```
hal config storage gcs edit \
    --project $(gcloud info --format='value(config.project)') \
    --json-path ~/.gcp/gcp.json

hal config storage edit --type gcs
```

GCR設定

```
hal config provider docker-registry enable

hal config provider docker-registry account add my-gcr-account \
    --address asia.gcr.io \
    --password-file ~/.gcp/gcp.json \
    --username _json_key
```

k8s プロバイダ設定

```
hal config provider kubernetes enable

hal config provider kubernetes account add my-k8s-account \
    --docker-registries my-gcr-account \
    --context $(kubectl config current-context)
```

Deploy Spinnaker！

```
hal config deploy edit \
    --account-name my-k8s-account \
    --type distributed

hal deploy apply
```

Halyard (GCP) ⇔ Spinnaker (GKE) 接続

```
hal deploy connect
```

今回はローカルから9000番をリンクしてSSH接続したので、
http://localhost:9000 でSpinnakerに接続
※ deploy後、OAuthを設定してない、GCRに何もないなどWarningが出るが接続はできる
　
<img width="1679" alt="Screen Shot 2017-12-07 at 15.49.29.png" src="https://aone.qiita.com/files/e5471314-0089-bd1f-5b47-f51d0366f0d5.png">


# 感想
長くなったので、実動作については別記事に書こうと思います。

コンテナレジストリ(今回はGCR)と連携してくれてとても便利そう。
[halコマンド](https://www.spinnaker.io/reference/halyard/)覚えないと。中身の動作まで理解できたらk8sの勉強にもなりそう。
`hal deploy apply` SoCOOL!　Halyardは常駐させなくていい？


# 大変参考になる記事

①[Global Continuous Delivery with Spinnaker](https://medium.com/netflix-techblog/global-continuous-delivery-with-spinnaker-2a6896c23ba7) - Netflix 本家ブログ
→ はじめに。

②[SpinnakerによるContinuous Delivery](http://tech.mercari.com/entry/2017/08/21/092743) - メルカリブログ
→ 分かりやすいく使いたくなる記事。簡潔にまとまってて素晴らしい。

③[Compute Engine での Spinnaker の実行](https://cloud.google.com/solutions/spinnaker-on-compute-engine) - GCP Blog
→ "Spinnakerについて" のセクションが分かりやすい


---
*1 不変のインフラ (参考：http://image.itmedia.co.jp/l/im/enterprise/articles/1701/23/l_kz_kore0123_01.jpg)