PreemptibleNodes(プリエンプティブルノード)を使ってGKEの開発環境コストを7割削減する

# 概要

ここでは開発環境のコストを下げられるPreemptibleNodesへの移行方法について解説します。
PreemptibleNodesについては[プリエンプティブル仮想マシン](https://cloud.google.com/preemptible-vms)を参考にしください。

手順の途中で手元のターミナルから操作が必要なのでそちらのセットアップは

[[コピペ出来る！]GKEをターミナルから操作するまでの手順](https://qiita.com/kakky0418/items/b7e077bad4d88f1ba06f)を参考にしてください。



# 前提

- 古いNodePool名: `old`,  新しいNodePool名を`new`
- Nodeは15台
- e2-standard-2をPreemptibleNodesへ移行
- 環境: development

として解説します。



## 料金の下がり幅
現状development環境は15Node使用しているので以下の図から `$941.25 -> $282.45` へのコスト削減が見込めます！
![125561388-1eb61a76-90ec-4402-ac71-b4a3f62f6d15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49347/8ae6d579-3bf9-f1cf-ae31-5280233f9b34.png)


# 新NoodPoolの作成(GCPコンソール)

**GCPのコンソールから特定のクラスタに新しいNoodPoolを作成する。**
![125561385-cdd7e2e4-b99b-4db0-bca3-adb45bf916ce.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49347/2824baa3-630d-a29c-80dd-66178f24bcd2.png)



- **PreemptibleNodesを有効にする**
![125561391-0b126b42-fe6d-407c-9f74-62774828faa0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49347/7df4a91c-db22-5e24-85cc-72002a3a2e74.png)



# 旧NodePoolから新NodePoolに移行する(手元のターミナル)

## Contextsを確認(手元のターミナル)

ここで変更したいNodePoolが存在しているClusterにContextが向いていないと思わぬ不具合を招いてしまうので確認してください。

```bash
# contextの確認
$ kubectl config get-contexts
```

で確認。

## 削除するNodePoolのPodスケジュールリングを停止

まずは現状のnodeの状態を確認

```bash
$ kubectl get nodes -l cloud.google.com/gke-nodepool=pool-old
NAME                                          STATUS   ROLES    AGE   VERSION
gke-development-pool-old-aaaaaaaaaaaa-bbbb          Ready    <none>   5d10h   v1.18.17-gke.1901
```

`STATUS: Ready` であることを確認

## 下記コマンドでPodのスケジューリングを停止

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

上記コマンドを実行すると

```
NAME                                          STATUS                     ROLES    AGE     VERSION
gke-development-pool-old-aaaaaaaaaaaa-bbbb          Ready,SchedulingDisabled   <none>   5d10h   v1.18.17-gke.1901
```

`STATUS: Ready,SchedulingDisabled` であることを確認

## 旧NodePoolから新NodePoolに移行

**以下コマンドで pool-oldからpool-newにpodを移行**

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

一通りログの出力が終わったら既存のpodが新しいnodeに移っているのか確認

```bash
$ kubectl get pods -o=wide
NAME                               READY   STATUS    RESTARTS   AGE   IP          NODE                                          NOMINATED NODE   READINESS GATES
app-11111ccccc-dddd               2/2     Running   0          14m   10.0.11.2   gke-development-new-pool-cccccccc-dddd   <none>           <none>
app-11111eeeee-ffff               2/2     Running   0          12m   10.0.11.4    gke-development-new-pool-eeeeeeee-ffff   <none>           <none>
```

## 実際にアクセスして問題ないか確認

今まで通りつながればOK

# 旧NodePoolを削除(GCPコンソール)

不要になったNodePoolを削除
![125561706-439786f4-440d-49ef-a33f-994c4d13df27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49347/b9fb76fd-3465-dc31-ae66-3f33571f58fc.png)




以上です！

# 参考

- [異なるマシンタイプへのワークロードの移行](https://cloud.google.com/kubernetes-engine/docs/tutorials/migrating-node-pool?hl=ja)
- [VM インスタンスの料金](https://cloud.google.com/compute/vm-instance-pricing?hl=ja)