Slide 1

Slide 1 text

Copyrights©3-shake Inc. All Rights Reserved. KEP-753: Sidecar containers の歩み 2023/10/12 3-shake SRE Tech Talk #7 (30 min)

Slide 2

Slide 2 text

Copyrights©3-shake Inc. All Rights Reserved. 2 Tsubasa Nagasawa (@toversus26) 株式会社スリーシェイク Sreake 事業部 スマホ向けゲームの Kubernetes エンジニアを経て、 2023 年 3 月から SRE 見習いをやっています。 Kubernetes やエコシステム周りを観察するのが好きです。 Terraform Provider for Google Cloud Platform などの OSS コントリビュート活動の社内でサポートしています。 whoami

Slide 3

Slide 3 text

Copyrights©3-shake Inc. All Rights Reserved. 3 Table of Contents ● Sidecar containers の機能の紹介 ○ Kubernetes 1.28 時点の機能 ○ スケジューラーが考慮するリソース要求の計算 ○ 現在の実装に対する不満 ● Sidecar containers のこれまでの歩み ○ これまで提案された案を一部紹介 ○ 今の実装が採用されるまでの流れ ● Sidecar containers のこれからの歩み ○ コンテナの停止順と停止処理 ○ コンテナ停止時のプロセスの終了と Liveness Probe の扱い ○ Kubernetes 1.29 で予定されている変更

Slide 4

Slide 4 text

Copyrights©3-shake Inc. All Rights Reserved. 4 KEP-753: Sidecar containers ● Sidecar container を Init container の一部として起動する機能 ○ Init container で restartPolicy に Always を指定 ■ Pod レベルの restartPolicy とは別に Init container レベルで指定可能に ■ restartPolicy を指定しない場合は通常の Init container の挙動 ○ スケジューラの判断材料のリソース要求の計算が複雑化 ● ユースケース ○ サービスメッシュのプロキシや証明書管理 ○ ログやメトリクス収集のエージェント ○ Sidecar container を含んだ Job の停止 ○ Init container が Sidecar container を必要とするパターン alpha: 1.28 beta: 1.29 https://kep.k8s.io/753

Slide 5

Slide 5 text

Copyrights©3-shake Inc. All Rights Reserved. 5 Sidecar containers と Probe ● Sidecar を 2 つ作成 ● Sidecar に Probe を設定 ○ Startup probe ○ Readiness probe apiVersion: v1 kind: Pod metadata: name: pod-with-sidecar spec: initContainers: - name: sidecar-1 image: cgr.dev/chainguard/wolfi-base:latest restartPolicy: Always command: ["ash", "-c", "trap 'echo Terminated; exit' TERM; echo Started; while true; do sleep 1; done"] startupProbe: exec: command: ["ash", "-c", "echo StartupProbe Started > /proc/1/fd/1; sleep 5; echo Ready > /proc/1/fd/1"] initialDelaySeconds: 5 timeoutSeconds: 8 periodSeconds: 10 - name: sidecar-2 image: cgr.dev/chainguard/wolfi-base:latest restartPolicy: Always command: ["ash", "-c", "trap 'echo Terminated; exit' TERM; echo Started; while true; do sleep 1; done"] readinessProbe: exec: command: ["ash", "-c", "echo ReadinessProbe Started > /proc/1/fd/1; sleep 5; echo Ready > /proc/1/fd/1"] initialDelaySeconds: 5 timeoutSeconds: 8 periodSeconds: 10 containers: - name: regular-1 image: cgr.dev/chainguard/wolfi-base:latest command: ["ash", "-c", "trap 'echo Terminated; exit' TERM; echo Started; while true; do sleep 1; done"] ※ Kubernetes 1.28 時点の実装

Slide 6

Slide 6 text

