GKEを整理したい : コントロールプレーン、ノード（ノードプール）のアップグレードについて（Standardモード）

## 前書き
Google Kubernetes Engine (GKE)はGoogle Cloudのサービスの1つで、
コンテナオーケストレーションツールであるKubernetes (K8s)を用いた、コンテナのデプロイ、管理及びスケーリングが行えるサービスです

オンプレでのK8s運用に比べると様々なことが簡単に行えるとのこと
ただ、それでも様々な機能があるゆえになかなか最初は理解しにくいです

ですので、特定の機能に絞り、自分なりの理解を整理します
今回はStandardモードのクラスタにおける、コントロールプレーン及びノードのアップグレードについてです

## GKEにおけるバージョンについて（[公式ドキュメント](https://cloud.google.com/kubernetes-engine/versioning)）
K8sにおいては、年に3回のペースでマイナーバージョンがリリースされています
GKEにおいても、K8sのリリースに合わせる形でバージョンが提供されます

GKEにおいて各マイナーバージョンは、後述するRegularチャンネルでのリリース後
K8sと同様の12ヶ月間 + メンテナンス期間の2ヶ月
の計14ヶ月間サポートされます

## コントロールプレーンのアップグレード
コントロールプレーンがアップグレードされるのは以下の3パターンです
- 自動アップグレード
    - リリースチャンネル（[後述](#リリースチャンネル)）を選択します
    - 時間指定が可能です（[後述](#メンテナンスの時間枠と除外)）
- [手動アップグレード](https://cloud.google.com/kubernetes-engine/docs/how-to/upgrading-a-cluster#upgrade_cp)
- 強制アップグレード
    - コントロールプレーンのバージョンのサポートが終了すると強制でアップグレードされます
    つまり、コントロールプレーンをずっと同じバージョンにしておくことは不可能です
    （[公式ドキュメント](https://cloud.google.com/kubernetes-engine/versioning#faq)）

## ノードのアップグレード
正確にはノードのテンプレートである[ノードプール](https://cloud.google.com/kubernetes-engine/docs/concepts/node-pools)のアップグレードを行うことで、そのノードプールに属するノードがアップグレードされます
そのため、以後はノードプールをアップグレードするとして話を進めます

ノードプールは、コントロールプレーンと同じバージョンまたはコントロールプレーンと互換性のある以前のバージョンにアップグレードが可能です

また、コントロールプレーンとは別々にアップグレードされます
すなわち、後述の自動アップグレードを有効にしているからといって、コントロールプレーンがアップグレードされたらすぐにノードプールもアップグレードされるということでありません

アップグレードは以下の2パターンです
- [自動アップグレード](https://cloud.google.com/kubernetes-engine/docs/how-to/node-auto-upgrades)
    - 時間指定が可能です（[後述](#メンテナンスの時間枠と除外)）
- [手動アップグレード](https://cloud.google.com/kubernetes-engine/docs/how-to/upgrading-a-cluster#upgrade_nodes)

### サージアップグレード
ノードプールのアップグレードの手法として、[公式ドキュメント](https://cloud.google.com/kubernetes-engine/docs/concepts/node-pool-upgrade-strategies)においてはサージアップグレードとブルーグリーンアップグレードが紹介されています
が、今回はノードプールの設定項目として存在しているサージアップグレードについてのみ記載します

[サージアップグレード](https://cloud.google.com/kubernetes-engine/docs/concepts/cluster-upgrades#surge)は、ワークロードを中断させることなく、徐々にノードをアップグレードしている手法です

以下の値を設定することで、アップグレードの速度やコスト、アップグレード中の可用性などを調整します
- max-surge-upgrade 
    アップグレード中のみノードプールに対して追加できるノードの数
    例えばノード数が5でこの値が2の場合、アップグレード中は最大7つのノードが同時に稼働します
- max-unavailable-upgrade
    アップグレード中に同時に使用が不可能になるノードの最大数
    例えばノード数が5でこの値が2の場合、アップグレード中は最大2のノードが同時に使用不可となり、ワークロード実行可能なノードが3つになる時があります

試しに検証してみた時は次のような遷移となりました
- ノード数 : 5
- max-surge-upgrade : 2
- max-unavailable-upgrade : 3

|バージョン : 前 <br> STATUS : Ready|バージョン : 前 <br> STATUS : NotReady|バージョン : 後 <br> STATUS : Ready|総ノード数|使用不可なノード数|
|:-:|:-:|:-:|:-:|:-:|
|5|0|0|5|0|
|2|3|2|7|3|
|2|1|2|5|1|
|1|2|4|7|2|
|1|1|5|7|1|
|0|2|5|7|2|
|0|0|5|5|0|

どの時点を見ても
- 同時に稼働しているノードは7台以下
- 同時に使用不可なノード数は3台以下

でアップグレード処理が行われたことがわかります

## [リリースチャンネル](https://cloud.google.com/kubernetes-engine/docs/concepts/release-channels)
コントロールプレーンにおいて自動アップグレード設定を行う際、リリースチャンネルというものを選択する必要があります

リリースチャンネルは、コントロールプレーンとノードプールのアップグレードが自動的に管理される仕組みです
ニーズに応じて3つのチャンネルを選択するかたちとなり、選択したチャンネルによって適応されるバージョンの成熟度が変わります
3つのチャンネルは適応されるバージョンがより新しい順に
Rapid > Regular > Stable
となります

Rapidチャンネルは、K8sの新しいバージョンがリリースから数週間で利用可能になります
そのため、早期に新機能の利用が可能になる一方、安定性は残り2つのチャンネルに比べると低く、[GKE SLA](https://cloud.google.com/kubernetes-engine/sla)の対象外となっています

残りのRegularチャンネルはRapidチャンネルでのリリースから2, 3ヶ月後、
StableチャンネルはRegularチャンネルでのリリースから2, 3ヶ月後に各バージョンが利用可能になります
そのため、本番環境においてはRegularチャンネルかStableチャンネルの利用が推奨されます

## [メンテナンスの時間枠と除外](https://cloud.google.com/kubernetes-engine/docs/concepts/maintenance-windows-and-exclusions)
自動アップグレード含めた各種メンテナンスについては、実行してほしい日時（メンテナンスの時間枠）及び実行してほしくない期間（メンテナンスの除外）をしていすることが可能です

メンテナンスの時間枠の設定により、例えば営業時間である日中は避け、営業時間外の深夜にメンテナンスを行うなどといったことが可能になります

また、メンテナンスの除外の設定により、例えば大規模なイベントが予定されている場合、イベント前の1週間及びイベント期間中の間はメンテナンスを抑制するといったことが可能になります
メンテナンスの除外については、どのレベルの処理を抑制するかといった指定も可能です（[参考](https://cloud.google.com/kubernetes-engine/docs/concepts/maintenance-windows-and-exclusions#scope_of_maintenance_to_exclude)）