Google Kubernetes Engineのバージョンアップ

Google Kubernetes Engine(GKE、2017秋にGoogle Container Engineから改称)はGCE上に構築されたkubernetesのマネージドクラスタです。

kubernetesは活発なオープンソース開発が継続していて、年数回のバージョンアップが提供されています。

GKE上のkubernetesバージョンアップの素朴な手順は、Webコンソールから実行可能です。

GCEのWebコンソールのKubernetes Engineカテゴリにクラスタがリストされており、個別にkubernetesバージョンアップも実施できます。

k8sマスター→ノードの順に更新

GKEのk8sは”マスター”と”ノードプール”をそれぞれ管理でき、バージョンアップの際はまずマスターを更新し、ノードプールをマスターverに追蹤させる手順になります。

クラスタ詳細画面の“バージョン”の欄に「アップグレード可能」と表示されている場合、マスターをアップグレードできます。

マスター更新中は、Pod作成などのk8sクラスタ操作は中断しますが、クラスタ上で実行しているアプリのサービスは継続しています。

ノードプール更新

マスターの更新が完了したら「ノード」タブに表示されるノードプール一覧から個別に更新します。
各ノードプール詳細画面から「編集」を選択すると、ノードのバージョンを「変更」するボタンが表示されます。

選択可能なバージョンのリストから、コントロールプレーンのバージョンを選択するとマスターと同じバージョンになります。

ダウンタイムの考慮

ノードプール更新では、クラスタの再構成が走りサービスが停止するため、計画停止のスケジュールを立てた方が良いでしょう。

ノードプールの設定で、サージアップグレードを有効にしておくと、新バージョンのノードを構築してから旧ノードを削除する挙動になります。

バージョンアップの際の短時間だけ最大サージに指定したノード数のVMインスタンスが追加され、その分ダウンタイムを減らせるため、サービス継続重視の場合リーズナブルでしょう。

もし切り戻しを含めた手順を必要する場合は、Webコンソールからの更新ではなく独自のBlue-Greenデプロイメントを計画すべきです。
新たにノードプールを作成したうえでクラスタ構築して、トラフィックを切り替えた後に旧ノードプールを削除する手順となります。

バージョンupのリカバリはControllerに依存している

ノードのアップグレードでは、一度ノードが除去され、新バージョンのノード上でPodが再構成されます。 この際、コンテナダウン時と同様に自動復旧は Deployment/StatefulSet/DaemonSetなどのコントローラーの機能に依存しています。
kubernetes導入の際にはとくに問題ない前提でしょう。

k8sでは個別Podを設定してコンテナを起動する方式もとれますが、Pod設定で動作しているコンテナはノード再起動の際に抹消されるため注意が必要です。

再構成後にコンテナが起動しない場合の例

ノードプールの更新をWebコンソールで確定したあとは基本的には自動プロセスに入るため経過を眺めるだけです(数分程度)。

kubectl get podsコマンドを実行してすべてのPodがReadyになれば完了です。ノードの更新状況はkubectl get nodesで確認できます。

このプロセスに介入余地はあまりないのですが、キャパシティオーバーで一部のコンテナが起動しきれないケースに遭遇する場合があります。

従来のクラスタリソースをぎりぎりまで利用していた場合、新バージョンのk8sクラスタのシステムコンテナが旧バージョンよりリソース消費が増えてあふれるという事象に遭遇しました。

バージョンアップが完了しReady状態のノード数が設定通りに安定した状態(kubectl get nodesで確認)で、kubectl get podsのリストに”Pending”のコンテナがあればリソース確保できていない可能性が高いです。

ノード上のリソース(CPU・メモリ)をどれだけ消費しているかを確認するには、kubectl describe nodesコマンドを利用します。

たとえば、コンテナが宣言しているCPUリソースの合計値が100%を超えるようなケースでは、CPUを確保できず起動しないコンテナが発生します。

リソース不足に対する基本的な対処方法は、ノードプールにノード(仮想マシン)を追加することです。新規ノードがReadyになるとPendingのコンテナが自動でクラスタに参入し始めます。

まとめ:k8sの定期更新はかんたん&重要

GKEはkubernetesクラスタ運用が全般的に自動化されていて、構築不要・メンテナンスの多くがWebコンソールから実行可能です。計画停止を許容できるのであれば、ミドルウェアのアップグレードもコンソール上のボタン操作で完結します。

k8sのコンテナ構成定義は、Serviceと各種Controllerの設定ファイルであり、現状、設定の仕様は安定しているため、バージョンアップにあたりコンテナ構成レベルで大がかりな変更作業は発生していません。

メジャーバージョンの間隔が空いた更新の場合には、古いAPIの廃止などkubernetes自体の非互換が起きることはあります。
これはGKE特有の問題ではなく、kubenetesのリソース管理上の共通課題です。

このような非互換は、日常の運用時にkubectl applyのレスポンスに非推奨の予告が表示されるため、個別にクリアしておくことが重要です。

GKEのサポートポリシーとして3バージョン以上古いクラスタは非サポートになっていくので、年数回のバージョンアップは計画的に対応すべきと言えます。

中馬崇尋
Chuma Takahiro