Copyrights©3-shake Inc. All Rights Reserved. 6 Sidecar containers と Probe ● sidecar-1 の Startup probe が成功してから次の sidecar-2 を起動 ○ Init container が Sidecar container に依存している場合は使える ● sidecar-1 の Readiness probe の成功を待たずに regular-1 を起動 ○ Liveness probe も同様に成功を待たない ● コンテナの停止順はアルファ時点ではランダム pod-with-sidecar sidecar-1 2023-07-19T10:41:41.149427271+09:00 Started pod-with-sidecar sidecar-1 2023-07-19T10:41:49.999416000+09:00 StartupProbe Started pod-with-sidecar sidecar-1 2023-07-19T10:41:55.000988954+09:00 Ready pod-with-sidecar sidecar-2 2023-07-19T10:41:56.037333917+09:00 Started pod-with-sidecar regular-1 2023-07-19T10:41:57.682351314+09:00 Started pod-with-sidecar sidecar-2 2023-07-19T10:42:09.999915870+09:00 ReadinessProbe Started pod-with-sidecar sidecar-2 2023-07-19T10:42:15.000654193+09:00 Ready … pod-with-sidecar regular-1 2023-07-19T10:42:20.167238932+09:00 Terminated pod-with-sidecar sidecar-1 2023-07-19T10:42:20.167235599+09:00 Terminated pod-with-sidecar sidecar-2 2023-07-19T10:42:20.168897834+09:00 Terminated

Slide 7

Slide 7 text

Copyrights©3-shake Inc. All Rights Reserved. 7 Sidecar containers と Job ● Job に Sidecar container を挟む ○ Job の Regular container が終了しても Sidecar container が停止しない問題は? apiVersion: batch/v1 kind: Job metadata: name: pod-with-sidecar spec: template: spec: initContainers: - name: init-1 image: cgr.dev/chainguard/wolfi-base:latest command: ["ash", "-c", "echo Started; echo Sleep 5s; sleep 5; echo Terminated"] - name: sidecar-1 image: cgr.dev/chainguard/wolfi-base:latest restartPolicy: Always command: ["ash", "-c", "trap 'echo Terminated; exit' TERM; echo Started; while true; do sleep 1; done"] containers: - name: regular-1 image: cgr.dev/chainguard/wolfi-base:latest command: ["ash", "-c", "echo Started; echo Sleep 5s; sleep 5; echo Terminated"] restartPolicy: Never backoffLimit: 4 ※ Kubernetes 1.28 時点の実装

Slide 8

Slide 8 text

Copyrights©3-shake Inc. All Rights Reserved. 8 Sidecar containers と Job ● regular-1 が停止すると sidecar-1 に SIGTERM が飛ぶ ○ 現在 Job を止めるためにやっているハックが不要になる! ■ 終了時ファイル検出 ■ PID namespace 共有 + シグナル通知 pod-with-sidecar-nn4zh init-1 2023-07-19T10:47:03.613131134+09:00 Started pod-with-sidecar-nn4zh init-1 2023-07-19T10:47:03.613188550+09:00 Sleep 5s pod-with-sidecar-nn4zh init-1 2023-07-19T10:47:08.614265132+09:00 Terminated pod-with-sidecar-nn4zh sidecar-1 2023-07-19T10:47:09.753494135+09:00 Started pod-with-sidecar-nn4zh regular-1 2023-07-19T10:47:11.878372366+09:00 Started pod-with-sidecar-nn4zh regular-1 2023-07-19T10:47:11.878387241+09:00 Sleep 5s pod-with-sidecar-nn4zh regular-1 2023-07-19T10:47:16.882976981+09:00 Terminated pod-with-sidecar-nn4zh sidecar-1 2023-07-19T10:47:17.809750902+09:00 Terminated

Slide 9

Slide 9 text

Copyrights©3-shake Inc. All Rights Reserved. 9 スケジューラが考慮するリソース要求の計算 Max ( Max(Init containers), Sum(Regular containers) )

Slide 10

Slide 10 text

