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

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

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

## 所感
:pencil:

今回の Kubernetes 1.28 リリースでは、SIG-Node (Kubelet) 系での大きな変更・機能追加がありました。特に気になったものを抜粋して紹介します。

大きな変更としては、Swap のサポートが追加されました。 `Limited` swap と `Unlimited` swap の2つのモードが実装されています。 `Limited` swap は、Burstable pod の場合は memory request の割合で swap 領域を分け合う、という直感的な振る舞いをします。メモリ領域が厳しい環境で Kubernetes を利用されている方には有効な機能かもしれません。

また、cgroup v2 の `memory.oom.group` で pod 内のプロセスをまとめて扱って OOM させる機能が実装されました。こちらもメモリ領域が厳しい環境では、中途半端にプロセス単位で evict されるのではなく、pod 単位で evict されたりしなかったりするので、限りあるメモリを有効に使ってギリギリまで pod を実行させることができそうです。

User namespace 対応も続けられています。Kubernetes 1.28 では idmapped mount を使うことで、これまで stateless な pod (emptyDir や configMap のみ使っていて、hostPath や PVC は使用していなかった）に限定されていた User namespace 利用が、stateful な pod にも広げられました。 user namespace は、uid/gid の空間を別個に用意する namespace 機能で、コンテナ内では特権 (uid=0, gid=0) ですが、ホストではそうではない、というような mapping を設定できます。

## Changes by Kind

### Deprecation

- Kubelet: `--azure-container-registry-config` フラグが廃止予定になりました。代わりに `--image-credential-provider-config` と `--image-credential-provider-bin-dir` フラグを使って、Azure Container Registry の credential provider を設定してください。([#118596](https://github.com/kubernetes/kubernetes/pull/118596), [@SataQiu](https://github.com/SataQiu)) [SIG Node] [sig/node]

### API Change

- CDIDevice フィールドが、Device Plugin の `ContainerAllocateResponse` に含まれるようになりました。このフィールドは、CRIプロトコルのCDIDeviceにマップされます。 ([#118254](https://github.com/kubernetes/kubernetes/pull/118254), [@elezar](https://github.com/elezar)) [SIG Node and Testing] [sig/node,sig/testing]
  - :pencil:
    - [CDI (Container Device Interface)](https://github.com/cncf-tags/container-device-interface) は、コンテナランタイムがサードパーティのデバイスをサポートするためのインターフェイスです。デバイスは、 `vendor.com/class=unique_name` で表現されるそうです。これにより、1つのデバイスが複数のファイルに対応したり、なんらかのチェックを行ったり、ランタイムごとに特殊な処理を行ったりするような、ベンダ特有の複雑性を隠蔽するためにあるそうです。
    - デバイスプラグインが allocate の結果として Kubelet に設定するべきデバイスの名前 (CDIDevice) を返し、Kubelet がコンテナランタイムにその名前を転送して、コンテナランタイムが名前に対応したコンテナの設定を行います。これまではアノテーションを利用していたそうです。
- 正しく `localhostProfile` を設定しないような seccomp localhost configuration についてのエラーハンドリングを追加しました。 ([#117020](https://github.com/kubernetes/kubernetes/pull/117020), [@cji](https://github.com/cji)) [sig/node,sig/api-machinery]
- cgroup v2を使う場合に、`memory.oom.group` を使って container cgroup aware な OOM killer が有効になるようにします。これにより、同じ cgroup に属するプロセスが単一のものとして扱われるようになり、cgroup 内の任意のプロセスが OOM kill されたときに、同時にグループ内のプロセスが kill されるようになります。 ([#117793](https://github.com/kubernetes/kubernetes/pull/117793), [@tzneal](https://github.com/tzneal)) [SIG Apps, Node and Testing] [sig/node,sig/apps,sig/testing]
  - :pencil:
    - これにより、cgroup 内のプロセスが中途半端に kill されることがなく、一貫して kill されたりされなかったりするので、よりマルチプロセスのワークロードを安定的に実行できるようになります。
- `WindowsHostProcessContainers` feature gate が削除されました。 ([#117570](https://github.com/kubernetes/kubernetes/pull/117570), [@marosset](https://github.com/marosset)) [SIG API Machinery, Apps, Auth, Node and Windows] [sig/node,sig/api-machinery,sig/auth,sig/apps,sig/windows]

### Feature

- kubelet によって preempt された pod について `DistruptionTarget` condition が設定されるようになりました。これにより、重要な pod のためのスペースを作ることができます。 ([#117586](https://github.com/kubernetes/kubernetes/pull/117586), [@mimowo](https://github.com/mimowo)) [sig/node,sig/testing]
  - :pencil:
    - [KEP-3329: Retriable and non-retriable Pod failures for Jobs](https://github.com/kubernetes/enhancements/tree/master/keps/sig-apps/3329-retriable-and-non-retriable-failures) で、Pod障害をハンドルする方法をカスタマイズできるようになりました。これにより、Job をリトライするようなPod障害と、エラーとカウントするようなPod障害を区別できるようになります。この変更は、kubelet による preemption の場合でも、この KEP の対象として扱えるようにするためのものです。
- cgroup v2 での `Limited` と `Unlimited` swap をサポートしました。 ([#118764](https://github.com/kubernetes/kubernetes/pull/118764), [@iholder101](https://github.com/iholder101)) [sig/node,sig/testing]
  - `Limited` Swap は、Burstable QoS な Pod に対して自動的に設定されます。利用可能な Swap 量は、`(<memory-request>/<node-memory-capacity>)*<node-swap-capacity>` で計算されます。
  - Burstable QoS ではない Pod (Best-Effort もしくは Guaranteed) では、Swap は無効化されています。
  - cgroup v1 はサポートされなくなりました。
  - :pencil:
    - KubeletConfiguration で、 `Limited` swap を利用するか、 `Unlimited` swap を利用するかを設定することができます。 `Limited` の場合は、メモリリクエスト量の割合で swap 量が制約されます。 `Unlimited` の場合は、swap 量の制約はありません。デフォルトは `Limited` swap です。
- `hostNetwork` field selector がサポートされました。 ([#110477](https://github.com/kubernetes/kubernetes/pull/110477), [@halfcrazy](https://github.com/halfcrazy)) [SIG Apps and Node] [sig/node,sig/apps]
- Swap に関するメトリクスが、 Summary API (stats/summary) と、Prometheus endpoint (/metrics/resource) に追加されました。 ([#118865](https://github.com/kubernetes/kubernetes/pull/118865), [@iholder101](https://github.com/iholder101)) [sig/node,sig/testing]
- CRI: Windows 限定の コンテナの commit memory bytes が container stats に出力されるようになりました。 ([#119238](https://github.com/kubernetes/kubernetes/pull/119238), [@kiashok](https://github.com/kiashok)) [sig/node,sig/windows]
- Dynamic resource allocation: wait for first consumer (default) が claim で使用されているとき、pod が利用し終わったときに deallocate されるようになりました。これにより、その後の pod について、以前のスケジューリング結果に影響されなくなったり、不必要な時にリソースが確保され続けられることがないようになりました。もし、リソースを確保し続けたい場合には、immediate を使用する必要があります。 ([#118936](https://github.com/kubernetes/kubernetes/pull/118936), [@pohly](https://github.com/pohly)) [sig/node,sig/apps,sig/testing]
- Volume と user namespace を同時に使えるようになりました。以前の `UserNamespacesStatelessPodsSupport` feature gate が `UserNamespacesSupport` にリネームされました。 ([#118691](https://github.com/kubernetes/kubernetes/pull/118691), [@giuseppe](https://github.com/giuseppe)) [sig/node,sig/apps,sig/testing]
  - :pencil:
    - このPRでは、単純に user namespace を使っている時に、volume を検査して stateful なものがあったら弾く、という `UserNamespacesStatelessPodsSupport` を実装した時に追加されたバリデーションを削除しているだけのようです。
    - idmapped mount が実現したことによって、[KEPの範囲を stateless pod only から stateful pod も含めるように広げるPR](https://github.com/kubernetes/enhancements/pull/4084)がマージされたので、バリデーションを削除したようです。
    - idmapped mount は、ファイルのuid/gidを読み替える機能です。通常1つのファイルには1つのuid/gidしか所有者として設定できませんが、idmapped mountを使うことでマウント単位でuid/gidの読み替えを行えるため、ファイルの所有者を複数のuidにしたり、コンテナ内からはuid=0に見えるがホストではそうではない、といったことが実現できます。
- Kubelet が呼び出した external credential provider plugin の stderr がロギングされるようになりました。 ([#117448](https://github.com/kubernetes/kubernetes/pull/117448), [@cartermckinnon](https://github.com/cartermckinnon)) [sig/node]
- ResourceClaims が関わるスケジューリングが高速になりました。 ([#119078](https://github.com/kubernetes/kubernetes/pull/119078), [@pohly](https://github.com/pohly)) [sig/scheduling,sig/node]
- `ProbeTerminationGracePeriod` が GA しました。 ([#114307](https://github.com/kubernetes/kubernetes/pull/114307), [@rphillips](https://github.com/rphillips)) [sig/node,sig/apps]
  - :pencil:
    - ProbeTerminationGracePeriod は、Probe の `terminationGracePeriodSeconds` で設定できるものです。Pod の終了時間は PodSpec 内の terminationGracePeriodSeconds で設定できますが、probe が fail した場合の grace period を probe ごとに override することができます。
- drop-in kubelet configuration directory の アルファサポートが実装されました。 ([#119390](https://github.com/kubernetes/kubernetes/pull/119390), [@sohankunkerkar](https://github.com/sohankunkerkar)) [sig/node]
  - :pencil:
    - 特定のディレクトリにおいた設定ファイルで、kubeletConfigurationを override することができます。
- Kubelet: dynamic resource allocation の plugin が、`v1alpha2` API の代わりに `v1alpha3` API を利用することで、prepare/unprepare をバッチで行うことができるようになります。 ([#119012](https://github.com/kubernetes/kubernetes/pull/119012), [@pohly](https://github.com/pohly)) [sig/node,sig/testing]
- Kubelet: dynamic resource allocation に関する object が、当該ノードからしか操作できないようにすることで、セキュリティを向上します。 ([#116254](https://github.com/kubernetes/kubernetes/pull/116254), [@pohly](https://github.com/pohly)) [SIG Auth and Testing] [sig/auth,sig/testing]
- Kubelet: `--provider-id` フラグを deprecated ではなくしました。 ([#116530](https://github.com/kubernetes/kubernetes/pull/116530), [@pacoxu](https://github.com/pacoxu)) [sig/node]
- `PodHasNetwork` feature gate を `PodReadyToStartContainers` にリネームしました。 ([#117702](https://github.com/kubernetes/kubernetes/pull/117702), [@kannon92](https://github.com/kannon92)) [SIG Node and Testing] [sig/node,sig/testing]
- `ExpandedDNSConfig` feature が GA しました。この機能はデフォルトで有効で、v1.30で feature gate が削除されるので、明示的に設定している場合は削除してください。 ([#116741](https://github.com/kubernetes/kubernetes/pull/116741), [@gjkim42](https://github.com/gjkim42)) [SIG Apps, Network and Node] [sig/network,sig/node,sig/apps]
- cAdvisor が `v0.47.2` に更新され、コンテナがリスタートしたときに `cri-o` のメトリクスがおかしかった問題が解決しました。 ([#118774](https://github.com/kubernetes/kubernetes/pull/118774), [@harche](https://github.com/harche)) [sig/node]
- pod が完了したかもう起動しないときには、`ResourceClaims` を他の pod から再利用するか、削除できるようにします。 ([#118817](https://github.com/kubernetes/kubernetes/pull/118817), [@pohly](https://github.com/pohly)) [sig/node,sig/api-machinery,sig/auth,sig/apps,sig/testing]
- `KubeletCgroupDriverFromCRI` feature gate が有効になっていて、container runtime が十分に新しい場合、kubelet が自動で container runtime から受け取ったcgroup driver configを検出して、cgroupDriver configuration を指定する必要がなくなりました。 ([#118770](https://github.com/kubernetes/kubernetes/pull/118770), [@marquiz](https://github.com/marquiz)) [sig/node]
- `TopologyManagerPolicyOptions` feature flag がベータに昇格して、デフォルトで有効になりました。 ([#118816](https://github.com/kubernetes/kubernetes/pull/118816), [@PiotrProkop](https://github.com/PiotrProkop)) [sig/node]
  - :pencil:
    - TopologyManagerPolicyOptions は、Topology Manager のポリシー（どのようにNUMAを使うか）にオプションを与えて振る舞いを変更するための機能です。

### Bug or Regression

- 新しいイベント `FailedToRetrieveImagePullSecret` が、pod が参照する `ImagePullSecret` が存在していない時に発報されるようになりました。 ([#117927](https://github.com/kubernetes/kubernetes/pull/117927), [@kaisoz](https://github.com/kaisoz)) [SIG Node] [sig/node]
- Kubernetes `v1.26` と `v1.27` で、resource claim が不要な場合に prepare されていた問題を修正します。 ([#118786](https://github.com/kubernetes/kubernetes/pull/118786), [@pohly](https://github.com/pohly)) [sig/node,sig/testing]
- cAdvisor のバージョンを `v0.47.3` に更新します。 ([#119225](https://github.com/kubernetes/kubernetes/pull/119225), [@iholder101](https://github.com/iholder101)) [sig/node,sig/testing]
- CVE-2023-27561 CVE-2023-25809 CVE-2023-28642: runc を v1.1.4 から v1.1.5 に更新します。 ([#117095](https://github.com/kubernetes/kubernetes/pull/117095), [@PushkarJ](https://github.com/PushkarJ)) [SIG Architecture, Node and Security] [sig/node,sig/architecture,sig/security]
- device plugin の allocation で、 pod によってリクエストされたリソースが、その device plugin によって kubelet に登録されている かつ allocate されるデバイスがノードに存在するときのみ allocate することができます。これが満たされていない場合は `UnexpectedAdmissionError` で pod が失敗します。 ([#116376](https://github.com/kubernetes/kubernetes/pull/116376), [@swatisehgal](https://github.com/swatisehgal)) [SIG Node and Testing] [sig/node,sig/testing]
- Dynamic Resource Allocation: dynamic resource の prepare に失敗した場合に、ロギングとエラーイベントの発報を行います。 ([#118578](https://github.com/kubernetes/kubernetes/pull/118578), [@bart0sh](https://github.com/bart0sh)) [sig/node]
- 修正: ノードがダウンして、復活するまでいくらかの時間がかかるとき、evict された pod のマウントポイントが正しくクリーンナップされませんでした。(#111933) そのとき、kubelet が2秒ごとに `Orphaned pod "xxx" found, but error not a directory occurred when trying to remove the volumes dir` と出力していました。 (#105536) ([#116134](https://github.com/kubernetes/kubernetes/pull/116134), [@cvvz](https://github.com/cvvz)) [SIG Node and Storage] [sig/storage,sig/storage,sig/storage,sig/node]
- http (live-/readiness) プローブのカスタムの Accept header が小文字の場合に、意図せずオーバーライドしてしまっていたバグを修正しました。 ([#114606](https://github.com/kubernetes/kubernetes/pull/114606), [@tuunit](https://github.com/tuunit)) [sig/network,sig/node]
- リモートの CRI ランタイムについて、正しく `ErrRegistryUnavailable` を報告するようにバグを修正しました。 ([#117612](https://github.com/kubernetes/kubernetes/pull/117612), [@saschagrunert](https://github.com/saschagrunert)) [SIG Node] [sig/node]
- Kubelet が再起動される間に、non-admissible な pod が削除される問題を修正しました。 ([#118497](https://github.com/kubernetes/kubernetes/pull/118497), [@mimowo](https://github.com/mimowo)) [sig/node,sig/testing]
- Kubelet の起動が `NewVolumeManagerReconstruction` が有効で、CSI volume が `/var/lib/kubelet/pods` に存在する場合に、Kubelet の起動がスタックする問題を修正しました。 ([#117804](https://github.com/kubernetes/kubernetes/pull/117804), [@jsafrane](https://github.com/jsafrane)) [SIG Node and Storage] [sig/storage,sig/node]
- `preStop` フックを修正しました。現在は、pod termination grace period をブロックします。 ([#115835](https://github.com/kubernetes/kubernetes/pull/115835), [@HirazawaUi](https://github.com/HirazawaUi)) [sig/node,sig/testing]
- Kubelet が pod を停止するときに、Kubelet が再起動されると、pod が正しく停止しませんでした。これを修正し、Kubelet が再起動されても正しく pod を停止できるようになりました。 ([#117019](https://github.com/kubernetes/kubernetes/pull/117019), [@bobbypage](https://github.com/bobbypage)) [SIG Node and Testing] [sig/node,sig/testing]
- Volume 参照がない場合の pod termination が高速化されました。 ([#117412](https://github.com/kubernetes/kubernetes/pull/117412), [@smarterclayton](https://github.com/smarterclayton)) [SIG Node and Testing] [sig/node,sig/testing]
- mirror pod の phase を Succeeded か Failed に設定すると、Kubelet cache の変更による対応する static pod の再起動を防ぐことができます。 ([#116482](https://github.com/kubernetes/kubernetes/pull/116482), [@smarterclayton](https://github.com/smarterclayton)) [SIG Node] [sig/node]
- Static pod が更新後に再起動されるのに余計な時間がかかっていました。Static pod が再起動されるのを待っている時間が正しく `kubelet_working_pods` に反映されていませんでした。 ([#116995](https://github.com/kubernetes/kubernetes/pull/116995), [@smarterclayton](https://github.com/smarterclayton)) [SIG Node] [sig/node]
- DaemonSet のコントローラが、VM の preemption や pod finalizer を利用しているような終了Podの替えを作成します。 [#118716](https://github.com/kubernetes/kubernetes/pull/118716), [@alculquicondor](https://github.com/alculquicondor)) [sig/node,sig/apps,sig/testing]
- 順番のバグ（正しいが最適ではない）を修正することで、Static Pod が 2秒早く再起動します。 ([#116690](https://github.com/kubernetes/kubernetes/pull/116690), [@smarterclayton](https://github.com/smarterclayton)) [SIG Node] [sig/node]
- [Dual-stack] kubelet の `generateAPIPodStatus()` がセカンダリIPを正しくハンドルします。hostIPs の順序が一貫していませんでした。もし、セカンダリIPがプライマリのものよりも前の場合、今のロジックでは `PodIPs` にプライマリIPを2回追加してしまい、"may specify no more than one IP for each IP family" のエラーになっていました。 ([#116879](https://github.com/kubernetes/kubernetes/pull/116879), [@lzhecheng](https://github.com/lzhecheng)) [sig/node]
- `Kubelet` が umask によらず 0644 のモードになるようにします。 ([#113209](https://github.com/kubernetes/kubernetes/pull/113209), [@luozhiwenn](https://github.com/luozhiwenn)) [sig/node]
- `kubelet`: イベントの volume メッセージがソートされます。 ([#117079](https://github.com/kubernetes/kubernetes/pull/117079), [@qingwave](https://github.com/qingwave)) [sig/node]

### Other (Cleanup or Flake)

- コンテナランタイムが `ErrSigunatureValidationFailed` を使用できるようになりました。 ([#117717](https://github.com/kubernetes/kubernetes/pull/117717), [@saschagrunert](https://github.com/saschagrunert)) [sig/node]
- `node-local` kubelet podresources API が UNIX だけではなく Windows でも利用できるようになりました。 ([#115133](https://github.com/kubernetes/kubernetes/pull/115133), [@ffromani](https://github.com/ffromani)) [sig/node,sig/windows,sig/testing,sig/cloud-provider]
- non-amd64 のアーキテクチャで、DRAの e2e イメージのビルドを直しました。 ([#117912](https://github.com/kubernetes/kubernetes/pull/117912), [@bart0sh](https://github.com/bart0sh)) [SIG Node and Testing] [sig/node,sig/testing]
- feature gate `ExperimentalHostUserNamespaceDefaulting` が 廃止予定とされました。これを有効にしても効果がなく、将来的に feature gate が削除されます。 ([#116723](https://github.com/kubernetes/kubernetes/pull/116723), [@SergeyKanzhelev](https://github.com/SergeyKanzhelev)) [SIG Node] [sig/node]
- `k8s.io/kubernetes/pkg/kubelet/cri/streaming` package が `k8s.io/kubelet/pkg/cri/streaming`.に移動しました。 ([#118253](https://github.com/kubernetes/kubernetes/pull/118253), [@saschagrunert](https://github.com/saschagrunert)) [SIG Node, Release and Security] [sig/node,sig/release,sig/security]
- GA 済みの feature gate `DevicePlugins` が削除されました。 ([#117656](https://github.com/kubernetes/kubernetes/pull/117656), [@carlory](https://github.com/carlory)) [sig/node]
- GA 済みの feature gate `KubeletCredentialProviders` が削除されました。 ([#116901](https://github.com/kubernetes/kubernetes/pull/116901), [@pacoxu](https://github.com/pacoxu)) [sig/node,sig/testing,sig/cloud-provider]
- in-tree storage plugin の 廃止予定 `azureFile` が削除されました。 ([#118236](https://github.com/kubernetes/kubernetes/pull/118236), [@andyzhangx](https://github.com/andyzhangx)) [sig/storage,sig/node,sig/api-machinery,sig/cloud-provider]
- `GetAllocatableResources` podresources API エンドポイントが GA しました。 ([#118973](https://github.com/kubernetes/kubernetes/pull/118973), [@ffromani](https://github.com/ffromani)) [sig/node,sig/testing]
- feature gate `CSIMigrationGCE` が GA して、無条件に有効化されました。`gcepd` パッケージが削除されました。 ([#117055](https://github.com/kubernetes/kubernetes/pull/117055), [@cyclinder](https://github.com/cyclinder)) [sig/scheduling,sig/storage,sig/node,sig/api-machinery]
- feature gate `DisableAcceleratorUsageMetrics` と `PodSecurity` が GAして、無条件に有効化されました。 ([#114068](https://github.com/kubernetes/kubernetes/pull/114068), [@cyclinder](https://github.com/cyclinder)) [SIG API Machinery, Node, Scheduling and Storage] [sig/scheduling,sig/storage,sig/node,sig/api-machinery]
- kubelet podresources エンドポイントがGAして有効化されました。 ([#116525](https://github.com/kubernetes/kubernetes/pull/116525), [@ffromani](https://github.com/ffromani)) [SIG Node] [sig/node]
- `cri-tools` が `v1.27.0` に更新されました。 ([#117545](https://github.com/kubernetes/kubernetes/pull/117545), [@saschagrunert](https://github.com/saschagrunert)) [sig/node,sig/cloud-provider]