GKEのインスタンスタイプを無停止で変更する

GKEのクラスタのインスタンスタイプを上げたのでメモっておく

# やること

[異なるマシンタイプへのワークロードの移行  |  Kubernetes Engine のチュートリアル  |  Google Cloud](https://cloud.google.com/kubernetes-engine/docs/tutorials/migrating-node-pool?hl=ja)
**↑これにすべて書いてある**

ざっくり書くと

1. 新しいNodePool作成
	- スケジュール可能な新しいNodePool
	- インスタンスタイプを上げたNodePoolにしておく
2. 既存のNodePoolへのスケジュールを停止
	- これによって、既存のNodePoolへはpodがデプロイされなくなる
3. 既存のNodePoolをdrain
	- これによって、既存のNodePoolにいたpodが終了し、新しいNodePoolへデプロイされる
		- 正確に言うと、スケジュール可能なNodeにデプロイされるのだと思う
		- 既存NodePoolのNodeはスケジュールを止めているのでデプロイされない
4. 既存のNodePoolを削除


# 現状

- 既存のNodePool: `default-pool`
    - GKEでクラスタを作った時にdefaultで作成されるNodePool
    - インスタンスタイプ: `n1-standard-4`

# 手順

あとで使うので、クラスタ名を定義しておく

```
export CLUSTER_NAME=xxxx-cluster
```

## 新しいNodePool作成

```
$ gcloud container node-pools create n1s8-pool --cluster $CLUSTER_NAME --machine-type=n1-standard-8 --num-nodes=2 --enable-autoscaling --min-nodes=2 --max-nodes=10
```
**※まぁまぁ時間かかります**

- `machine-type` で変えたいtypeを指定する
- オートスケール設定は適宜

この時点では、daemonset以外のpodはすべて `default-pool` のnodeにデプロイされている

```
$ kubectl get po -o=wide
NAME                                             READY     STATUS    RESTARTS   AGE       IP           NODE
xxx-xxxxxx-bf5cdb4b5-m2jws                       1/1       Running   0          12d       xx.x.0.x     gke-xxxx-default-pool-xxxxxxx-xxxx
...
```

- `-o=wide` で確認しておく
- `NODE` の所を見ると、default-poolのNodeであることがわかる

## 既存NodePoolのNodeへのスケジューリングを停止する

先に現状を確認しておく

```
$ kubectl get nodes
NAME                                  STATUS    ROLES     AGE       VERSION
gke-xxxx-default-pool-xxxxxxxx-xxxx   Ready     <none>    12d       v1.10.2-gke.3
gke-xxxx-default-pool-xxxxxxxx-xxxx   Ready     <none>    12d       v1.10.2-gke.3
gke-xxxxxx--n1s8-pool-xxxxxxxx-xxxx   Ready     <none>    5m        v1.10.2-gke.3
...
```
- 全部 STATUSが `Ready` になっている

```
$ for node in $(kubectl get nodes -l cloud.google.com/gke-nodepool=default-pool -o=name); do kubectl cordon "$node"; done
```

- `-l` で `default-pool` のラベルが付いたnode名を取得する
- それぞれのNodeを `cordon` していく
    - [Kubectl Reference Docs cordon](https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands#cordon)

```
$ kubectl get nodes
NAME                                  STATUS                     ROLES     AGE       VERSION
gke-xxxx-default-pool-xxxxxxxx-xxxx   Ready,SchedulingDisabled   <none>    12d       v1.10.2-gke.3
gke-xxxx-default-pool-xxxxxxxx-xxxx   Ready,SchedulingDisabled   <none>    12d       v1.10.2-gke.3
gke-xxxxxx--n1s8-pool-xxxxxxxx-xxxx   Ready                      <none>    6m        v1.10.2-gke.3
...
```
- default-poolのnodeのSTATUSが `SchedulingDisabled` になっていることを確認

## 既存のNodePoolのNodeをdrainしてpodを移す

```shell
for node in $(kubectl get nodes -l cloud.google.com/gke-nodepool=default-pool -o=name); do
  kubectl drain --force --ignore-daemonsets --delete-local-data --grace-period=180 "$node";
done
```

[Kubectl Reference Docs drain](https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands#drain)
![drain](https://kubernetes.io/images/docs/kubectl_drain.svg)
**※これを見る限り、drainするとcordonしてから後の処理を行うようなので、先にcordonしておく必要はないかもしれない**

```
$ watch kubectl get po -o=wide
```
とかで見てると、徐々に移っていくのを見ることができる


```
$ kubectl get po --all-namespaces -o=wide
```
終わったら、daemonset以外のpodが全て新しいNodeにデプロイされていることを確認しておく

## 既存のNodePoolを削除する

```
$ gcloud container node-pools delete default-pool --cluster $CLUSTER_NAME
```