Copyrights©3-shake Inc. All Rights Reserved. 10 スケジューラが考慮するリソース要求の計算 Max ( Max(Init container(i) + Sum(Sidecar containers(i-1)), Sum(Sidecar containers) + Sum(Regular containers) )

Slide 11

Slide 11 text

Copyrights©3-shake Inc. All Rights Reserved. 11 Sidecar containers の実装に対する不満 ● initContainers に restartPolicy: Always を指定するのは直感的じゃない ○ 特に初学者は背景を知らないので混乱する ● sidecarContainers のフィールドを追加するのが良かったのでは? ○ Init containers != Sidecar containers ● initContainers や containers のフィールドで印を付ける方が良かったのでは? ○ sidecar: true 的な ● depends_on で依存関係グラフを構築できた方が良かったのでは? ○ Docker Compose / ECS と同じように => 背景を知ることで、意外と良い実装かも?と思って貰うのが目的

Slide 12

Slide 12 text

Copyrights©3-shake Inc. All Rights Reserved. 12 KEP-753: Sidecar containers の道のり ● [2018/5-2020/3] 最初の試み (@Joseph-Irving) ● [2020/6-2020/10] 最初の試みの延長 (@rata) ○ Graceful Node Shutdown の前提条件として ● [2020/11] Pod Lifecycle Phases (@thockin) ● [2021/7] systemd から影響を受けた依存関係グラフ (@rata) ● [2021/8] Keystone container (@matthyx) ● [2022/9] systemd の BindsTo (@thockin) ● [2022/9] Terminate pod on container completion (@SergeyKanzhelev) ● [2022/10-] 現在の実装 (@SergeyKanzhelev, @matthyx, @tzneal, @gjkim42) ○ wg-sidecar の発足 ○ Kubernetes 1.28 にアルファ機能として入る ※ 黄色マークが今日話す内容

Slide 13

Slide 13 text

Copyrights©3-shake Inc. All Rights Reserved. 13 最初の試み ● 2018 年 5 月に Kubernetes 1.11 の開発期間中に KEP の草案が上がる ○ https://github.com/kubernetes/community/pull/2148 ● 当時の Sidecar containers で解決したかった問題 ○ Job の Sidecar container の停止 (https://issue.k8s.io/25908) ○ Pod 内のコンテナの起動順の制御 (https://issue.k8s.io/65502) ● 提案されていた主な実現方法 ○ sidecarContainers フィールドの追加 (不採用) ○ primaryContainer にコンテナ名を指定 (不採用) ○ containers に sidecar フィールドを追加 (不採用) ○ containers に dependsOn フィールドを追加 (不採用) ○ containers に lifecycle.type フィールドを追加 (採用)

Slide 14

Slide 14 text

Copyrights©3-shake Inc. All Rights Reserved. 14 sidecarContainers フィールドの追加 ● ツールの改修が必要 ○ e.g.) Kubernetes Dashboard, kubectl exec / logs ● 既存の containers フィールドと違いは? ○ ライフサイクルに大きな違いがない ○ 新しいフィールドの追加は API 規則的にどうなのか ● Init container が難産だったので追加への不安 ○ Ephemeral containers の追加も控えていた ● コンテナの起動順に柔軟性がない ○ Init -> Sidecar -> Regular ○ Sidecar に依存した Init は実現不可能 ■ 別のフィールドの追加が必要 apiVersion: batch/v1 kind: Job metadata: name: pod-with-sidecar spec: template: spec: initContainers: - name: init-1 image: cgr.dev/chainguard/wolfi-base:latest sidecarContainers: - name: sidecar-1 image: cgr.dev/chainguard/wolfi-base:latest containers: - name: regular-1 image: cgr.dev/chainguard/wolfi-base:latest restartPolicy: Never backoffLimit: 4 ※ 動作しないので注意 不採用

Slide 15

Slide 15 text

Copyrights©3-shake Inc. All Rights Reserved. 15 primaryContainer にコンテナ名を指定 ● Job の Sidecar container が停止しない問題に焦点 ● primaryContainer が最後に起動する ○ Sidecar container 間の依存関係はどう表す? ● primaryContainer が停止すると... ○ 他のコンテナに SIGTERM を飛ばす ● 複数 Regular container があるパターンは? ● Job 以外の Sidecar containers の問題を解決できない ○ 起動停止順の制御が難しい ○ 拡張が難しい ■ primary 以外の役割が必要になったら? apiVersion: batch/v1 kind: Job metadata: name: pod-with-sidecar spec: template: spec: initContainers: - name: init-1 image: cgr.dev/chainguard/wolfi-base:latest containers: - name: sidecar-1 image: cgr.dev/chainguard/wolfi-base:latest - name: regular-1 image: cgr.dev/chainguard/wolfi-base:latest restartPolicy: Never backoffLimit: 4 primaryContainer: regular-1 ※ 動作しないので注意 不採用

Slide 16

Slide 16 text

