Kubernetes 1.29: SIG-Node (kubelet) 変更内容

本記事は、[Kubernetes 変更内容共有会(v1.29)](https://kubernetes-updates.connpass.com/event/306050/) の SIG-Node(kubelet)に関する資料として準備されました。
Kubernetes 1.29の [CHANGELOG](https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.29.md) から、SIG-Nodeに関するところを抜粋して紹介します。

:pencil: は筆者(@y1r96)による補足です。

## 所感
:pencil:

今回の Kubernetes 1.29 の SIG-Node (kubelet) に関しては、以下の2つの変更が大きなものでした：
- SidecarContainer の beta への昇格
- DevicePluginCDIDevice の beta への昇格

SidecarContainer は、InitContainer のタイミングで起動し、Container が終了するまで走り続けるコンテナです。ユースケースとして、ログのフォワーダ、メトリクスサイドカー、サービスメッシュなどが挙げられています。
これまでは、Container の 1つに、サイドカーとして実行したいコンテナを指定していましたが、この設定方法では Container との起動順序をコントロールすることが難しかったです。また、Job など一定時間で終了するワークロードについて、サイドカーをシャットダウンしないと Pod が終了できない、という問題もありました。
これらの問題が、InitContainer の起動順序制御をうまく使うことで解消されました。

また、DevicePluginCDIDevice が beta に昇格しています。これは、Device Plugin から kubelet へデバイスの割当結果を返す ContainerAllocateReponse で、CDIDevice の名前のフィールドを追加するものです。
kubelet はこのフィールドをそのまま（高レベル）コンテナランタイムに渡すことで、コンテナランタイムがCDIDeviceを呼び出すことができます。
既に NVIDIA GPU などが、このCDIDeviceを実装しているそうです（[参考](https://docs.nvidia.com/datacenter/cloud-native/gpu-operator/latest/cdi.html)）。

## Changes by Kind

### API Change

- `PreStop` ライフサイクルフックに、sleep アクションが追加されました。sleep アクションを利用すると、コンテナの終了する前に pause することができます。 ([#119026](https://github.com/kubernetes/kubernetes/pull/119026), [@AxeZhan](https://github.com/AxeZhan)) [sig/node,sig/api-machinery,sig/apps,sig/testing]
- InPlace Vertical Scaling で、Windows をサポートするようになりました。([#112599](https://github.com/kubernetes/kubernetes/pull/112599), [@fabi200123](https://github.com/fabi200123)) [SIG Autoscaling, Node, Scalability, Scheduling and Windows] [sig/scalability,sig/scheduling,sig/node,sig/autoscaling,sig/windows]
- Kubelet の設定に、`ImageMaximumGCAge` フィールドが追加されました。このフィールドを利用すると、イメージがガベージコレクトされる最大の経過時間を設定することができます。 ([#121275](https://github.com/kubernetes/kubernetes/pull/121275), [@haircommander](https://github.com/haircommander)) [sig/node,sig/api-machinery]
- `UserNamespacesPodSecurityStandards` フィーチャーゲートが追加されました。このフィーチャーゲートを利用すると、Pod Security Standards で user namespace をサポートすることができます。この機能を有効にすると、全ての Pod Security Standard rules を変更して `spec[.*].securityContext.[runAsNonRoot,runAsUser]` を許可することができます。このフィーチャーゲートは、クラスタで全てのノードが user namespace をサポートしていて有効にしているときにのみ、有効にするべきです。このフィーチャーゲートは将来の Kubernetes リリース で graduate することはありませんし、デフォルトで有効になることもありません。([#118760](https://github.com/kubernetes/kubernetes/pull/118760), [@saschagrunert](https://github.com/saschagrunert)) [SIG API Machinery, Auth, Node and Release] [sig/node,sig/api-machinery,sig/auth,sig/release]
- `DisableNodeKubeProxyVersion` フィーチャーゲートが追加されました。このフィーチャーゲートを利用すると、`kubeProxyVersion` フィールドが設定されなくなります。 ([#120954](https://github.com/kubernetes/kubernetes/pull/120954), [@HirazawaUi](https://github.com/HirazawaUi)) [sig/node,sig/api-machinery,sig/apps]
- Go API: ボリュームにおける `ResourceRequirements` 構造体が、`VolumeResourceRequirements` でリプレースされました。([#118653](https://github.com/kubernetes/kubernetes/pull/118653), [@pohly](https://github.com/pohly)) [sig/scheduling,sig/storage,sig/node,sig/api-machinery,sig/auth,sig/apps,sig/testing]
  - :pencil: これまでは、Container 構造体内のリソース定義と、PVCSpec 構造体内のリソース定義で、同じ `ResourceRequirements` 構造体を利用していたので、API を拡張することが難しかったようです。
- `PodReadyToStartContainers` コンディションが beta に昇格しました。 ([#119659](https://github.com/kubernetes/kubernetes/pull/119659), [@kannon92](https://github.com/kannon92)) [sig/node,sig/testing]
  - :pencil: これまで、Pod のサンドボックスの作成と初期化が完了したかどうかを、クラスタ管理者が簡単に確認するかどうかは難しかったです。v1.28 までは Initialized コンディションが initContainer の実行も含んでいたので、それを確認することが難しかったようです。

### Feature

- CRI API における `ImageFsInfoResponse` に container filesystem が追加されました。 ([#120914](https://github.com/kubernetes/kubernetes/pull/120914), [@kannon92](https://github.com/kannon92)) [sig/node,sig/testing]
  - :pencil: CRI (Container Runtime Interface) は、kubelet と（高レベル）コンテナランタイムの間の通信を行うインターフェイスです。コンテナランタイムへの `ImageFsInfoRequest` の対になるレスポンスに、`container_filesystem` フィールドが追加されました。
- Kubelet が split image filesystem をサポートするようになりました。 ([#120616](https://github.com/kubernetes/kubernetes/pull/120616), [@kannon92](https://github.com/kannon92)) [sig/node,sig/testing]
  - :pencil: split image filesystem は、コンテナイメージの書き込み可能なレイヤ（コンテナ）と、読み取り専用のレイヤ（イメージ）を、異なるディスクに保存できるようにする仕組みです。これまでは、コンテナとイメージが同じディスクに保存されている必要がありました。コンテナとイメージを分けることによって、kubelet の性能が向上することが期待されます。 KEP-4191は[こちら](https://github.com/kubernetes/enhancements/blob/master/keps/sig-node/4191-split-image-filesystem/README.md)。
- CRI: runtime class ごとの image pull がサポートされました。 ([#121121](https://github.com/kubernetes/kubernetes/pull/121121), [@kiashok](https://github.com/kiashok)) [sig/node,sig/windows]
  - :pencil: この機能は、runtime class (コンテナランタイムの設定を指定する機能) ごとに正しくコンテナイメージを選択するために実装された機能です。提案されたのは Microsoft の方で、Windows container の場合は Hyper-V 仮想化を行うような runtime class を利用することができ、そのときに使用する UVM (Utility VM) のカーネルバージョンにあわせたコンテナイメージを選択できるようにするために、提案されているようです。 KEP-4216は[こちら](https://github.com/kubernetes/enhancements/blob/master/keps/sig-node/4216-image-pull-per-runtime-class/README.md)
- `NodeLifeCycleController` から `TaintManager` を抽出しました。（KEP-3902）([#119208](https://github.com/kubernetes/kubernetes/pull/119208), [@atosatto](https://github.com/atosatto)) [sig/scheduling,sig/node,sig/api-machinery,sig/apps,sig/instrumentation,sig/testing]
- drop-in config が設定されていないときに、デフォルトの `KubeletConfig` がオーバライドされるのを修正しました。([#121193](https://github.com/kubernetes/kubernetes/pull/121193), [@sohankunkerkar](https://github.com/sohankunkerkar)) [sig/node,sig/testing]
- `ReadWriteOncePod` フィーチャーゲートが GA しました。 ([#121077](https://github.com/kubernetes/kubernetes/pull/121077), [@chrishenzie](https://github.com/chrishenzie)) [sig/scheduling,sig/storage,sig/node,sig/apps,sig/testing]
- kubelet の以下のリソースメトリクスが GA しました（`container_cpu_usage_seconds_total`, `container_memory_working_set_bytes`, `container_start_time_seconds`, `node_cpu_usage_seconds_total`, `node_memory_working_set_bytes`, `pod_cpu_usage_seconds_total`, `pod_memory_working_set_bytes`, `resource_scrape_error`）。また、`resource_scrape_error` にリネームされた `scrape_error` が deperecate されました。([#116897](https://github.com/kubernetes/kubernetes/pull/116897), [@Richabanker](https://github.com/Richabanker)) [SIG Architecture, Instrumentation, Node and Testing] [sig/node,sig/instrumentation,sig/testing,sig/architecture]
- サイドカー コンテナ の終了がシリアライズされ、メインコンテナの終了後に、あとから起動されたサイドカーコンテナから順に終了されるようになります。 ([#120620](https://github.com/kubernetes/kubernetes/pull/120620), [@tzneal](https://github.com/tzneal)) [sig/node,sig/testing]
- `SidecarContainers` 機能が beta に昇格して、デフォルトで有効になりました。([#121579](https://github.com/kubernetes/kubernetes/pull/121579), [@gjkim42](https://github.com/gjkim42)) [sig/node]
  - :pencil: SidecarContainer が実装されました。このコンテナは、InitContainer のタイミングで起動し、終了せずに Containers と同じ間だけ生存し続けます。この終了は Pod の終了をブロックせず、最後まで生存し続けます。ログフォワーダやメトリクスのサイドカー、サービスメッシュなどが想定されたユースケースです。KEP-753は[こちら](https://github.com/kubernetes/enhancements/blob/master/keps/sig-node/753-sidecar-containers/README.md)。
- `configMapAndSecretChangeDetectionStrategy` が `Cache` に設定されているとき、 `--sync-frequency` が `ConfigMaps` や `Secrets` の更新タイミングを設定していなかった問題を修正します。更新頻度は `node.alpha.kubernetes.io/ttl` node アノテーションのみの影響を受けます。 ([#120255](https://github.com/kubernetes/kubernetes/pull/120255), [@likakuli](https://github.com/likakuli)) [sig/node]
- `DevicePluginCDIDevices` フィーチャーゲートが beta に昇格して、デフォルトで有効になりました。([#121254](https://github.com/kubernetes/kubernetes/pull/121254), [@bart0sh](https://github.com/bart0sh)) [sig/node]
  - :pencil: CDI (Container Device Interface) を device plugin がサポートします。具体的には device plugin から kubelet への通信で、ContainerAllocateResponse という構造体をやり取りして device plugin によるデバイスの割当結果を返すときに、CDIDevice の名前を返せるようになります。これによって、コンテナランタイムが適切な CDI を呼び出すことができるようになります。 
- `kubelet` の `--cloud-provider=external` が設定されているとき、ノードアドレスを `--node-ip` の値があればそれで初期化するようにして、なければ cloud provider がアドレスを割り当てるのを待ちます。([#121028](https://github.com/kubernetes/kubernetes/pull/121028), [@aojea](https://github.com/aojea)) [sig/node,sig/cloud-provider]
- `kubelet` が pods に対して `net.ipv4.tcp_fin_timeout`, `net.ipv4.tcp_keepalive_intvl`, `net.ipv4.tcp_keepalive_probes` をデフォルトで利用できるようにします。Pod Security Admission は `v1.29+` のバージョンで baseline および restricted のポリシーでこれを許可します。 ([#121240](https://github.com/kubernetes/kubernetes/pull/121240), [@HirazawaUi](https://github.com/HirazawaUi)) [sig/node,sig/auth]
` kubelet` が pods に対して `net.ipv4.tcp_keepalive_time` をデフォルトで利用できるようにします（Minimal kernel version は 4.5）。Pod Security Admission は `v1.29+` のバージョンで baseline および restricted のポリシーでこれを許可します。 ([#118846](https://github.com/kubernetes/kubernetes/pull/118846), [@cyclinder](https://github.com/cyclinder)) [sig/network,sig/node,sig/auth]
` kubelet` が image pull を含め end-to-end の pod 起動レイテンシメトリックを出力するようになりました。([#121041](https://github.com/kubernetes/kubernetes/pull/121041), [@ruiwen-zhao](https://github.com/ruiwen-zhao)) [sig/node]
  - :pencil: メトリック名は `pod_start_total_duration_seconds` です。
- `kubelet` がノード起動の異なるステージについてレイテンシメトリックを出力するようになりました。 ([#118568](https://github.com/kubernetes/kubernetes/pull/118568), [@qiutongs](https://github.com/qiutongs)) [sig/scalability,sig/node,sig/instrumentation]
  - :pencil: メトリック名は以下のとおりです：
    - `node_startup_pre_kubelet_duration_seconds`
    - `node_startup_pre_registration_duration_seconds`
    - `node_startup_registration_duration_seconds`
    - `node_startup_post_registration_duration_seconds`
    - `node_startup_duration_seconds`

### Documentation

- kubelet が Pod に対して Pod のリソースリクエストに対して利用可能なCPUが不足していて、CPU を割り当てるのに失敗したときのエラーメッセージを `not enough cpus available to satisfy request` から `not enough cpus available to satisfy request: <num_requested> requested, only <num_available> available` に変更します。 ([#121059](https://github.com/kubernetes/kubernetes/pull/121059), [@matte21](https://github.com/matte21)) [sig/node]

### Failing Test

- `k8s.io/dynamic-resource-allocation`: Kubernetes `v1.27`, `v1.28` と互換があるように DRA driver を更新しました。([#120868](https://github.com/kubernetes/kubernetes/pull/120868), [@pohly](https://github.com/pohly)) [sig/node]

### Bug or Regression

- ユーザが名前を設定せずに static pod を `kubelet` 経由で作成した場合のチェックを追加しました。これに違反した場合、理解可能なvalidation errorが出力されます。 ([#119522](https://github.com/kubernetes/kubernetes/pull/119522), [@YTGhost](https://github.com/YTGhost)) [sig/node]
- CRI stats provider を使っている場合に、uncached partitions についてのログが `error` から `info` に変更されました。 ([#100448](https://github.com/kubernetes/kubernetes/pull/100448), [@saschagrunert](https://github.com/saschagrunert)) [sig/node]
- CPU や Memory の未定義なリソースについて、checkpoint ファイルで Empty value がアサインされないようになれました。 ([#117615](https://github.com/kubernetes/kubernetes/pull/117615), [@aheng-ch](https://github.com/aheng-ch)) [sig/node]
` systemLogQuery` サービス名前マッチングが修正されました。 ([#120678](https://github.com/kubernetes/kubernetes/pull/120678), [@rothgar](https://github.com/rothgar)) [sig/node]
- `v1.28` の init containers の再起動が通常のコンテナと相対的に正しい順になるようにリグレッションを直しました。 ([#120281](https://github.com/kubernetes/kubernetes/pull/120281), [@gjkim42](https://github.com/gjkim42)) [sig/node,sig/testing]
- `SidecarContainers` を有効にした `v1.28` の init containers の再起動が通常のコンテナと相対的に正しい順になるようにリグレッションを直しました。 ([#120269](https://github.com/kubernetes/kubernetes/pull/120269), [@gjkim42](https://github.com/gjkim42)) [sig/node,sig/testing]
- `swap` が無効にされているとき、`cgroupv2` なシステムにおいてコンテナがスタートしないバグを修正しました。 ([#120784](https://github.com/kubernetes/kubernetes/pull/120784), [@elezar](https://github.com/elezar)) [sig/node]
- `containerRestartPolicy` が Always になっているとき、init container に設定した CPU セットが、誤って通常のコンテナに再利用されているバグを修正しました。 ([#119447](https://github.com/kubernetes/kubernetes/pull/119447), [@gjkim42](https://github.com/gjkim42)) [SIG Node and Testing] [sig/node,sig/testing]
- `containerRestartPolicy` が Always になっているとき、init container に設定したデバイスが、誤って通常のコンテナに再利用されているバグを修正しました。 ([#120461](https://github.com/kubernetes/kubernetes/pull/120461), [@gjkim42](https://github.com/gjkim42)) [sig/node,sig/testing]
- `containerRestartPolicy` が Always になっているとき、init container に設定したメモリリソースが、誤って通常のコンテナに再利用されているバグを修正しました。  ([#120715](https://github.com/kubernetes/kubernetes/pull/120715), [@gjkim42](https://github.com/gjkim42)) [SIG Node] [sig/node]
- `EventedPLEG` を有効にしているとき、`kubelet` がコンテナを作成するときの振る舞いに関するリグレッションを修正しました。 ([#120942](https://github.com/kubernetes/kubernetes/pull/120942), [@sairameshv](https://github.com/sairameshv)) [sig/node]
- コンテナの起動時間に関する `container_start_time_seconds` という kubelet のリソースメトリックのバグを修正しました。 ([#120518](https://github.com/kubernetes/kubernetes/pull/120518), [@saschagrunert](https://github.com/saschagrunert)) [SIG Instrumentation, Node and Testing] [sig/node,sig/instrumentation,sig/testing]
- コンテナランタイムによって pin されていたイメージが `kubelet` によってガベージコレクトされているバグを修正しました。 ([#119986](https://github.com/kubernetes/kubernetes/pull/119986), [@ruiwen-zhao](https://github.com/ruiwen-zhao)) [sig/node]
- `kubectl logs POD_NAME -f` が実行中に、kubelet がログファイルをローテートしたとき、kubelet がログを出力しない問題を修正しました。 ([#115702](https://github.com/kubernetes/kubernetes/pull/115702), [@xyz-li](https://github.com/xyz-li)) [sig/node]
- ホストと pod がネームスペースを共有するときに許可されていない sysctls が、pod を作成するか更新するときに、そのような sysctls が含まれないことを確認するようになりました。 ([#118705](https://github.com/kubernetes/kubernetes/pull/118705), [@pacoxu](https://github.com/pacoxu)) [sig/node,sig/apps]
- `pod_start_duration_seconds` のメトリックバケットが、`{0.5, 1, 2, 3, 4, 5, 6, 8, 10, 20, 30, 45, 60, 120, 180, 240, 300, 360, 480, 600, 900, 1200, 1800, 2700, 3600}` に更新されました。 ([#120680](https://github.com/kubernetes/kubernetes/pull/120680), [@ruiwen-zhao](https://github.com/ruiwen-zhao)) [sig/node,sig/instrumentation]
- ユーザが kubelet に対して CRI-O の socket path を設定しているとき、例えば `/run/crio/crio.sock` を指定している場合に、CRI stats provider が奇妙な振る舞いをしないようになりました。 ([#118704](https://github.com/kubernetes/kubernetes/pull/118704), [@dgl](https://github.com/dgl)) [sig/node]
- `k8s.io/dynamic-resource-allocation/controller`: `UnsuitableNodes` が 割り当てられている claim と 割り当てられていない claim の混合を正しく扱えるようになりました。([#120338](https://github.com/kubernetes/kubernetes/pull/120338), [@pohly](https://github.com/pohly)) [sig/node]
- `k8s.io/dynamic-resource-allocation/controller`: `ResourceClaimParameters` and `ResourceClassParameters` validation errors are now visible on `ResourceClaim`, `ResourceClass` and `Pod`. ([#121065](https://github.com/kubernetes/kubernetes/pull/121065), [@byako](https://github.com/byako)) [sig/node]
- `k8s.io/dynamic-resource-allocation` が、`potential` とリストされていないノードを `selected` と扱えるようになりました。 ([#120871](https://github.com/kubernetes/kubernetes/pull/120871), [@pohly](https://github.com/pohly)) [sig/node]

### Other (Cleanup or Flake)

- local debugging を行うときの `local-up-cluster.sh` での CNI バイナリの自動ダウンロードを行うようになりました。 ([#120312](https://github.com/kubernetes/kubernetes/pull/120312), [@HirazawaUi](https://github.com/HirazawaUi)) [sig/network,sig/node]
- Dynamic resource allocation: 毎回の prepare/unprepare resource の呼び出しで、新しい gRPC 接続を作らないようになりました。 ([#118619](https://github.com/kubernetes/kubernetes/pull/118619), [@TommyStarK](https://github.com/TommyStarK)) [sig/node]
- 生成された `ResourceClaim` の名前が、ランダムな接尾子の前にハイフンをつけるようになったので、より読みやすくなりました。 (`<pod name>-<claim name>-<random suffix>`). ([#120336](https://github.com/kubernetes/kubernetes/pull/120336), [@pohly](https://github.com/pohly)) [sig/node,sig/apps]
- `GA` したフィーチャーゲート `CSIMigrationvSphere` が削除されました。 ([#121291](https://github.com/kubernetes/kubernetes/pull/121291), [@bzsuni](https://github.com/bzsuni)) [sig/storage,sig/node,sig/api-machinery]
- `GA` したフィーチャーゲート `ProbeTerminationGracePeriod` が削除されました。 ([#121257](https://github.com/kubernetes/kubernetes/pull/121257), [@bzsuni](https://github.com/bzsuni)) [sig/node,sig/testing]
- `GA` したフィーチャーゲート `TopologyManager` が削除されました。 ([#121252](https://github.com/kubernetes/kubernetes/pull/121252), [@tukwila](https://github.com/tukwila)) [sig/node]
- `GA` したフィーチャーゲート `SeccompDefault` が削除されました。 ([#121246](https://github.com/kubernetes/kubernetes/pull/121246), [@tukwila](https://github.com/tukwila)) [sig/node]
- 既に安定していて常に有効になっているフィーチャーゲート `DownwardAPIHugePages` が削除されました。 ([#120249](https://github.com/kubernetes/kubernetes/pull/120249), [@pacoxu](https://github.com/pacoxu)) [SIG Apps and Node] [sig/node,sig/apps]
- 既に安定していて常に有効になっているフィーチャーゲート `GRPCContainerProbe` が削除されました。 ([#120248](https://github.com/kubernetes/kubernetes/pull/120248), [@pacoxu](https://github.com/pacoxu)) [sig/node,sig/api-machinery,sig/cli]
- `/metrics/slis` を提供する `ComponentSLIs` フィーチャーゲートが、GAに昇格して、無条件で有効になりました。このフィーチャーゲートは `v1.31` で削除されます。 ([#120574](https://github.com/kubernetes/kubernetes/pull/120574), [@logicalhan](https://github.com/logicalhan)) [sig/network,sig/scheduling,sig/node,sig/api-machinery,sig/instrumentation,sig/architecture,sig/cloud-provider]
- CNI plugins が `v1.3.0` に更新されました。 ([#119969](https://github.com/kubernetes/kubernetes/pull/119969), [@saschagrunert](https://github.com/saschagrunert)) [sig/node,sig/testing,sig/cloud-provider]
- runc が `1.1.10` に更新されました。 ([#121739](https://github.com/kubernetes/kubernetes/pull/121739), [@ty-dc](https://github.com/ty-dc)) [sig/node,sig/architecture]
- `GetPodQOS(pod *core.Pod)` 関数が、`PodStatus.QOSClass` に格納されている値を返すようになりました。この値を計算するには、`ComputePodQOS(pod*core.Pod)` を使用してください。 ([#119665](https://github.com/kubernetes/kubernetes/pull/119665), [@vinaykul](https://github.com/vinaykul)) [sig/scheduling,sig/node,sig/api-machinery,sig/apps,sig/cli,sig/testing]