強化された GKE の Maintenance Exclusions を解説する

Kazuu
google-cloud-jp
Published in
15 min readFeb 3, 2022

Kubernetes / GKE ファンの皆様、こんにちは。Google Cloud の Kazuu (かずー) です。

Kubernetes を利用されているユーザーにとって、アップグレードをどう乗り切るか、は非常に大きな課題だと思います。GKE にも Release channelSurge upgrade などアップグレードを自動化し、作業負荷を軽減するための機能は従来からありました。ただ皆さんが求めていたものは、「当分の間、アップグレードをしなくてよい」というシチュエーションではないでしょうか?

本記事ではそんな「当分の間、アップグレードをしなくてよい」 GKE をどう実現するか、について解説します。

TL;DR

  • GKE の Maintenance Exclusions (メンテナンスの除外) 機能が強化されました。
  • Scope という概念が導入され、Scope 毎に設定可能なメンテナンス除外期間が定義されました。
  • Release Channel に登録されたクラスタが前提となりますが、Scope によっては最大連続 180 日間のメンテナンスの除外を実現出来ます。条件が揃えば、更なる期間のメンテナンスの除外が可能です。
  • Maintenance Exclusions と Maintenance Windows は Release Channel や Node のオートアップグレード機能を使っていない場合も有効です。
    ぜひ活用しましょう!

1. GKE のバージョン

本題に入る前に少しだけ復習です。ひとえに GKE のバージョンと言っても以下の通り、K8s マイナーバージョン、K8s パッチリリース、GKE パッチリリースの 3 つから構成されています。

GKE のバージョンを分解

K8s マイナーバージョンが上がると、API 仕様の変更など大きめのインパクトが想定されます。OSS の Kubernetes は年間 3 回のマイナーバージョンのリリースを予定しています。一方パッチリリースはほぼ毎週のようにリリースされており、Bug fix や Security アップデートなどが含まれます。パッチリリースのケイデンスはマイナーバージョンよりも高く、数週間に 1 度となっています。GKE もこれらのケイデンスに準ずることになります。

更に GKE では以下の通り、大きく 2 つのコンポーネントのバージョンを分けて管理しています。

  • Control plane バージョン
    GKE の Control plane で使われるバージョン。
    クラスタで使われる大半のソフトウェアのバージョンを指す。
    GKE では基本的に自動でアップグレードされ、ユーザーが無効にすることは出来ません。
  • Node バージョン
    GKE の Nodeで使われるバージョン。
    主に OS イメージおよび Kubelet のバージョンを指す。
    自動アップグレードを利用するかはユーザーが選択可能。

また、以下のようなルールもあります。

  • Node は Control plane よりも新しいバージョンは使えない
  • Node は Control plane から 2 マイナーバージョン古いものまで利用可能

2. Release Channel とは

Release channel とは GKE の Control plane と Node のアップグレードを自動で実行する機能です。Release channel には以下の通り複数の Channel が存在し、Channel 毎にアップグレードの頻度やバージョンの新しさが違います。ユーザーはクラスタ毎に Channel を選択することが可能です。本番環境での利用は Regular か Stable をおすすめしています。

Release Channel の種類

どのバージョンが各 Channel 毎にいつリリースされるのか?は GKE Release Schedule というページに纏まっていますので、スケジュールを逆算しつつ、テスト環境での検証など前もって実施することが可能です。是非活用してください。

Release Channel では Control plane と Node が自動アップグレードされ便利な反面、自分たちで実行タイミングを制御出来ない懸念があるかと思います。GKE では、Maintenance Windows (メンテナンスの時間枠) という機能があり、自動アップグレードを実行する時間帯を指定することが可能です。ただし、以下のような条件があります。

  • 32 日周期で最低 48 時間の時間枠
  • 各時間枠は 最低 4 時間以上の連続した時間

特に Node のアップグレードはサービスへの影響も考慮する必要があるため、Maintenance Windows を使って自動アップグレードがビジネスアワーや繁忙期を避けたタイミングで実行されるよう、予め設定しておくことが大切です。

注意: Maintenance Windows は Release Channel を設定したクラスタに限らず、Control plane の自動アップグレード、Node の自動アップグレード等に対して有効です。