Copyrights©3-shake Inc. All Rights Reserved. 16 containers に sidecar: true を指定 ● KEP 草案の PR が作られた時に提案されていた API ● initContainers には sidecar: true を指定できない ○ initContainers に手を加えるのが怖い時代 ■ ただ当時も要望があるにはあった ● sidecar で良いのかの議論 ○ sidecar の定義が不明確 ○ 動作を表すフィールド名に変えた方が良い? ■ e.g.) terminationFatalPod: true ■ e.g.) terminateWithOthers: true ○ 真偽値の拡張性への懸念 apiVersion: batch/v1 kind: Job metadata: name: pod-with-sidecar spec: template: spec: initContainers: - name: init-1 image: cgr.dev/chainguard/wolfi-base:latest containers: - name: sidecar-1 image: cgr.dev/chainguard/wolfi-base:latest sidecar: true - name: regular-1 image: cgr.dev/chainguard/wolfi-base:latest restartPolicy: Never backoffLimit: 4 ※ 動作しないので注意 不採用

Slide 17

Slide 17 text

Copyrights©3-shake Inc. All Rights Reserved. 17 dependsOn フィールドを指定 ● Docker Compose / ECS のような依存関係グラフ ○ sidecar-1 が起動するまで regular-1 は起動しない ○ regular-1 が停止した後に sidecar-1 が停止する ● 再帰的なコンテナの依存関係が分かりづらい ● Pod に複雑なコンテナの起動停止順が必要か? ○ 必要なユースケースが見つからなかった ● Admission Webhook で injection しづらい ○ e.g.) istio-proxy を差し込むのが面倒 apiVersion: batch/v1 kind: Job metadata: name: pod-with-sidecar spec: template: spec: initContainers: - name: init-1 image: cgr.dev/chainguard/wolfi-base:latest containers: - name: sidecar-1 image: cgr.dev/chainguard/wolfi-base:latest - name: regular-1 image: cgr.dev/chainguard/wolfi-base:latest dependsOn: - sidecar-1 restartPolicy: Never backoffLimit: 4 ※ 動作しないので注意 不採用

Slide 18

Slide 18 text

Copyrights©3-shake Inc. All Rights Reserved. 18 containers に lifecycle.type: Sidecar を指定 ● 2019 年 6 月に最初の試みの KEP がついに完成 ○ Ephemeral containers の実装との衝突の話も ● コンテナのライフサイクルの動作を変える意図 ○ デフォルトで lifecycle.type: Standard ○ 後から別のライフサイクルの種類を追加可能 ● initContainers に lifecycle.type は指定できない ○ 起動順は init-1 -> sidecar-1 -> regular-1 ■ Sidecar container が Ready になるまで待つ ○ 停止順は regular-1 -> sidecar-1 -> init-1 apiVersion: batch/v1 kind: Job metadata: name: pod-with-sidecar spec: template: spec: initContainers: - name: init-1 image: cgr.dev/chainguard/wolfi-base:latest containers: - name: sidecar-1 image: cgr.dev/chainguard/wolfi-base:latest lifecycle: type: Sidecar - name: regular-1 image: cgr.dev/chainguard/wolfi-base:latest restartPolicy: Never backoffLimit: 4 ※ 動作しないので注意 採用 * * この時点で採用されたが、機能としては入らなかった

Slide 19

Slide 19 text

Copyrights©3-shake Inc. All Rights Reserved. 19 containers に lifecycle.type: Sidecar を指定 ● Regular / Sidecar container で停止処理のフェーズを分ける ● PreStop hook は各フェーズで全てのコンテナに対して同時に実行 ● Regular container が terminationGracePeriodSeconds (TGPS) を食い潰したら... ○ Sidecar container に SIGTERM を飛ばして 2 秒待って SIGKILL を繰り返す

Slide 20

Slide 20 text

