TT Lab
はじめる
学ぶ 学習パス コース

CKAD — Kubernetesアプリケーション開発者

Podを退勤させよう — 応答を返してから終了

TT Labで続きを見る

目標

個人のk3s VMで、すでに処理中のHTTPリクエストを残したままPodを終了し、アプリの終了処理・EndpointSlice・終了猶予を結び付けて説明します。実際のプロセスを使い、kwokによる状態のシミュレーションではありません。

なぜ重要なのか

Deploymentの成功の表示は、処理中だったリクエストの完了を保証しません。ここでは、読み取り専用のコードで実行される小さなHTTPサーバーを置き、学生が作成したPodの宣言をヘルパーがそのまま生成します。まずService経路とリクエストの受け付けを確認し、Pod watchを開始した状態で削除するので、同じUIDのレスポンス・切断・終了コードを結び付けられます。

通常の終了と猶予不足を比較しますが、小数点以下の時間を当てるラボではありません。入力ファイルや観測ファイルをコピーして成功の文を作るのではなく、実際の実行とその解釈が合っているかを確認します。新しいリクエストの除外と既存の接続の終了は同じ出来事ではなく、この実験が外部ロードバランサーを含むサービス全体の無停止を保証するわけでもありません。

所要時間は約80分です。セッションの既定は60分なので、期限が切れる前に「+時間」で延長してください(最大180分)。セッションが終わるとVMとファイルは回収されます。必要な結果は、終了する前に別に保存してください。

ステップ

  1. 個人VMのnode_name、server_version、namespace_uid、imageを/root/ckad-inflight-termination/environment.jsonに記録し、run 1を実行してください。namespaceはckad-inflight-termination、imageは提供されたpod-template.jsonのサーバーイメージです。
  2. immediate.jsonを作成してください。Podの名前とcaseラベルはimmediate、MODEはimmediate、WORK_SECONDSは文字列の8、terminationGracePeriodSecondsは整数の15、lifecycleはなしです。run 2で、サーバーが受け付けたリクエストを、終了中に観測してください。
  3. immediate-analysis.jsonに、観測したpod_uid、client_error、exit_codeと、accepted_before_delete、readiness_alone_drains_requestsの判断を書き、run 3を実行してください。削除の前に受け付けられたかどうかと、readinessだけでリクエストを終わらせられるかどうかを区別します。
  4. graceful.jsonを作成してください。名前とcaseラベルはgraceful、MODEはgraceful、WORK_SECONDSは文字列の8、猶予は整数の15です。テンプレートのpreStopを維持して、/drainの呼び出しのあとに2秒待つようにし、run 4を実行してください。
  5. graceful-analysis.jsonに、pod_uidと、最初のterminating endpointのconditions全体をfirst_terminating_conditionsとして書いてください。hook_before_term、accepted_response_complete、endpoint_ready_false_means_connection_closedを観測と結び付けて判断し、run 5を実行してください。
  6. exhausted.jsonを作成してください。名前とcaseラベルはexhausted、MODEはgraceful、WORK_SECONDSは文字列の10、猶予は整数の5です。preStopの/drainのあとのsleepだけを3秒に変更し、run 6を実行してください。終了モードが同じでも、リクエストの結果が変わるかを確認します。
  7. repaired.jsonを作成してください。名前とcaseラベルはrepaired、MODEはgraceful、WORK_SECONDSは文字列の10、猶予は整数の15、preStopは/drainのあとに3秒です。run 7で、実際の完了レスポンスを確認してください。既存の観測ファイルは変更しません。
  8. comparison.jsonのoutcomesに、immediate・graceful・exhausted・repairedごとのpod_uid、client_completed、exit_codeを記録してください。grace_includes_prestop、api_delete_is_exact_deadline、service_zero_downtime_provenを判断し、run 8を実行してください。

参考

本物の厨房かを確認する