3. Maintenance Exclusions とは

ここからが本題です。(前置きが長くなってすみません)

Maintenance Exclusions (メンテナンスの除外) とは前述の Maintenance Windows と反対に、自動アップグレードを絶対に実行しない時間帯を指定する機能です。ちなみに Maintenance Windows と Maintenance Exclusions の設定が重複した場合には、Maintenance Exclusions が優先されます。

今回、この Maintenance Exclusions が強化され、以下のように Scope を設定出来るようになりました。Scope 毎に Exclusion の対象となる自動アップグレードの種類が定義され、その結果、サービス影響なども変わってきます。尚、No minor upgrades と No minor or node upgrades は Release Channel に登録されたクラスタのみ設定可能です。

Maintenance Exclusions Scope
  • No upgrades (default)
    Control plane 及び Node の 全ての自動アップグレード を実行しません。1 回の Exclusion で 最大 30 日まで設定出来ます。1 クラスタにつき最大 3 個まで設定可能ですが、上述の 「32 日周期で最低 48 時間の時間枠」が適用されるため、30 日間の Exclusion を 3 回設定し連続 90 日間の Exclusion にすることは出来ません。また、Static version のクラスタはこちらの Scope しか利用出来ません。
  • No minor upgrades
    Control plane 及び Node のパッチ アップグレードを除く、全ての自動アップグレードを実行しません。Node のアップグレードの際、サービスへの影響が発生する可能性があります。Exclusion 設定時点から 180 日を超えて設定することは出来ません。また当該マイナーバージョンの EOL (End Of Life) date を超えることも出来ません。この Scope はRelease Channel に登録されたクラスタのみ利用可能です。
  • No minor or node upgrades
    Control plane のパッチ アップグレードを除く、全ての自動アップグレードを実行しません。Exclusion 設定時点から 180 日を超えて設定することは出来ません。また当該マイナーバージョンの EOL date を超えることも出来ません。このScope はRelease Channel に登録されたクラスタのみ利用可能です。

各マイナーバージョンの予定されている EOL date については先の GKE Release Schedule をご確認ください。各マイナーバージョンがざっくりですが、利用開始から EOL まで1年強というスケジュールになっています。

注意: Maintenance Exclusionsは Release Channel を設定したクラスタに限らず、Control plane の自動アップグレード、Node の自動アップグレード等に対して有効です。ただし、Static version ( Release Channel を設定していない)の場合は、上記 No upgrades scope のみサポートされます。

4. 長期間の Exclusion をどう実現するか?

3 つの Scope のうち、恐らく一番需要があるのが、Control plane のマイナーバージョンを固定しつつ、Node のアップグレードを一切行わない、No minor or node upgrades になるかと思います。この Scope は最大 180 日間 Exclusion を行いますが、例えば、180 日経過後に当該マイナーバージョンが EoL を迎えていなければ更にExclusion を設定することが可能です。

例えば、私が運用しているクラスタ “lts-cluster-01” は Regular channel に登録されており、本記事を執筆している 2022 年 1 月 7 日時点のバージョンが 1.21.5-gke.1302 です。GKE Release Schedule を見ると、1.21 の EoL は 2022 年 10 月とあるので、2022 年 10 月末まで、約 10 ヶ月間の Maintenance Exclusions (No minor or node upgrades) を 今回は CLI で設定してみます。