Copyrights©3-shake Inc. All Rights Reserved. 20 最初の試みの終焉 ● Kubernetes 1.18 で入る予定だったが結局入らなかった ○ @thockin による謝罪文 (https://kep.k8s.io/753#issuecomment-597372056) ■ キャパオーバーな sig-node の体制に反して sig-node 内で推進派が強行 ■ 闇深い kubelet に Pod のライフサイクルの変更を入れる懸念 ■ Sidecar container の要件と API 定義の甘さ ● コンテナの停止処理、 Init container が対象外、... ○ フライングで公開されたブログ記事もあり混乱も ■ Sidecar container lifecycle changes in Kubernetes 1.18 ● Kubernetes 1.19 でも入らず、そのままお蔵入りに ○ Graceful Node Shutdown の実装を優先 ■ ノードの停止処理の改善中に Pod のライフサイクルの複雑化を避けたかった

Slide 21

Slide 21 text

Copyrights©3-shake Inc. All Rights Reserved. 21 Pod Lifecycle Phases ● コンテナにフェーズの概念を導入 ○ AppInit: emptyDir にデータを生成 ○ Network: iptables ルールの追加、istio-proxy の起動 ○ ClusterEnv: 秘密情報を fetch・復号化 ○ AppRun: これまでの Regular containers と同じ ● コンテナレベルで restartPolicy を追加 ○ Always: Sidecar container を意味する ○ OnFailure: これまでの Init container と同じ ○ Never: フェーズ中に失敗すると Pod を再起動 ● API や Pod ライフサイクルに大きな変更が必要 ● 既存の Init containers の扱いをどうする? ● フェーズを追加する場合のバージョンスキューの複雑さ apiVersion: batch/v1 kind: Job metadata: name: pod-with-sidecar spec: template: spec: containers: - name: init-1 image: cgr.dev/chainguard/wolfi-base:latest phase: AppInit restartPolicy: OnFailure - name: sidecar-1 image: cgr.dev/chainguard/wolfi-base:latest phase: Network restartPolicy: Always - name: regular-1 image: cgr.dev/chainguard/wolfi-base:latest phase: AppRun restartPolicy: Never backoffLimit: 4 ※ 動作しないので注意 不採用

Slide 22

Slide 22 text

Copyrights©3-shake Inc. All Rights Reserved. 22 KEP-2872: Keystone containers ● Job の Sidecar container の停止に絞った KEP ○ restartPolicy が Never or OnFailure の場合のみ ○ 起動停止順の変更を含まない ■ これまでの失敗を鑑みて意図的に範囲を狭めた ● Pod のライフサイクルを小さく変えていく ● 解決できる問題が限定的で停滞 ... ○ sig-node に Sidecar containers 推進派が少ない ■ Istio Ambient Mesh の登場で優先度が下がった ○ 起動停止順の解決方法との連携をどうする? ■ レガシーなコードとしてお荷物にならないか? apiVersion: batch/v1 kind: Job metadata: name: pod-with-sidecar spec: template: spec: initContainers: - name: init-1 image: cgr.dev/chainguard/wolfi-base:latest containers: - name: sidecar-1 image: cgr.dev/chainguard/wolfi-base:latest - name: regular-1 image: cgr.dev/chainguard/wolfi-base:latest lifecycle: type: Keystone restartPolicy: Never backoffLimit: 4 ※ 動作しないので注意 不採用 https://kep.k8s.io/2872

Slide 23

Slide 23 text

Copyrights©3-shake Inc. All Rights Reserved. 23 KEP-3582: Per Container Restart Policy override ● containers フィールドに restartPolicyOverride 追加 ○ Always, OnFailure, Never, TeminatePod から選ぶ ○ Init / Ephemeral container は対象外 ● TerminatePod の場合は再起動の挙動は変わらない ○ Pod レベルの restartPolicy を継承 ○ マークしたコンテナが停止したら他のコンテナを停止 ● Regular が 2 つある場合に期待した挙動にならない ○ 2 つ TerminatePod でマークして片方が停止すると? ● Admission Webhook で Inject しづらい ○ どのコンテナを TeminatePod にマークすべき? ● コンテナレベルで restartPolicy を上書きする機能 ○ 需要があるかもなので保留 (Kubernetes の初期にも議論はあった ) 保留 apiVersion: batch/v1 kind: Job metadata: name: pod-with-sidecar spec: template: spec: initContainers: - name: init-1 image: cgr.dev/chainguard/wolfi-base:latest containers: - name: sidecar-1 image: cgr.dev/chainguard/wolfi-base:latest restartPolicyOverride: Always - name: regular-1 image: cgr.dev/chainguard/wolfi-base:latest restartPolicyOverride: TerminatePod restartPolicy: Never backoffLimit: 4 ※ 動作しないので注意 https://kep.k8s.io/3582

Slide 24

Slide 24 text

Copyrights©3-shake Inc. All Rights Reserved. 24 initContainers に restartPolicy: Always 指定 (採用) ● Pod レベルの restartPolicy と各コンテナフィールドの比較 ○ initContainers -> sidecarContainers + restartPolicy: OnFailure ○ sidecarContainers -> initContainers + restartPolicy: Always ● initContainers に restartPolicy を設定できるようにする initContainers containers sidecarContainers ● Pod レベルの restartPolicy に関わらず、OnFailure で変 更できない ● containers の前に起動して 停止 ● Pod レベルの restartPolicy から継承 ● Always / OnFailure / Never ● OnFailure / Never の場合は Pod の完了とともに停止 ● 利用用途に合わせて指定 ● Always / OnFailure ● containers の前に起動して containers の後に停止 採用

Slide 25

Slide 25 text

Copyrights©3-shake Inc. All Rights Reserved. 25 initContainers に restartPolicy: Always 指定 (採用) ● API の変更が最小限に抑えられる ● initContainers は起動順を保証 ○ リストの先頭から直列で実行 ○ Sidecar container 用に停止処理を決める必要がある ● initContainers の Probe / Hook ○ これまでは指定できなかった ○ Sidecar container 用にサポートする ○ startupProbe の成功を待ってから次のコンテナ起動 ● コンテナの停止処理 ○ Regular container よりも複雑化 apiVersion: batch/v1 kind: Job metadata: name: pod-with-sidecar spec: template: spec: initContainers: - name: init-1 image: cgr.dev/chainguard/wolfi-base:latest - name: sidecar-1 image: cgr.dev/chainguard/wolfi-base:latest restartPolicy: Always containers: - name: regular-1 image: cgr.dev/chainguard/wolfi-base:latest restartPolicy: Never backoffLimit: 4

Slide 26

Slide 26 text

Copyrights©3-shake Inc. All Rights Reserved. 26 Regular container の停止処理 ● 既存の Pod の削除の流れ ○ kube-apiserver が Pod に DeletionTimestamp を設定 ○ kubelet が Pod 内のコンテナの停止処理を開始 ○ 全てのコンテナで PreStop hook を同時に実行 (厳密にはほぼ同時、順番はランダム ) ○ PreStop hook が完了したコンテナから SIGTERM が飛ぶ ○ terminationGracePeriodSeconds (TGPS) を超えると SIGKILL が飛ぶ ○ preStop hook が TGPS を超えると SIGTERM を飛ばして 2 秒待機してから SIGKILL

Slide 27

Slide 27 text

Copyrights©3-shake Inc. All Rights Reserved. 27 Regular container の停止処理 ● PreStop hook の実行時間が TGPS を超えた場合のバグ修正 (@1.28.0) ○ 1.22 で発生したリグレッション ■ 1.28 以外には cherry-pick されていない ○ TGPS を消化している場合の TGPS の上書き処理にバグが ○ TGPS=30 で、PreStop hook で 30 秒 sleep する ■ 本来なら 30 秒後に SIGTERM、32 秒後に SIGKILL ■ 30 秒後に SIGTERM、60 秒後に SIGKILL になっていた ■ SIGTERM が処理できないと TGPS の倍の時間掛かる https://pr.k8s.io/115835 apiVersion: v1 kind: Pod metadata: name: lifecycle-demo spec: containers: - name: lifecycle-demo-container image: nginx lifecycle: preStop: exec: command: ["sleep", "30"] terminationGracePeriodSeconds: 30 I0930 15:32:13.014443 211 kuberuntime_container.go:738] "Killing container with a grace period override" pod="default/lifecycle-demo" podUID=**** containerName="lifecycle-demo-container" containerID="containerd://=****" gracePeriod=30

Slide 28

Slide 28 text

Copyrights©3-shake Inc. All Rights Reserved. 28 Sidecar container の停止処理 ● コンテナの停止順は直感的に起動と逆の順番で良さそう ○ e.g.) 起動順が sidecar-1 -> sidecar-2 -> {regular-1, regular-2} ■ 停止順は {regular-1, regular-2} -> sidecar-2 -> sidecar-1 ● SIGTERM を飛ばすタイミング問題 ○ 全てのコンテナで同時? Regular container が停止してから Sidecar container に飛ばす? ○ TGPS が限られた時間 (e.g. Spot インスタンス) や長時間 (e.g. 1 時間) の場合の影響 ● TGPS は Pod レベルかコンテナ毎か問題 ○ 現状は Pod レベルでしか TPGS を指定できない ○ PodSpec の API 変更を避けたい (コンテナレベルの TGPS の導入など) ● Pod の停止処理中に Sidecar container が停止した場合に再起動するか問題 ○ PreStop hook でプロセスを停止した場合とエラー終了した場合をどう区別する?