個人VMのnode_name、server_version、namespace_uid、imageを/root/ckad-inflight-termination/environment.jsonに記録し、run 1を実行してください。namespaceはckad-inflight-termination、imageは提供されたpod-template.jsonのサーバーイメージです。

kubectl get nodes、kubectl version -o json、kubectl get namespaceのmetadata.uidと、Podテンプレートを読みます。外部のクラスターには接続しません。

お客さんを残してすぐに帰る

immediate.jsonを作成してください。Podの名前とcaseラベルはimmediate、MODEはimmediate、WORK_SECONDSは文字列の8、terminationGracePeriodSecondsは整数の15、lifecycleはなしです。run 2で、サーバーが受け付けたリクエストを、終了中に観測してください。

pod-template.jsonから、名前・caseラベル・MODE・WORK_SECONDS・終了猶予・preStopだけを変更します。runがその宣言で、実際のリクエストと削除を観測します。

準備完了の表示では注文は終わらない

immediate-analysis.jsonに、観測したpod_uid、client_error、exit_codeと、accepted_before_delete、readiness_alone_drains_requestsの判断を書き、run 3を実行してください。削除の前に受け付けられたかどうかと、readinessだけでリクエストを終わらせられるかどうかを区別します。

observation-2.jsonのobservationから、initial.events、delete_at、client、pod_watchを結び付けてください。終了コードは、最後のコンテナのterminated状態にあります。

受けた注文まで仕上げてから帰る

graceful.jsonを作成してください。名前とcaseラベルはgraceful、MODEはgraceful、WORK_SECONDSは文字列の8、猶予は整数の15です。テンプレートのpreStopを維持して、/drainの呼び出しのあとに2秒待つようにし、run 4を実行してください。

pod-template.jsonから、名前・caseラベル・MODE・WORK_SECONDS・終了猶予・preStopだけを変更します。runがその宣言で、実際のリクエストと削除を観測します。

扉は閉まったのにレスポンスは届く

graceful-analysis.jsonに、pod_uidと、最初のterminating endpointのconditions全体をfirst_terminating_conditionsとして書いてください。hook_before_term、accepted_response_complete、endpoint_ready_false_means_connection_closedを観測と結び付けて判断し、run 5を実行してください。

observation-4.jsonのendpointsを時間順に読みます。server_eventsのhookとterm、client.completedを比較し、ready=falseを既存の接続の切断と同一視しないでください。

終了猶予を短くしすぎる

exhausted.jsonを作成してください。名前とcaseラベルはexhausted、MODEはgraceful、WORK_SECONDSは文字列の10、猶予は整数の5です。preStopの/drainのあとのsleepだけを3秒に変更し、run 6を実行してください。終了モードが同じでも、リクエストの結果が変わるかを確認します。

pod-template.jsonから、名前・caseラベル・MODE・WORK_SECONDS・終了猶予・preStopだけを変更します。runがその宣言で、実際のリクエストと削除を観測します。

猶予を補って、もう一度観測する

repaired.jsonを作成してください。名前とcaseラベルはrepaired、MODEはgraceful、WORK_SECONDSは文字列の10、猶予は整数の15、preStopは/drainのあとに3秒です。run 7で、実際の完了レスポンスを確認してください。既存の観測ファイルは変更しません。

pod-template.jsonから、名前・caseラベル・MODE・WORK_SECONDS・終了猶予・preStopだけを変更します。runがその宣言で、実際のリクエストと削除を観測します。

観測した分だけ結論を書く

comparison.jsonのoutcomesに、immediate・graceful・exhausted・repairedごとのpod_uid、client_completed、exit_codeを記録してください。grace_includes_prestop、api_delete_is_exact_deadline、service_zero_downtime_provenを判断し、run 8を実行してください。

ステップ2・4・6・7の観測を比較します。猶予バジェットにはフックも含まれますが、API削除の時刻が正確な終了時刻を保証するわけではなく、単一のリクエストがサービス全体の可用性を証明するわけでもありません。