Kubernetes 1.30: SIG Cluster Lifecycle の変更内容

[Kubernetes 1.30 の CHANGELOG](https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.30.md) から SIG Cluster Lifecycle の取り組みについてにピックアップしました。

- [kubeadm configuration v1beta4](https://github.com/kubernetes/kubeadm/issues/2890) の実装が進んでいるようですが、まだ利用できるわけではないためリリースノートには影しか見えません。
- [kubeadm: machine readable output](https://github.com/kubernetes/enhancements/issues/2504) というKEPが粛々と進捗しているようです。全てのCLIが YAML か JSON を出力するようになれば世の中平和になると思うのですが、その世界が来る前に AI がサクッとなんでも処理しそうですね。

## Changes by Kind

### Deprecation

- None

### API Change

- None

### Feature

- kubeadm: `kubeadm reset`時に、アンマウントに失敗した際のエラーハンドリングを改善しました。`/var/run/kubelet`配下のディレクトリのアンマウントに失敗した際、kubeadmは警告を表示してディレクトリのクリーンアップを続行するのではなく、エラーを投げるようになりました。このような状況下では、問題を調査して手動で解決することが推奨されます。その後、`kubeadm reset`を再度呼び出してクリーンアップを完了させることができます。([#122530](https://github.com/kubernetes/kubernetes/pull/122530), [@neolit123](https://github.com/neolit123)) [sig/cluster-lifecycle]

:::note info
`ResetConfiguration` に アンマウントの際、`umount2` に渡すフラグを指定できるフィールド `UnmountFlags` が追加されていました。
`ResetConfiguration` 自体は kubeadm configuration v1beta4 から利用できるようになるようで、v1beta4の進捗は以下のissueでトラックすることができます。

- https://github.com/kubernetes/kubeadm/issues/2890
:::

- kubeadm: `kubeadm certs check-expiration` コマンドにおいて、`-o yaml`および`-o json`オプションによる機械可読な出力のサポートが追加されました。この変更は、新しいAPIでである `output.kubeadm.k8s.io/v1alpha3 CertificateExpirationInfo` で導入されました。既存の非構造化フォーマットは維持されますが出力APIバージョン `v1alpha2` は現在非推奨となり、将来のリリースで削除される予定です。`v1alpha3` の使用に移行してください。([#123372](https://github.com/kubernetes/kubernetes/pull/123372), [@carlory](https://github.com/carlory)) [sig/cluster-lifecycle]

- kubeadm: `WaitForAllControlPlaneComponents`フィーチャーゲートが追加されました。これにより、`kubeadm init` または `kubeadm join --control-plane` を実行する際に、すべてのコントロールプレーンコンポーネントが準備完了になるのを待つようにkubeadmに指示することができます。従来は、kubeadmは `kube-apiserver` のみを待っていました。`kubeadm join` のワークフローには、新しい実験的フェーズ`wait-control-plane` が追加されました。このフェーズは、`WaitForAllControlPlaneComponents` がGAになった際に非実験的フェーズとされます。それに伴い、`kubeadm init` フェーズ`wait-control-plane`も`WaitForAllControlPlaneComponents` がGAになった時点で利用可能となります。これらのフェーズは、ユーザーがコントロールプレーンコンポーネントを待たないことを選択した場合にスキップすることができます。([#123341](https://github.com/kubernetes/kubernetes/pull/123341), [@neolit123](https://github.com/neolit123)) [sig/cluster-lifecycle]

- kubeadmは、`upgrade plan` を実行する際に、アップグレードが必要なすべての `kubelet` およびノードを表示するようになりました。
([#123578](https://github.com/kubernetes/kubernetes/pull/123578), [@carlory](https://github.com/carlory)) [sig/cluster-lifecycle]

### Documentation

- None

### Failing Test

- None

### Bug or Regression

- kubeadmの1.27.0以降のリグレッションを修正しました: `kubelet` のパッチ設定はもはや `kube-system/kubelet-config` ConfigMap にアップロードされなくなります。
([#123093](https://github.com/kubernetes/kubernetes/pull/123093), [@SataQiu](https://github.com/SataQiu)) [sig/cluster-lifecycle]

:::note info
本来ならばノードのみに影響を与えるパッチが誤ってアップロードされてしまうという問題で、
[kubeadm: fix a bug where the uploaded kubelet configuration in kube-system/kubelet-config ConfigMap does not respect user patch #115575](https://github.com/kubernetes/kubernetes/pull/115575) で導入されてしまったようです。
:::

- `EnsureAdminClusterRoleBindingImpl` におけるエラーハンドリングを修正しました。([#122893](https://github.com/kubernetes/kubernetes/pull/122893), [@danwinship](https://github.com/danwinship)) [sig/cluster-lifecycle]

:::note info
client-goでは、エラー時に `nil` ではなく空の構造体が返ってくる実装になっているのですが、`fakeClient` においては `nil` がが返ってきていたため、ユニットテストと実際の動作時で乖離があったようです。
:::

- kubeadmにおいて、新しい出力API `output.kubeadm.k8s.io/v1alpha3` で、`kubeadm upgrade plan ... -o yaml|json`を呼び出す際に使用される`UpgradePlan`構造体が変更され、複数の利用可能なアップグレードのリストを含むようになりました。([#123461](https://github.com/kubernetes/kubernetes/pull/123461), [@carlory](https://github.com/carlory)) [sig/cluster-lifecycle]

- kubeadm: `kubeadm upgrade plan -o yaml|json` で不要な出力が含まれていたバグを修正し、コンポーネント設定情報が欠けていた問題を解決しました。 ([#123492](https://github.com/kubernetes/kubernetes/pull/123492), [@carlory](https://github.com/carlory)) [sig/cluster-lifecycle]

:::note info
標準出力の最初に必ず「[upgrade] Running cluster health checks」という文字列が出力されていたため、せっかく `YAML/json` で出力されてもパースに失敗してしまう、という問題を修正したようです。
:::

- Etcd: `v3.5.11` にアップデートしました。([#122393](https://github.com/kubernetes/kubernetes/pull/122393), [@mzaian](https://github.com/mzaian)) [sig/api-machinery,sig/cluster-lifecycle,sig/testing,sig/cloud-provider,sig/etcd]

- kubeadmで、コントロールプレーンノードに対する `kubeadm upgrade node` コマンドで `--rootfs` グローバルフラグが機能しなかったバグを修正しました。([#123077](https://github.com/kubernetes/kubernetes/pull/123077), [@neolit123](https://github.com/neolit123)) [sig/cluster-lifecycle]

- `kubeadm init` において、ユーザーが指定した `--kubeconfig` ファイルが無視されるリグレッションを修正しました。 ([#122735](https://github.com/kubernetes/kubernetes/pull/122735), [@avorima](https://github.com/avorima)) [sig/cluster-lifecycle]

- kubeadm: `kube-system/kubeadm-config` ConfigMapに保存されている `ClusterConfiguration` で、`kube-apiserver` のデフォルトフラグ値 `--authorization-mode=Node,RBAC` をアップロードしないようにしました。`Node,RBAC` は既に `kubeadm` のデフォルト値であるため、この操作は冗長です。 ([#123555](https://github.com/kubernetes/kubernetes/pull/123555), [@neolit123](https://github.com/neolit123)) [sig/cluster-lifecycle]

- kubeadm: `kubeadm` アップグレード中に、新しいデバイスをマウントし、`/etc/kubernetes`（またはそのサブディレクトリ）へのシンボリックリンクを作成して、`kubeadm` がその情報をマウントされたデバイスに保存できるようにすることができないバグを修正しました。([#123406](https://github.com/kubernetes/kubernetes/pull/123406), [@SataQiu](https://github.com/SataQiu)) [sig/cluster-lifecycle]

:::note info
アップグレード中、static podのマニフェストは `TempDirForKubeadm` にバックアップされるのですが、この値は `/etc/kubernetes/tmp` にハードコードされており変更できないようです。

別の場所に保存したい場合はシンボリックリンクを作成する必要があるのですが、別のデバイスへのシンボリックリンクはバグがあって利用できなかったようです。
:::

- kubeadm: `kubeadm init` の `kubelet-finalize` フェーズは、`kubelet` の `kubeconfig` に特定の認証情報が必要なくなりました。 ([#123171](https://github.com/kubernetes/kubernetes/pull/123171), [@vrutkovs](https://github.com/vrutkovs)) [sig/cluster-lifecycle]

- `CVE-2024-24786` を解決するため、 `google.golang.org/protobuf` を `v1.33.0` にアップデートしました。 ([#123758](https://github.com/kubernetes/kubernetes/pull/123758), [@liggitt](https://github.com/liggitt)) [sig/network,sig/storage,sig/node,sig/api-machinery,sig/cluster-lifecycle,sig/auth,sig/cli,sig/instrumentation,sig/architecture,sig/cloud-provider]

- kubeadam: "structured authz" `--authorization-config` を設定時、デフォルトの `--authorization-mode` を利用しません。([#123654](https://github.com/kubernetes/kubernetes/pull/123654), [@LiorLieberman](https://github.com/LiorLieberman)) [sig/cluster-lifecycle]

### Other (Cleanup or Flake)

- Etcd: `v3.5.11` にアップデートしました。
([#123150](https://github.com/kubernetes/kubernetes/pull/123150), [@bzsuni](https://github.com/bzsuni)) [sig/api-machinery,sig/cluster-lifecycle,sig/testing,sig/cloud-provider]

- `kubeadm completion` のエラーメッセージが、無効なシェルが指定された場合にサポートされているシェルタイプを表示するようになりました。
([#122477](https://github.com/kubernetes/kubernetes/pull/122477), [@SataQiu](https://github.com/SataQiu)) [sig/cluster-lifecycle]

- kubeadm: `init`、`join`、`upgrade`、`reset` のワークフロー中に、さまざまなAPIサーバーリクエストが再試行されるようにしました。この変更以前は、ConfigMapの作成や更新などの一部のAPIサーバーリクエストが「ワンショット」であり、APIサーバーが短時間接続を失った場合に失敗する可能性がありました。
([#123271](https://github.com/kubernetes/kubernetes/pull/123271), [@neolit123](https://github.com/neolit123)) [sig/cluster-lifecycle]

- kubeadm: `kubelet` と apiserver の /healthz エンドポイントが OK を返すのを待つ際の全体的なロジック、エラーハンドリング、および出力メッセージを改善しました。`kubelet` と apiserver のチェックは並行ではなく、順次（直列で）実行されるようになりました。
([#121958](https://github.com/kubernetes/kubernetes/pull/121958), [@neolit123](https://github.com/neolit123)) [sig/cluster-lifecycle]

- kubeadm: Pre-flight チェックでの `bridge-nf-call-iptables=1` と `bridge-nf-call-ip6tables=1` のチェックが削除されました。これは、すべてのネットワーク実装がこの設定を必要とするわけではないためです。コンテナをLinuxブリッジに接続するか他のメカニズムを使用するかに応じて、ネットワークプラグインがこの設定を正しく行う責任を負います。 ([#123464](https://github.com/kubernetes/kubernetes/pull/123464), [@SataQiu](https://github.com/SataQiu)) [sig/cluster-lifecycle]

- kubeadm: アップグレードの事前チェック中に実行される `upgrade-health-check` ジョブを自動的にクリーンアップするために `ttlSecondsAfterFinished` を使用しました。 ([#122079](https://github.com/kubernetes/kubernetes/pull/122079), [@carlory](https://github.com/carlory)) [sig/cluster-lifecycle]