Slide 29

Slide 29 text

Copyrights©3-shake Inc. All Rights Reserved. 29 Pod レベルの TGPS の分割 ● Regular / Sidecar container で停止処理のフェーズを分ける ● PreStop hook は各フェーズで全てのコンテナに対して同時に実行 ● Regular container が TGPS を食い潰したら... ○ Sidecar container に SIGTERM を飛ばして 2 秒待って SIGKILL を繰り返す ● Regular / Sidecar container のどちらも Pod レベルの TGPS が保証されない 不採用

Slide 30

Slide 30 text

Copyrights©3-shake Inc. All Rights Reserved. 30 Pod レベルの TGPS を各コンテナに反映 ● Sidecar container の数だけ Pod レベルの TGPS を超える形に ○ TGPS を固定時間 (e.g. 5 秒) にして、後で PodSpec の API で設定可能にする案も ● Regular / Sidecar container に TGPS を食い潰される心配はなくなる ● PreStop hook の実行が遅れるので Spot など時間が限られている場合に問題になる? 不採用

Slide 31

Slide 31 text

Copyrights©3-shake Inc. All Rights Reserved. 31 Pod レベルの TGPS の保証 ● PreStop hook を全てのコンテナで同時に実行 ○ TGPS の食い潰しにより PreStop hook を実行できないコンテナはなくなる ● 全ての Regular container が停止してから Sidecar container に SIGTERM が飛ぶ ○ Sidecar container に起動順と逆で SIGTERM を飛ばして順番に落とす ● TGPS を食い潰すと 2 秒の猶予期間後に SIGKILL される ○ 残りの全てのコンテナに対して SIGKILL を一斉に飛ばす 採用

