GKE のアップグレード戦略を改めて確認しよう
この記事は Google Cloud Japan Customer Engineer Advent Calendar 2019 の 3 日目の記事です。
本記事では、GKE を対象に、マスター、ノードのアップグレード戦略について紹介します。11/5 には Surge Upgrade がベータ版としてリリースされましたので、そちらも合わせて紹介します。
GKE のアップグレード戦略
Kubernetes は、約 3 ヶ月ごとにマイナーバージョンがリリースされます。また、3 つのマイナーリリースをサポートするというポリシーになっています( v1.3 がリリースされたタイミングで、 v1.0 はサポートされなくなります)。そのため、Kubernetes を運用するに当たって、Kubernetes を適切にアップグレードしていくことは、必須の作業といえるでしょう。
では、GKE のアップグレードを考えるに当たり、どのようなパターンがあるでしょうか。以下にまとめてみました。
■ マスターのアップグレード
- 自動アップグレード
- 手動アップグレード
■ ノードのアップグレード
- 自動アップグレード
- 手動アップグレード(3 パターン)
ここからは、具体的にどのような手順でアップグレードを行うか、考慮すべきポイントなどをご紹介していきます。公式ドキュメントに、より詳細な情報が記載されていますので、そちらもご覧ください。
マスターのアップグレード
自動アップグレード
GKE のマスターは GCP におまかせで、基本的にマスターのメンテナンスを気にする必要は有りません。マスターの自動アップグレードについては、GKE の Release notes に情報が記載されています。
※ ただし、自動アップグレードの情報が事前に掲載されることが保証されているわけでは無い点に注意しましょう
ただ、自動アップグレードといっても、設定によっては、マスターのアップグレード中、 kubectl
コマンドなど、操作を一時的に受け付けなくなります。本番環境で利用する GKE で日中帯に操作を受け付けなくなってしまうと、ビジネスに支障が出ないとも限りません。
マスターの自動アップグレードをより詳細にコントロールするため、以下の仕組みが提供されています。
リージョンクラスタ/ゾーンクラスタ
GKE では、リージョンクラスタまたはゾーンクラスタいずれかの可用性を持つマスターを選択することができます。
ゾーンクラスタでは、単一のマスター VM がデプロイされるため、アップグレード中にはマスターにダウンタイムが発生します。一方、リージョンクラスタを選択した場合、複数のゾーンに対してマスター VM がデプロイされるため、メンテナンスやゾーン障害が発生したとしても、Kubernetes API を利用し続けることができます。
本番環境であれば、リージョンクラスタを指定しましょう。
メンテナンスウィンドウ
メンテナンスウィンドウは、GKE のアップグレードを実施する時間帯(GA)または、実施しない時間帯(ベータ版)を指定するための仕組みです。メンテナンスウィンドウを利用することで、メンテナンスによるマスターのダウンタイムの影響が少ない時間帯にメンテナンスを実施させたり、逆に、ピーク時間帯からずらすといったことが可能となります。また、複数のクラスタを運用している場合は、メンテナンス実施タイミングを揃えるといった用途でも利用可能です。
リリースチャンネル
リリースチャンネルは、GKE クラスタの自動アップグレードをより詳細に制御するための仕組みです。「Rapid」「Regular」「Stable」の三つのチャンネルが提供されており、自動アップグレードの更新頻度がそれぞれ異なります。
新しい機能を積極的に試したい、本番環境をアップグレードする前に自社アプリケーションの挙動を確認したい場合などに「Rapid」を利用するといったことが考えられるでしょう。
GKE を適切に設定することによって、自動アップグレードの恩恵を受けつつ、自動アップグレードを適切にコントロールしましょう。
手動アップグレード
もちろん、手動で GKE のマスターをアップグレードしたい場合もあるでしょう。そのような場合は、以下のコマンドでアップグレードすることができます。
# サポート可能なバージョンを取得(東京リージョンを指定した例)
$ gcloud container get-server-config --region=asia-northeast1# アップグレードを実行
$ gcloud container clusters upgrade [CLUSTER_NAME] --master --cluster-version [CLUSTER_VERSION]
ノードのアップグレード
自動アップグレード
2019年12月時点で、ノードのアップグレードはデフォルトで「自動」に指定されています(ドキュメント)。マスターがアップグレードされると、ノードのアップグレードがスケジュールされます。自動アップグレードを有効にしておくことで、マネジメントコストをかけず、常にセキュリティを最新の状態に保つことが可能です。
ノードの自動アップグレードでは、一台ずつノードがローリングアップグレードされるのがデフォルトの挙動です。ただし、この挙動だと、ノード数が多い場合にアップグレードの時間がかかったり、逆に、ノード数が少ない場合は、アップグレード時のノード数減少により、クラスタ全体のキャパシティが減少し、GKE 上で可動する自社サービスの可用性を損なう可能性があります。
上記を回避するには、Surge Upgrade (ベータ版)を利用することができます。Kubernetes を利用されている方であれば、 Deployment
リソースで指定できる maxSurge
、maxUnavailable
をイメージしてもらえれば、わかりやすいでしょう。
Surge Upgrade では、max-surge-upgrade
と max-unavailable-upgrade
を指定することで、アップグレード中に追加できるノード数、アップグレード中に利用不可にできるノード数を指定することが可能です。
$ gcloud beta container clusters create test-cluster --max-surge-upgrade=2 --max-unavailable-upgrade=1 --zone=asia-northeast1-a
NAME LOCATION MASTER_VERSION MASTER_IP MACHINE_TYPE NODE_VERSION NUM_NODES STATUS
test-cluster asia-northeast1-a 1.13.11-gke.14 35.200.39.79 n1-standard-1 1.13.11-gke.14 3 RUNNING# 動作確認のため、Cloud Consoleで以下を実施
# (1) マスターをアップグレード
# (2) ノードをアップグレード# 認証情報を取得
$ gcloud container clusters get-credentials test-cluster --zone asia-northeast1-a# ノードのアップグレード状況を確認(以下は、アップグレード途中の結果を表示)
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
gke-test-cluster-default-pool-8bc9077a-0qk7 Ready,SchedulingDisabled <none> 18m v1.13.11-gke.14
gke-test-cluster-default-pool-8bc9077a-1zws Ready,SchedulingDisabled <none> 18m v1.13.11-gke.14
gke-test-cluster-default-pool-8bc9077a-5n29 NotReady,SchedulingDisabled <none> 16m v1.13.11-gke.14
gke-test-cluster-default-pool-8bc9077a-l0v9 Ready <none> 18m v1.13.11-gke.14
gke-test-cluster-default-pool-8bc9077a-nsd7 Ready <none> 28s v1.13.12-gke.13
gke-test-cluster-default-pool-8bc9077a-qcjv Ready <none> 32s v1.13.12-gke.13
gke-test-cluster-default-pool-8bc9077a-sz9m Ready <none> 16m v1.13.11-gke.14
手動アップグレード
手動でノードをアップグレードする方法は、幾つか考えられます。シチュエーションに応じて使い分けると良いでしょう。
(1) 現在のノードプールをアップグレード
現在のノードプールを手動でアップグレードするには、以下のコマンドを実行します(ドキュメント)。なお、前述の Surge Upgrade は、手動アップグレードの場合も有効です。
$ gcloud container clusters upgrade [CLUSTER_NAME] --node-pool=[NODE-POOL-NAME] --cluster-version [CLUSTER_VERSION]
(2) 新しいバージョンのノードプールを作成し、ワークロードを移行
新しいバージョンのノードプールを追加し、ワークロードを移行する方法です。新しいバージョンのノードにワークロードを徐々に移行していく場合や、サービス全体のキャパシティを落とさずにアップグレードを実施したい場合に選択します(現時点ではベータ版ですが、 Surge Upgrade によって後者のユースケースはカバーされます)。
具体的な手順は「異なるマシンタイプへのワークロードの移行」を参照してください。
この際、GKE 上で可動するサービスのキャパシティを落とさないようにする必要があります。PodDisruptionBudget
リソースを利用して、レプリカ数が一定数以下にならないよう、適切に設定しましょう。
(3) クラスタを再作成
クラスタの設定変更など、ノードのアップグレード以外の用途も含めて、クラスタ自体を再作成したい場合もあります。その場合は、GKE の手前にトラフィックを分散するコンポーネントが必要となります。例えば、Fastly を利用すると、以下のような構成となります。
この構成の場合、なにかトラブルが起こった際の切り戻しも、トラフィックを元のクラスタに向け直すだけのため、非常に手軽です。トラフィックを新しいクラスタに徐々に向けていくカナリアリリースも可能なため、リスクマネジメントにも有効でしょう。
一方、一時的にクラスタを 2 つ運用することになるため、インフラ、運用のコストが上がってしまう点には注意が必要となります。
なお、上記の構成は、例えば、一部のマイクロサービスで GAE を採用したり、オンプレミス環境から徐々にクラウドにトラフィックを移行する際などにも応用することができます。
おわりに
本記事では、GKE のアップグレードを行う際に、どういった戦略を取ることが出来るのかをご紹介しました。GKE は、フルマネージドなサービスで有り、GKE を最新に保つための方法が多く提供されています。それぞれの方法に利点や考慮点があるので、より安全にGKE を運用していくために、それぞれに合ったアップグレード戦略を選択しましょう。
明日は、 Jumpei Arashi による「複数のCloud Functions entrypointsを1 github repository(NodeJS with TypeScript)で管理する -Usecaseを添えて-」です。
お楽しみに!