GKEの同時ノードアップグレード数は各インスタンスグループのノード数に制限される

# 結論
GKEの同時ノードアップグレード数(maxSurge)を大きな値にしても同時アップグレードされるノード数は各インスタンスグループのノード数に制限される

# ノードサージアップグレードとは
GKEのノードはkubernetesのバージョンアップやaddonの追加等でアップグレードが必要となります。メンテナンス枠での自動アップグレードやgcloudコマンドを用いた手動アップグレードではローリングアップグレードとなり、順繰りにインスタンスの入替えが発生します。その際、デフォルトだとmaxSurge=1となっており、1ノードずつの入替えとなります。そのため、ノード数分に比例してアップグレード時間が増加してしまいます。アップグレード時間を短縮するためにはmaxSurgeの値を大きくし、同時に入替えできるノード数を増やす必要があります。なお、1ノードずつの入替えでも言えることなのですが、入替え中のpod数を制御したい(必ず1つ以上のpodのhealthcheckが通った状態を保つ等)場合はPodDisruptionBudgetを設定しておきましょう。maxSurgeはnode pool毎に設定することができます。

[GKE のサージ アップグレードで運用効率が大幅に改善](https://cloud.google.com/blog/ja/products/containers-kubernetes/introducing-surge-upgrades-for-anthos-gke)

# maxSurgeはインスタンスグループのノード数に制限される
## シングルゾーンクラスタの場合
1つのzoneのみにノードがあるGKEクラスタを[シングルゾーンクラスタ](https://cloud.google.com/kubernetes-engine/docs/concepts/types-of-clusters?hl=ja#single-zone_clusters)と言います。シングルゾーンクラスタの場合は1つのnode poolに1つのインスタンスグループしか存在しないため、maxSurgeに設定した値の数で同時アップグレードが行われます。例えば、6ノードあるシングルゾーンクラスタのnode poolにmaxSurge=6を設定した場合の挙動を見てみましょう。

```
# asia-northeast1-aに6ノードあるシングルゾーンクラスタを作成
gcloud container clusters create test-single-zone --zone asia-northeast1-a --node-locations asia-northeast1-a --num-nodes 6

# node-poolのmaxSurgeを6に設定
gcloud container node-pools update default-pool --cluster test-single-zone --max-surge-upgrade 6 --max-unavailable-upgrade 0 --zone asia-northeast1-a

# NodeLocal DNSCacheを有効化し、ノード入替えを発生させる
gcloud container clusters update test-single-zone --zone asia-northeast1-a --update-addons NodeLocalDNS=ENABLED

```

以下はアップグレード開始直後のノード一覧です。maxSurge=6を設定しているので6ノードが新規に立ち上がって、旧6ノードから新6ノードへpod移行が行われます。
![GKE-singlezone.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266372/369e18af-4bb6-9972-92d5-58f9ac7f2811.png)

## マルチゾーンクラスタ及びリージョンクラスタの場合
複数zoneにノードがあるGKEクラスタは[マルチゾーンクラスタ](https://cloud.google.com/kubernetes-engine/docs/concepts/types-of-clusters?hl=ja#multi-zonal_clusters)と[リージョンクラスタ](https://cloud.google.com/kubernetes-engine/docs/concepts/types-of-clusters?hl=ja#regional_clusters)があります。マルチゾーンクラスタはコントロールプレーンが1つのzoneのみに存在し、リージョンクラスタはコントロールプレーンが複数zoneに存在する点で違いがあります。これらのクラスタの場合は1つのnode poolに複数のインスタンスグループが存在します。この場合同時アップグレードされるノード数はmaxSurgeに設定した値ではなく**各インスタンスグループのノード数**となります。例えば、3つのzoneに2ノード、合計6ノードあるマルチゾーンクラスタのnode poolにmaxSurge=6を設定した場合の挙動を見てみましょう。

```
# asia-northeast1-a,asia-northeast1-b,asia-northeast1-cそれぞれに2ノード、合計6ノードあるマルチゾーンクラスタを作成
gcloud container clusters create test-multi-zone --zone asia-northeast1-a --node-locations asia-northeast1-a,asia-northeast1-b,asia-northeast1-c --num-nodes 2

# node-poolのmaxSurgeを6に設定
gcloud container node-pools update default-pool --cluster test-multi-zone --max-surge-upgrade 6 --max-unavailable-upgrade 0 --zone asia-northeast1-a

# NodeLocal DNSCacheを有効化し、ノード入替えを発生させる
gcloud container clusters update test-multi-zone --zone asia-northeast1-a --update-addons NodeLocalDNS=ENABLED

```

以下はアップグレード開始直後のインスタンスグループの一覧とasia-northeast1-aのノード一覧です。maxSurge=6を設定していますが、新規に6ノードが一気に立ち上がってノード入替えが発生するのではなく、asia-northeast1-aのインスタンスグループのノードから入替えが発生しました。入替え完了後は別のインスタンスグループの入替えが発生して、インスタンスグループ単位で順繰りにノード入替えが発生しました。

![GKE-multi2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266372/3956b9a1-7ce0-1a10-c25b-cce711084d14.png)


![GKE-multi1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266372/b0b60e76-34c1-7506-28e1-d43d51419c20.png)

# まとめ
maxSurgeを設定していたとしても、複数zoneのノードがまたがるGKEクラスタの場合は同時ノードアップグレード数がインスタンスグループのノード数に制限されることに注意しましょう。2020/11時点の[ドキュメント](https://cloud.google.com/kubernetes-engine/docs/concepts/cluster-upgrades#surge)ではこのことは記載されていません。
インスタンスグループにはzoneをまたがった設定をすることもできるようですが、GKEクラスタ作成時に作られるインスタンスグループは単一zoneの設定となるようです。