Slide 32

Slide 32 text

Copyrights©3-shake Inc. All Rights Reserved. 32 Sidecar containers の停止処理のまとめ ● Pod レベルの TGPS を各コンテナで共有 ● PreStop hook は全てのコンテナでほぼ同時に実行開始 ○ 限られた時間しかない場合に Early PreStop hook で可能な限り安全に停止した ■ e.g.) ログ収集のエージェントが早めにバッファの flush を行う ● Regular container が全て停止してから Sidecar container に SIGTERM を飛ばす ○ WIP: Sidecar containers の SIGTERM を遅らせる方法 (https://pr.k8s.io/120620) ■ killContainer の中の PreStop hook とコンテナの停止は切り離せない ■ コンテナ毎に Regular containers と直前の Sidecar container の channel を用意 ● コンテナが停止したら channel を close する ■ killContainer の中で必要なコンテナが停止するまで停止処理をブロック ● channel が全て close されたらコンテナの停止処理を進める

Slide 33

Slide 33 text

Copyrights©3-shake Inc. All Rights Reserved. 33 停止処理中の Regular containers の再起動 ● Pod が完全に停止するまでに Regular containers が停止したら? ○ 停止処理中 (PreStop + Termination) に終了したコンテナは再起動しない ■ エラー終了も正常終了も挙動は同じ ■ Pod レベルの restartPolicy: Always の場合でも挙動は同じ ○ Regular container でサイドカーパターンの場合 ■ 停止までに長時間掛かるサイドカーコンテナで問題が起きても再起動せず困る ● e.g.) Agones GameServer がマルチプレイのマッチの完了を待つ

Slide 34

Slide 34 text

