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

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

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

## 所感
:pencil:

重要な機能の追加としては、 `NodeLogQuery` があります。Kubernetes blogは[こちら](https://kubernetes.io/blog/2023/04/21/node-log-query-alpha/)。
Kubernetes ノードに問題が生じた可能性がある時、ノードにSSH接続して、ログを調査することがよくあります。`NodeLogQuery` を使用すると、SSHすることなく、kubectl を使って `journalctl` 相当のログ収集を行うことができます。また、`/var/log/` ディレクトリ以下のログも収集することができるそうです。

また、引き続き Dynamic Resource Allocation 関連の機能開発も進んでいます。例えば [PR #114364](https://github.com/kubernetes/kubernetes/pull/114364) では、CNIが呼ばれる前に DRA の PrepareResources API が呼ばれることを保証することで、PrepareResource 時点でネットワークデバイスの初期化を実施し、そのあとに CNI を使って Pod に attach する、ということができるようになったそうです。

他にも、 [KEP-127: Support User Namespaces in stateless pods](https://github.com/kubernetes/enhancements/blob/master/keps/sig-node/127-user-namespaces/README.md) では、stateless な Pod に対して、user namespaceが利用できるようになります。user namespace は、uid/gid の空間を別個に用意する namespace 機能で、コンテナ内では特権 (uid=0, gid=0) ですが、ホストではそうではない、というような mapping を設定できます。これにより、コンテナ内のプロセスが特権で動作していて、何らかの手段でコンテナからホストに出ることができたとしても、ホストでは特権ではないので、大きな影響はない、というようなことができます。

## Urgent Upgrade Notes
- 再起動されない全てのPodに正しく terminal phase を付与するようになりました。とくに、Pending中に削除されたPodにFailed phaseを付与したり、Running中に削除されたPodに terminal phase （つまり、Podの終了コードに基づく Succeeded か Failed ）を付与します。これは、Pod Failure Policy (JodPodFailurePolicy と PodDistruptionConditions feature gate が有効になっているもの)を使うJob が、削除された時に、Pending phaseでスタックする可能性があったことを直すものです。コントローラの開発者で、RestartPolicy=AlwaysなPodが、決して Succeeded phase に入らないことに依存している場合、これに適応する必要があるかもしれません。これは、RestartPolicy=AlwaysなPodが、Pod削除かgraceful node shutdownの2つのシナリオで、Succeeded phaseに移行するように変更されたためです。 ([#115331](https://github.com/kubernetes/kubernetes/pull/115331), [@mimowo](https://github.com/mimowo)) [SIG Cloud Provider, Node and Testing] [sig/node,sig/testing,sig/cloud-provider]

## Changes by Kind

### Deprecation

- Node オブジェクトの deprecated なフィールド `spec.externalID` をセットしたリクエストについて、[warning](https://k8s.io/blog/2020/09/03/warnings/) レスポンスがかえるようになりました。([#115944](https://github.com/kubernetes/kubernetes/pull/115944), [@SataQiu](https://github.com/SataQiu)) [SIG Node] [sig/node]
  - :pencil: `spec.externalID` はもともと、パブリッククラウドにおける instance id のような、ノードに紐づく外部のIDが設定されていたようです。（[参照](https://github.com/kubernetes/kubernetes/issues/61966#issuecomment-377659476)）

### API Change

- feature gate `NodeLogQuery` が追加され、クライアントサイドでのリーダの実装やノードへのログインをすることなくkubectlを使って、クラスタ管理者にログのストリーミングを提供できるようになりました。([#96120](https://github.com/kubernetes/kubernetes/pull/96120), [@LorbusChris](https://github.com/LorbusChris)) [sig/node,sig/api-machinery,sig/apps,sig/windows,sig/cli,sig/testing]
- Kubelet の API QPS limit が拡張されました。([#116121](https://github.com/kubernetes/kubernetes/pull/116121), [@wojtek-t](https://github.com/wojtek-t)) [sig/node,sig/api-machinery]
  - :pencil: QPS が 10倍に設定されたようです。
- GRPC プローブが GA しました。 `GRPCContainerProbe` feature gate はデフォルトにロックされていて、v1.29で削除されます。この feature gate を明示的に有効化している場合は、削除してください。([#116233](https://github.com/kubernetes/kubernetes/pull/116233), [@SergeyKanzhelev](https://github.com/SergeyKanzhelev)) [sig/node,sig/api-machinery,sig/apps]
- `Kubelet Topology Manager` が GA しました。([#116093](https://github.com/kubernetes/kubernetes/pull/116093), [@swatisehgal](https://github.com/swatisehgal)) [sig/node,sig/api-machinery,sig/testing]
  - :pencil: Topology Manager については[スライド](https://www.slideshare.net/pfi/topology-manager-kubernetes-meetup-tokyo-50)をご参照ください。この機能を用いることで、サーバ内のNUMA構成を考慮したデバイスの確保が実現でき、「NUMA的に近い」デバイスを同一のPodにつけることができます。
- `KubeletTracing` が beta に昇格しました。この feature gate はデフォルトで有効です。([#115750](https://github.com/kubernetes/kubernetes/pull/115750), [@saschagrunert](https://github.com/saschagrunert)) [sig/node,sig/instrumentation]
  - :pencil: KEPは[こちら](https://github.com/kubernetes/enhancements/tree/master/keps/sig-instrumentation/2831-kubelet-tracing)。 OpenTelemetry コレクタと接続することで、Kubeletのトレース情報を収集することができます。
- seccomp profile の defaulting が GA しました。kubelet の `--seccomp-default` flag か、`seccompDefault` kubelet configuration field を `true` に設定することで、そのノード上のPod で、 `RuntimeDefault` seccomp Profile が利用されるようになります。カーネルやコンテナランタイムのバージョンによっては、ワークロードのパフォーマンスに悪い影響を与えるかもしれません、これらを特定して緩和する方法は、[seccomp tutorial](https://k8s.io/docs/tutorials/security/seccomp)にまとめられています。 ([#115719](https://github.com/kubernetes/kubernetes/pull/115719), [@saschagrunert](https://github.com/saschagrunert)) [SIG API Machinery, Node, Storage and Testing] [sig/storage,sig/node,sig/api-machinery,sig/testing]
- `resource.k8s.io` API の `AllocationResult` 構造体に破壊的変更を行いました。この変更によって、`DynamicResourceAllocation` 向けのkubelet pluginに、複数のリソースドライバコントローラからの割り当てを提供することができるようになります。([#116332](https://github.com/kubernetes/kubernetes/pull/116332), [@klueska](https://github.com/klueska)) [sig/scheduling,sig/node,sig/api-machinery,sig/apps,sig/cli,sig/testing]
- Kubelet: `maxParallelImagePulls` フィールドを設定することで、並行にkubeletが実行するimage pullの数を制御することができます。 ([#115220](https://github.com/kubernetes/kubernetes/pull/115220), [@ruiwen-zhao](https://github.com/ruiwen-zhao)) [SIG API Machinery, Node and Scalability] [sig/scalability,sig/node,sig/api-machinery]
- Kubelet: `MemoryThrottlingFactor` のデフォルト値の`0.9`への変更と、`memory.high` を計算する式の変更を行いました。([#115371](https://github.com/kubernetes/kubernetes/pull/115371), [@pacoxu](https://github.com/pacoxu)) [sig/node,sig/api-machinery,sig/apps]
  - :pencil: limits.memory をギリギリまで使うワークロードのパフォーマンスを改善するため、0.8から0.9に増やしたそうです。（[参考](https://docs.google.com/document/d/1p9awiXhu5f4mWsOqNpCX1W-bLLlICiABKU55XpeOgoA/edit#heading=h.lzwcbx4fdx06)）
- deprecated になっていた `--enable-taint-manager` と `--pod-eviction-timeout` 引数を削除しました。([#115840](https://github.com/kubernetes/kubernetes/pull/115840), [@atosatto](https://github.com/atosatto)) [sig/node,sig/api-machinery,sig/apps,sig/testing]
- `DynamicResourceManagement` の `v1alpha1` の kubelet plugin API を削除しました。すべてのプラグインは `v1alpha2` に移行する必要があります。 ([#116558](https://github.com/kubernetes/kubernetes/pull/116558), [@klueska](https://github.com/klueska)) [sig/scheduling,sig/node,sig/api-machinery,sig/apps,sig/cli,sig/testing]
- `PodDistruptionBudget` の `spec.unhealthyPodEvictionPolicy` が beta に昇格し、デフォルトで有効になりました。有効になっているサーバでは、このフィールドは `AlwaysAllow` に設定されることがあり、常に PodDistruptionBudget でカバーされる unhealthy pod が常に削除されることを許します。([#115363](https://github.com/kubernetes/kubernetes/pull/115363), [@ravisantoshgudimetla](https://github.com/ravisantoshgudimetla)) [SIG Apps, Auth and Node] [sig/node,sig/auth,sig/apps]
- `DownwardAPIHugePages` kubelet feature が GA しました。([#115721](https://github.com/kubernetes/kubernetes/pull/115721), [@saschagrunert](https://github.com/saschagrunert)) [SIG Apps and Node] [sig/node,sig/apps]
  - :pencil: DownwardAPI で hugepage の requests と limits がとれるようになる機能です。
- `Requests` に関する API リファレンスが更新され、Limits を超えられないことが説明されました。 ([#115434](https://github.com/kubernetes/kubernetes/pull/115434), [@ehashman](https://github.com/ehashman)) [sig/node,sig/docs,sig/architecture]
  - :pencil: ご存知かと思いますが、Podの Resource Request は、Resource Limit よりも小さい値を指定する必要があります。
- `UpdateContainerResources` CRI API が Linux と Windows でサポートされるようになりました。([#102884](https://github.com/kubernetes/kubernetes/pull/102884), [@vinaykul](https://github.com/vinaykul)) [sig/scheduling,sig/node,sig/api-machinery,sig/apps,sig/instrumentation,sig/testing]
  - :pencil: UpdateContainerResourcesは[このようなAPI](https://github.com/kubernetes/cri-api/blob/d12277e32f6e8d1e668b4c18b52751268cd8ac3d/pkg/apis/runtime/v1/api.proto#L84)です。
- Kubelet: `--container-runtime-endpoint` と `--image-service-endpoint` が kubelet config に移行されました。([#112136](https://github.com/kubernetes/kubernetes/pull/112136), [@pacoxu](https://github.com/pacoxu)) [sig/scalability,sig/node,sig/api-machinery]
- `resource.k8s.io/v1alpha1` が `resource.k8s.io/v1alpha2` に移行しました。クラスタを更新するまえに、ResourceClaim, ResourceClaimTemplate, ResourceClass, PodScheduling オブジェクトは削除される必要があります。この変更は内部的なものなので、YAMLファイルは apiVersion 以外変更する必要がありません。([#116299](https://github.com/kubernetes/kubernetes/pull/116299), [@pohly](https://github.com/pohly)) [sig/scheduling,sig/node,sig/api-machinery,sig/apps,sig/cli,sig/testing]

## Feature

- `NewVolumeManagerReconstruction` が追加されデフォルトで有効になりました。これにより、kubelet起動時にマウントされたボリュームの探索が更新されます。kubeletが起動時にスタックしたり、削除されたPodのボリュームのマウントが解除されない場合は、issueを起票してください。([#115268](https://github.com/kubernetes/kubernetes/pull/115268), [@jsafrane](https://github.com/jsafrane)) [sig/storage,sig/node]
- Topology Manager のメトリクスが追加され、発生したadmission requestとエラーについて追跡できるようになりました。([#115137](https://github.com/kubernetes/kubernetes/pull/115137), [@swatisehgal](https://github.com/swatisehgal)) [sig/node,sig/testing]
  - :pencil: メトリクス名は `kubelet_topology_manager_admission_requests_total`, `kubelet_topology_manager_admission_errors_total`。
- Topology Manager のメトリクスが追加され、Topology Manager でのadmissionにかかった時間が測れるようになりました。([#115590](https://github.com/kubernetes/kubernetes/pull/115590), [@swatisehgal](https://github.com/swatisehgal)) [sig/node,sig/testing]
  - :pencil: メトリクス名は `kubelet_topology_manager_admission_duration_ms`。
- `UserNamespacesStatelessPodsSupport` feature gate を有効にすることで、分離された user namespace で、stateless pod を実行することができます。([#116377](https://github.com/kubernetes/kubernetes/pull/116377), [@giuseppe](https://github.com/giuseppe)) [SIG Apps, Node and Storage] [sig/storage,sig/node,sig/apps]
  - :pencil: KEPは[こちら](https://github.com/kubernetes/enhancements/blob/master/keps/sig-node/127-user-namespaces/README.md)。 user namespace によって、pod 内のプロセスに特権をもたせていたとしても、ホストでは非特権なuid/gidにすることができるようになります。コンテナ内のプロセスがホストにアクセスできたとしても、ホストでは、特権を失っており問題がない、というふうなことを実現できます。
- Dynamic Resource Allocation framework が network device に対しても利用できるようになりました。([#114364](https://github.com/kubernetes/kubernetes/pull/114364), [@bart0sh](https://github.com/bart0sh)) [SIG Node] [sig/node]
  - :pencil: もともとは、CNI が呼ばれるタイミングと、`PrepareResources` API が呼ばれるタイミングが逆転していたため、正しく Prepare したのちに NIC を Pod につけることができませんでした。
- GRPC probe の linger option が 1s に設定されて、TIME-WAIT state を改善するようになりました。([#115321](https://github.com/kubernetes/kubernetes/pull/115321), [@rphillips](https://github.com/rphillips)) [SIG Network and Node] [sig/network,sig/node]
- Evented PLEG が Beta になりました。([#115967](https://github.com/kubernetes/kubernetes/pull/115967), [@harche](https://github.com/harche)) [sig/node]
  - :pencil: KEPは[こちら](https://github.com/kubernetes/enhancements/blob/master/keps/sig-node/3386-kubelet-evented-pleg/README.md)。PLEG は Pod Lifecycle Event Geneletor の略です。CRI からコンテナの情報を取得する方法を、polling から event 駆動に変更することで、更新をすばやく少ないCPU時間で取得できるようにすることを目指しています。
- Kubelet の TCP / HTTP probe がよりネットワークのリソース（conntrack entries, sockets) を効率的に使用するようにしました。これは、`TIME-WAIT` の長さをデフォルトの60秒から1秒に短縮する、ということで実現されています。これにより kubelet が socket を開放し、conntrack entryや割り当てられた ephemeral port を開放できるようになります。([#115143](https://github.com/kubernetes/kubernetes/pull/115143), [@aojea](https://github.com/aojea)) [sig/network,sig/node]
- Kubelet が pod に `net.ipv4.ip_local_reserved_ports` sysctl を使うことをデフォルトで許可するようになり、minimal kernel version が 3.16 になりました。Pod Security Admission は v1.27 以上で、baseline および restricted ポリシーでこれを許可します。([#115374](https://github.com/kubernetes/kubernetes/pull/115374), [@pacoxu](https://github.com/pacoxu)) [SIG Auth, Network and Node] [sig/network,sig/node,sig/auth]

### Documentation

- CRI API における reason フィールドが、OOM Killer によってコンテナが終了された時に、`OOMKilled` になることをドキュメントしました。([#112977](https://github.com/kubernetes/kubernetes/pull/112977), [@mimowo](https://github.com/mimowo)) [sig/node]
- Requests が Limits を超えた場合のエラーメッセージに、Limits の値が含まれるようにしました。([#112925](https://github.com/kubernetes/kubernetes/pull/112925), [@SergeyKanzhelev](https://github.com/SergeyKanzhelev)) [sig/node,sig/apps]

### Falling Test

- Windows における Kubelet の `--resolv-conf=Host` オプションが、Pod DNS Policy を想定通り設定します。([#110566](https://github.com/kubernetes/kubernetes/pull/110566), [@claudiubelu](https://github.com/claudiubelu)) [sig/network,sig/node,sig/windows,sig/testing]

### Bug or Regression

- Host Path Provisioner によって作成された Host Path Bolume の `SELinux` ラベルを修正 ([#112021](https://github.com/kubernetes/kubernetes/pull/112021), [@mrunalp](https://github.com/mrunalp)) [sig/storage,sig/node]
- Windows における CPU Limits の計算が、64 論理Processer を超えるとおかしかった問題を修正 ([#114231](https://github.com/kubernetes/kubernetes/pull/114231), [@mweibel](https://github.com/mweibel)) [sig/node,sig/windows]
- 実際にはPodにマウントされていないディレクトリがあるとき、これをアンマウントしようと試行してしまうことで、Pod の終了がスタックする問題を修正 ([#115769](https://github.com/kubernetes/kubernetes/pull/115769), [@mochizuki875](https://github.com/mochizuki875)) [sig/storage,sig/node]
- コンテナランタイムが終了時にエラーを返したことで、kubeletが再起動されるまで、force delete された pod の終了に失敗する。ランタイムのエラーに関してテストを強化し、もっと頑健な reconcile を実装することで、static pod (とくに、固定されたUIDを利用するもの）が再起動できるようにした。副作用として、static pod の再起動にかかるレイテンシが短縮され（平均時間で4秒から2秒）、pod 設定の変更がより早く反映されるようになった。新しいメトリック `kubelet_known_pods` が Alpha 安定性として追加され、kubelet が追跡しているPodの数を報告するようになった。オペレータはこのメトリックを使って、終了していない孤立したPodの増加を確認することができる。([#113145](https://github.com/kubernetes/kubernetes/pull/113145), [@smarterclayton](https://github.com/smarterclayton)) [SIG API Machinery, Auth, Cloud Provider, Node and Testing] [sig/node,sig/api-machinery,sig/auth,sig/testing,sig/cloud-provider]
- ユーザが ephemeral container を static pod に追加しようとした時に、わかりやすい validation error が出力されるようになった。([#114086](https://github.com/kubernetes/kubernetes/pull/114086), [@xmcqueen](https://github.com/xmcqueen)) [sig/node,sig/apps]
- service か image のエンドポイントがエラーを返す時に、kubelet の起動が CRI connection に失敗する。([#115102](https://github.com/kubernetes/kubernetes/pull/115102), [@saschagrunert](https://github.com/saschagrunert)) [sig/node]
- Kubelet: image pull が終了したときの recording issue を修正 ([#114904](https://github.com/kubernetes/kubernetes/pull/114904), [@TommyStarK](https://github.com/TommyStarK)) [SIG Node] [sig/node]
- Kubelet: `fsquota` のモニタリングが有効な時、 `ConfigMaps` のレンダリングが停止するバグを修正 ([#112624](https://github.com/kubernetes/kubernetes/pull/112624), [@pacoxu](https://github.com/pacoxu)) [sig/storage,sig/node]
- 破壊的変更の可能性 - Windows における統計収集の頻度を1秒から10秒に変更 ([#116546](https://github.com/kubernetes/kubernetes/pull/116546), [@marosset](https://github.com/marosset)) [SIG Node and Windows] [sig/node,sig/windows]
- key encipherment の利用に関する API validation を緩和し、 kubelet が指定された使い方をするようになった ([#111660](https://github.com/kubernetes/kubernetes/pull/111660), [@pacoxu](https://github.com/pacoxu)) [sig/node,sig/api-machinery,sig/auth,sig/apps]
- Windows 環境において、複数のプロセッサグループがある際の CPU usage が正しく計算されるようになった ([#110864](https://github.com/kubernetes/kubernetes/pull/110864), [@claudiubelu](https://github.com/claudiubelu)) [SIG Node, Testing and Windows] [sig/node,sig/windows,sig/testing]

### Other (Cleanup or Flake)

- Node-local kubelet `podresource` API における基本的な DoS 防止を実装 ([#116459](https://github.com/kubernetes/kubernetes/pull/116459), [@ffromani](https://github.com/ffromani)) [SIG Node and Testing] [sig/node,sig/testing]
- FormatMap の性能を最悪ケースについて2倍、4倍程度改善 ([#112661](https://github.com/kubernetes/kubernetes/pull/112661), [@aimuz](https://github.com/aimuz)) [SIG Node] [sig/node]
- Kubelet: deprecated flag `--container-runtime` を削除 [#114017](https://github.com/kubernetes/kubernetes/pull/114017), [@calvin0327](https://github.com/calvin0327)) [SIG Cloud Provider and Node] [sig/node,sig/cloud-provider]
- Kubelet: deprecated flag `--master-service-namespace` を削除 ([#116015](https://github.com/kubernetes/kubernetes/pull/116015), [@SataQiu](https://github.com/SataQiu)) [sig/node]
- AWS kubelet credential provider を削除。代わりに、 `ecr-credential-provider` という名前の external kubelet credential provider binary を利用してください。([#116329](https://github.com/kubernetes/kubernetes/pull/116329), [@dims](https://github.com/dims)) [SIG Node, Storage and Testing] [sig/storage,sig/node,sig/testing]
- `CSIInlineVolume`, `CSIMigration`, `DaemonSetUpdateSurge`, `EphemeralContainers`, `IdentifyPodOS`, `LocalStorageCapacityIsolation`, `NetworkPolicyEndPort`, `StatefulSetMinReadySeconds` が v1.25 で GA していたが、feature gate が削除された。([#114410](https://github.com/kubernetes/kubernetes/pull/114410), [@SataQiu](https://github.com/SataQiu)) [SIG Node] [sig/node]