❯ gcloud container clusters update lts-cluster-01 \
--region us-central1 \
--add-maintenance-exclusion-name 10months-exclusion-1 \
--add-maintenance-exclusion-start=2022-01-08T00:00:00+09:00 \
--add-maintenance-exclusion-end=2022-07-06T00:00:00+09:00 \
--add-maintenance-exclusion-scope no_minor_or_node_upgrades
Updating lts-cluster-01...done.
Updated [https://container.googleapis.com/v1/projects/kzs-sandbox/zones/us-central1/clusters/lts-cluster-01].
To inspect the contents of your cluster, go to: https://console.cloud.google.com/kubernetes/workload_/gcloud/us-central1/lts-cluster-01?project=kzs-sandbox

以上のように Exclusion を設定出来ました。尚、一度設定した Exclusion は
--remove-maintenance-exclusion オプションを使って削除することも可能です。間違って設定した、急遽予定が変わったなどがあった場合にも安心して使って頂けます。

このまま 2 回目の Exclusion を設定したいところですが、上述の通り、 Exclusion 設定時点から 180 日を超えて設定することは出来ません。そのため 1 回目の Exclusion から 180 日後 もしくは EoL date から見て 180 日以内にならないと 2 回目の Exclusion を設定することが出来ません。以下は 180 日後に 2 回目の Exclusion を設定するイメージ図です。

ためしに 2 回目の Exclusion を設定しようとすると、以下のようなエラーになってしまいます。

❯ gcloud container clusters update lts-cluster-01 \
--region us-central1 \
--add-maintenance-exclusion-name 10months-exclusion-2 \
--add-maintenance-exclusion-start=2022-07-06T00:00:00+09:00 \
--add-maintenance-exclusion-end=2022-10-31T09:00:00+09:00 \
--add-maintenance-exclusion-scope no_minor_or_node_upgrades
ERROR: (gcloud.container.clusters.update) ResponseError: code=400, message=MaintenancePolicy.maintenanceExclusions["10months-exclusion-2"].endTime needs to be within 6 months from now.

エラーにはなってしまいましたが、段階的に設定すれば、 298 日間の Exclusion が理論上構成可能です。

GKE Release Schedule では EoL の月のみが記載されており、具体的な日付や時間までは明示されていません。2022.01.07 現在の実装では、EoL date の validation check が存在し、2022–10 の EoL の場合は 2022–10–31T00:00:00Z (UTC) が EoL date の終点となります。これはあくまで Maintenance Exclusions の設定上であり、公式ドキュメントにも記載がなく、今後変更される可能性も 0 ではないため、ご注意ください。
以下は試しに 1 分だけ後ろに設定してみた例です。エラーで怒られてしまいます。ご参考まで。

❯ gcloud container clusters update lts-cluster-01 \
--region us-central1 \
--add-maintenance-exclusion-name 10months-exclusion-2 \
--add-maintenance-exclusion-start=2022-07-06T00:00:00+09:00 \
--add-maintenance-exclusion-end=2022-10-31T09:01:00+09:00 \
--add-maintenance-exclusion-scope no_minor_or_node_upgrades
ERROR: (gcloud.container.clusters.update) ResponseError: code=400, message=MaintenancePolicy.maintenanceExclusions["10months-exclusion-2"].endTime needs to be before minor version 1.21 end of life: (2022-10). See release schedule at https://cloud.google.com/kubernetes-engine/docs/release-schedule.

5. まとめ

最後まで読んで頂きありがとうございました。

本記事では強化された GKE の Maintenance Exclusions 機能を使って、どのように長期間に渡りアップグレードフリーな状況 を作り出すかを解説しました。

ちなみに Exclusion が終わった後ですが、登録している Release channel のデフォルトバージョンから Exclusion 明けのクラスタのマイナーバージョンが遅れている場合(大体のケースでそうなると思います) は、月 1 回のケイデンスでマイナーバージョンのアップグレードが行われます。結局のところアップグレードを避けることは出来ないので、特別な事情がない限りは長期間の Exclusion は避けた方が無難だと個人的には思います。(最後に話の腰を折ってすみませんmm)

あるいは、In-place のアップグレードをやめて、長期間の Exclusion 明けにクラスタレベルの B/G アップグレードを行う(新しい version のクラスタを横に立てて移行する) のも良いかもしれません。理論上は年に 1 回程度のアップグレード対応作業になりますし、運用負荷は低減出来るかと思います。クラスタレベルの B/G アップグレードについては、昨年の Open Cloud Summit で 日経新聞社の 岩月さんが Multi-cluster Ingress (F.K.A Ingress for Anthos) を利用した方式を紹介してくれてますので、ぜひ参考にしてみてください。(Link to session)

また、短期間であっても不慮のトラブルを避ける意味で Maintenance Exclusions は非常に有効です。繁忙期やイベントに合わせて上手く使って頂けると幸いです。

それでは快適な GKE ライフを!!

--

--

Kazuu
google-cloud-jp

Customer Engineer at Google Cloud Japan. GKE & Cloud Run enthusiast. Opinions are my own, NOT views of my employer.