Copyrights©3-shake Inc. All Rights Reserved. 34 停止処理中の Sidecar container の再起動 ● Sidecar container は自身に SIGTERM が飛ぶまでは exit code に関わらず再起動 ○ PreStop hook 実行後でも SIGTERM が飛ぶまでは再起動 ■ Sidecar container の restartPolicy: Always の挙動と合致 ■ PreStop hook で自死した場合も再起動されるので注意 (ドキュメント化予定) ■ 再起動した Siecar container は起動後にすぐに PreStop hook を実行 ○ 停止処理に時間の掛かる Regular container の問題を解消 (e.g. Agones, ログ収集)

Slide 35

Slide 35 text

Copyrights©3-shake Inc. All Rights Reserved. 35 停止処理中の Regular container の Liveness Probe ● 停止処理に入ると Liveness Probe を実行しない (https://pr.k8s.io/98571) ○ ヘルスチェックに応答するプロセスが停止した後に時間が掛かるケースで問題に ■ Liveness Probe に失敗してコンテナが意図せず再起動する ○ Readiness Probe は停止処理中も実行される ○ Regular containers だけの場合は停止処理に複雑な決まり事がないので問題ない

Slide 36

Slide 36 text

Copyrights©3-shake Inc. All Rights Reserved. 36 停止処理中の Sidecar container の Liveness Probe ● 自分自身が停止処理に入るまで Liveness Probe を実行すべき? ○ 長時間起動しっぱなしの Sidecar container でデッドロックの可能性がある ○ Liveness Probe に失敗してコンテナを再起動する時に PreStop hook を呼び出す (?) ○ Pod 削除の直前で LivenessProbe に失敗してコンテナ再起動が走ったら? ■ sidecar-2 のように PreStop 中に LivenessProbe 失敗して再起動したら? ※ 設計が確定する前なので想像です

Slide 37

Slide 37 text

Copyrights©3-shake Inc. All Rights Reserved. 37 停止処理中の Sidecar container の Liveness Probe ● コンテナに順序を与えたせいで PreStop hook を再考すべきでは? ○ Pod を削除した時とコンテナの再起動時に同じ PreStop hook を呼び出すの変じゃない? ■ Liveness Probe の失敗 != Pod がもうすぐ停止 ○ 新しく Lifecycle hook の種類を増やすべきでは? (e.g. PodDelete) ■ PodDelete は Pod の削除時だけ、PreStop はコンテナの再起動時だけ呼び出す ● Sidecar container の GA 昇格までに解決が必要 ○ 現段階で回答は出ていない ■ Kubernetes 1.29 のベータ昇格時点では Liveness Probe は止まりそう

Slide 38

Slide 38 text

Copyrights©3-shake Inc. All Rights Reserved. 38 1.29 に向けた主な実装予定 ● Sidecar container は 1.29 でベータ昇格予定 ○ ベータに昇格するとデフォルトで有効になる ● PodStatus に RequestedResources を追加 (https://pr.k8s.io/115643) ○ Init / Sidecar / Regular container と Pod Overhead を含むリソース要求の合計 ■ Pod がスケジュールできていない原因をユーザーが確認しやすいように ■ Cluster Autoscaler や Karpenter がノードを追加する際の計算で使えるように ● Init container の restartPolicy のデフォルト値 (OnFailure?) の設定 ○ Init containers が再実行されない問題の解決にも繋がるかも? ● HPA のリソース計算に Sidecar container も含める (https://pr.k8s.io/120001) ● Topology Manager, OOM Score Adjustments, …

Slide 39

Slide 39 text

Copyrights©3-shake Inc. All Rights Reserved. 39 KubeCon + CloudNative North America 2023 ● Implementing a big feature on an example of a Sidecar container KEP ○ https://sched.co/1Sp9i (@SergeyKanzhelev) ○ Kubernetes Contributor Summit のセッションの一つ ○ 波風を余り立てずに Kubernetes に大きな変更をどう取り入れたか ● Sidecar Containers Are Built-in to Kubernetes: What, How, and Why Now? ○ https://sched.co/1R2tw (@SergeyKanzhelev, @tzneal) ○ Sidecar containers の実装が 1.28 まで入らなかった歴史の話にも触れるかも? ○ Sidecar containers の機能の TODO の話も

Slide 40

Slide 40 text

Copyrights©3-shake Inc. All Rights Reserved. 40 Kubernetes の最新情報をまとめてます https://zenn.dev/toversus/scraps/75c1ce543751b8