GKEとVMインスタンスのメンテナンス(ライブマイグレーション)について

3 min read読了の目安(約3200字

結論

  • ライブマイグレーションが起きるとPodにスリープ(数秒〜数分間Podの処理が一時停止する)が発生する
  • ライブマイグレーションは2週間に1回ぐらいの頻度で発生する
  • 標準GKEでもGKE Autopilotでも、ライブマイグレーションをおこなわいように設定することはできない
  • ライブマイグレーションによるスリープの影響を最小限にするには、GKE上で実行させるアプリケーション側で対応するしかない
  • ライブマイグレーションが発生したかどうか確認する方法はこちら

背景

GKEに構築したアプリケーションへのAPIリクエストがタイムアウトしました。
ログを追いかけていくと、Datastoreからデータをフェッチするのに数分かかっている様子だったので、GCPに問合せしたところ、Datastoreのフェッチに時間がかかっていたわけではないことがわかりました。
その後さらに調査をし、GKEのノードとして利用しているVMインスタンスのメンテナンスイベントがAPIリクエストと同じタイミングで発生していたことがわかりました。
VMインスタンスのメンテナンスイベントでは、ライブマイグレーションが実行されるため、処理中のpodが数分間スリープしてしまったことが原因でした。

解説

ライブマイグレーションとは

メンテナンスイベントについて

  • メンテナンスイベントでは、ハードウェアとソフトウェアを更新される
  • ホストメンテナンス簡易メンテナンスの2種類がある
  • ホストメンテナンスでは新しいホストへのライブ マイグレーションが必要
  • メンテナンスイベントのスケジューリングは、自動で管理されているので、タイミングを指定することはできない

https://cloud.google.com/compute/docs/instances/setting-instance-scheduling-options?hl=ja#maintenanceevents

GKEとメンテナンスイベントの設定

  • GKEのノードとして利用しているVMインスタンスでもメンテナンスイベントは発生する
  • GKEのノードして利用しているVMインスタンスのライブマイグレーションの設定を変更するこはできない
  • GKEでライブマイグレーションが発生することは避けられない
  • GKE Autopilotでも同じくライブマイグレーションが発生することは避けられない
  • ユーザーから機能追加のリクエストがきてはいるが、採用されるかはわからない

※公式ドキュメントに記載は見つけられませんでしたが、GCPの技術サポートに問い合わせて確認した内容です

GKEとライブマイグレーション

  • ライブマイグレーションによりノードは移行先のホストに退避される
  • Podは親であるNodeと共に、移行先のホストへ引っ越す
    • ライブマイグレーションではPodは停止もしなければ新しく作成もされない
  • イメージ
    • 移行前: HostA( NodeX(PodY)) )
    • 移行後: HostB( NodeX(PodY)) )
  • 移行している間、フリーズが発生することによって、ネットワークを遅延させるなどの影響がある

※公式ドキュメントに記載は見つけられませんでしたが、GCPの技術サポートに問い合わせて確認した内容です

GKEのアップグレードとVMインスタンスのメンテナンスって違うの?

  • 違います
  • GKEのアップグレードはkubernetesのバージョンをアップグレードするためのものです
  • それとは別にノードとして利用しているVMインスタンスのメンテナンス(=ライブマイグレーション)が実行されます
    • ライブマイグレーションが実行されると、起動中のPodがスリープします(数秒〜数分間Podの一時処理が停止する)
    • APIリクエストなどを捌いてる途中のPodが停止すると、APIリクエストの返却までより長い時間がかかることになるので、若干のダウンタイムが発生するといえるかもしれない

ライブマイグレーションの影響を受けないためには?

  • 標準GKEでもGKE Autopilotでもライブマイグレーションの影響を受けなくすることはできない
  • 別々のノードに複数のPodを配置しても、たまたま処理中のPodが所属するノードがライブマイグレーション発生することがあるので、Podのスケジューリングによっても影響を受けなくすることはできないが、影響を小さくすることはできる。
  • GKEで実行するアプリケーション側で影響を最小限にするための実装をする必要がある
    • リトライロジックをいれる
    • 別のノードに配置された複数のpodへリクエストを送り、最初にレスポンスを返したものを採用する
    • など、他の方法も模索中です

ライブマイグレーションが発生したログを取得する

  • GCP ConsoleのCloudLoggingページを開く
  • ログの検索フィールドに以下の二つを追加
    • resource.type="gce_instance"
    • operation.producer="compute.instances.migrateOnHostMaintenance"
  • ログを検索する

さいごに

影響を小さくすることはできての、回避不可能な問題なので、かなり悩んでいます。
今のところ、クライアントからAPIリクエストを送るときに、タイムアウトとして判定すべき時間と、タイムアウトした場合にリトライする、という対応で影響を最小限に押えようかなと思っています。