Help us understand the problem. What is going on with this article?

GKEクラスターのバージョン管理を便利にする自動アップグレードの戦略

はじめに

GKE(Google Kubernetes Engine)には、クラスタの自動アップグレード機能があります。Kubernetesにおけるマスターのバージョン管理をGoogleに任せることができる機能で、これを使うことで自分たちでクラスターの中身を入れ替える必要がなくなるため、運用コストの削減につながります。NodeのmaxSurge/maxUnavailableと組み合わせるとほぼ全自動でクラスタのバージョン入れ替えが終わりますね!なお、この機能はデフォルトで有効化されており、無効にすることはできません。

Ref: https://cloud.google.com/kubernetes-engine/docs/concepts/cluster-upgrades

今回は、この自動アップグレードにおいて注意すべきポイントや、どのような設定ができるかを見ていきます。

公式ドキュメントが散らばっているのとわかりにくいので、Terraformでどう設定するかも含めてまとめてみました。

GKEのReleaase channelについて

GKEにはリリースチャンネルという概念があり、それぞれのチャンネルに応じて、別々のバージョンライフサイクルがクラスターに提供されます。

チャンネル おおよそのアップグレード サイクル 対象ユーザー 見込み
Rapid 毎週 新しい機能を必要とする早期のテスターとデベロッパー。 認定された最新のコンポーネントで、他すべてのチャンネルより早期に提供されます。他のチャンネルよりも検証が不十分で、既知の解決策のない問題などの、未解決の問題が含まれます。本番環境のワークロードはサポートされません。GKE SLA の対象外です。
Regular 1 か月に複数回 Stable チャンネルで未提供の機能を必要とする本番環境のユーザー これらのバージョンは内部検証に合格しており、本番環境に対応した品質であると見なされていますが、履歴データが不十分なため安定性は保証されません。既知の問題には、通常は既知の解決策があります。
Stable 数か月に 1 回 安定性を何よりも優先し、頻繁なアップグレードによるリスクの大きい本番環境のユーザー これらのバージョンは、標準チャンネルの要件すべてを満たしており、実行中のクラスタのパフォーマンスに基づいて、本番環境レベルの安定性、信頼性があるものであることが判明しています。

※公式ページから引用

例えば、2020年1月頭におけるバージョンはそれぞれRapidが1.16、Regularが1.14、Stableが1.13となっています。

GKEにおけるKubernetesはDigital OceanやAmazon EKSなどと違い、多くの機能がデフォルトで統合化されたものです。より新しいバージョンベースのほうが有効な機能が多い一方で、Stableチャンネルのほうが変更頻度も少なく自動アップグレードなどに悩まされる心配も少ないという側面もあります。

例えば、GKE上でGCLBのIngressを使うためのIngress Controllerにはingress-gceがありますが、こちらはALB Ingressと異なりデフォルトでGKEのクラスターに組み込まれています。ingress-gceのリリースノートをご覧になれば分かる通り、新しいバージョンのIngress Controlelrは新しいバージョンのGKEでないと使えません。

まずは、お使いのクラスターの特性やメンテナンスコストの観点から、どのリリースチャンネルを使うべきかを見定めてみるとよさそうです。

自動アップグレードの適用とメンテナンス時間枠の設定

自動アップグレードは基本的にGoogleが自動的にスケジュールしたタイミングで発生します。そのため、ユーザーが手動でクラスターのバージョンを上げない限り、手元で具体的な時間を制御することはできません。

しかし、メンテナンスの時間枠と除外を設定することで、一定の制限の範囲において「このタイミングでのみアップグレードを行う」という条件を設定できます。

スクリーンショット 2020-01-06 11.33.10.png

クラスター作成時に実際に設定するときはこのような形で行います。

メンテナンス時間枠における制限事項

GCPのドキュメントには以下のような記述があります。

14日間のローリング ウィンドウ内で少なくとも24時間はメンテナンスが可能な状態にする必要があります。メンテナンスに4時間以上連続する時間を用意してください。

日本語がわかりにくいのですが、これは、要するに

  • 14日間(2週間)の間に少なくとも合計で24時間のメンテナンス時間を作る
  • 1回のメンテナンス時間は最低でも4時間以上確保する

という2つの条件を満たす必要があるという意味になります。

逆算すると、14日間に24時間以上なので、仮に毎日メンテしていいがとにかく最低限の時間に抑えたい場合は24/14で平均して1.71時間以上を設定すればよいが、1回のメンテナンス時間は4時間以上確保する必要があるのでだめ。

このバランスを取ろうと思うと、4(時間)×6(日)=24なので、1週間のうち少なくとも3日、4時間のメンテナンス時間を設ければよい、という計算になります。

結論

以上を踏まえて、うちのチームでは以下のような設定をTerraformに入れました。

cluster.tf
resource "google_container_cluster" "cluster-name" {
  provider                 = google-beta

...

  maintenance_policy {
    recurring_window {
      start_time = "2019-12-04T05:00:00+09:00"
      end_time   = "2019-12-04T09:00:00+09:00"
      recurrence = "FREQ=WEEKLY;BYDAY=MO,TU,WE,TH"
    }
  }

}

ドキュメントにもある通り、時刻と日付のフォーマットはRFC-5545準拠なので、このような表記になります。

月曜から木曜の朝5時から9時までメンテ時間として確保しています。

マスターのバージョンアップはワークロード(上に乗ってるアプリ)自体には原則として影響はありません。

ただ、Kuberntes APIを使うようなアプリ(例えばバッチで内部的にKubernetesのPodをプロビジョンするとか)の場合はAPI Serverの応答がなくなるので注意が必要です。

inductor
8割くらい正しい情報を噛み砕いて3秒で出すのが得意
https://inductor.me
infra-workshop
インフラ技術を勉強したい人たちのためのオンライン勉強会です
https://wp.infra-workshop.tech/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした