Kubernetes 1.29: SIG Cluster Lifecycle の変更内容

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

久しぶりに「Urgent Upgrade Notes」に登場してびっくりです。

## 重大なアップグレードに関する警告 (Urgent Upgrade Notes)

### `kubeadm upgrade plan --config` の振る舞いの変更 ([#120788](https://github.com/kubernetes/kubernetes/pull/120788), [@chendave](https://github.com/chendave))

`kubeadm upgrade plan --config` で指定するコンフィグ中で `kube-proxy` と `kubelet` のコンポーネント設定を受け付けなくなりました。

上記の振る舞いはアップグレードのプラン中にクラスタに保存されているこれらのコンポーネントの設定を手動でバージョンマイグレーションする必要があるかどうかを判断するためだけに使われていたため削除されたようです。

この変更は`kubeadm` の設定ファイル v1beta4 で導入される予定の`UpgradeConfiguration`/`ResetConfiguration` のための下準備のようです。今までは、メインのサブコマンドであるinitおよびjoin用の設定ファイル　(`InitConfiguration`/`JoinConfiguration`) は定義されていたものの、残りのupgradeおよびresetのための設定が定義されていなかったため、専用に用意することになったようです。

コンポーネントの設定をマイグレーションするかどうかの判断は `UpgradeConfiguration` でされるようになるのかもしれません。

### `admin.conf` の権限の変更 ([#121305](https://github.com/kubernetes/kubernetes/pull/121305), [@neolit123](https://github.com/neolit123))

`admin.conf` とは別に、独立した `super-admin.conf` ファイルがデプロイされるようになりました。

それに伴い、それぞれの設定ファイル中の「認可」で利用されるユーザグループの変更がありました。

| 設定ファイル | ユーザグループ | 権限 | 備考 |
|---|---|---|---|
| `admin.conf` | `kubeadm:cluster-admins` | `cluster-admin` | 今までは `system:masters` だった |
| `super-admin.conf` | `system:masters` | 組み込み権限 | 新設 |


`admin.conf` にはこれまで `system:masters` のGroupの権限を付与されていましたが、それは必要な権限よりも大きな権限であったため、変更されたようです。

- See: [Feature Reqest: Don't bind the admin.conf user to system:masters #2414](https://github.com/kubernetes/kubeadm/issues/2414)

:::note info
`system:masters` は単に `cluster-admin` にバインディングされているだけではなく、apiserver で全てのRBACをバイパスするようハードコードされている **超強力** なユーザグループなので、軽々しく使わない方が良さそうです。

- See: [kubernetes/pkg/registry/rbac/escalation_check.go](https://github.com/kubernetes/kubernetes/blob/b9e0714722a2d6456822a6b4b8131ab8b174ffac/pkg/registry/rbac/escalation_check.go#L38)
:::

この変更に伴う、`init`, `upgrade`, `join` および `certs renew` への影響は以下の通りです。

- `init`: `kubeadm init phase kubeconfig all` または単に `kubeadm init` で `super-admin.conf` を生成するようになりました。
- `upgrade`: このバージョンの `kubeadm` では、`super-admin.conf` および `admin.conf` をセットアップします。また、以降の `kubeadm` では、`super-admin.conf` が存在し、アップグレード時の更新が無効になっていない場合に `super-admin.conf` を更新します。
- `join`: より少ない特権 User を持つ `admin.conf` ファイルのみを生成するようになりました。
- `certs renew`: ファイルが存在する場合、`super-admin.conf` の証明書を1年間更新します。

## 種類別の変更 (Changes by Kind)

### 廃止予定 (Deprecation)

- None

### APIの変更 (API Change)

- None

### 機能 (Feature)

- `kubeadm`: `CertificateKey` が正当なhex encodedなAESキーであることを検証するバリデーションを追加しました。 ([#120064](https://github.com/kubernetes/kubernetes/pull/120064), [@SataQiu](https://github.com/SataQiu))

- `kubeadm`: `kubeadm certs renew` にて、証明書の組織の更新をサポートしました。 ([#121841](https://github.com/kubernetes/kubernetes/pull/121841), [@SataQiu](https://github.com/SataQiu))

:::note info
`admin.conf` の権限の変更 [#121305](https://github.com/kubernetes/kubernetes/pull/121305) により、証明書のサブジェクトに含まれる組織を変更した、ということのようです。
:::

- `kubeadm`: `EtcdLearnerMode` のフィーチャーゲートがベータ機能になりました。`etcd` メンバーへの追加時の "Learner mode" がデフォルトで有効化されます。 ([#120228](https://github.com/kubernetes/kubernetes/pull/120228), [@pacoxu](https://github.com/pacoxu))

:::note info
Learner については、[etcd の Learner とは?](https://qiita.com/kkohtaka/items/b7b0475428821b22814a) を参照。
:::

- `kubeadm`: 設定をフラグと設定ファイルからマージするためのフィーチャーゲートである `MergeCLIArgumentsWithConfig` を有効化しました。この値が設定されていなかった場合は、`--ignore-preflight-errors` フラグがCLIで指定されていた場合、設定ファイルのその値は無視されます。 ([#119946](https://github.com/kubernetes/kubernetes/pull/119946), [@chendave](https://github.com/chendave))

:::note info
リリースノートの英語では何を言ってるのかさっぱりわからなかったのですが、`ignorePreflightErrors` に関する振る舞いが変わるPRに対するリリースノートでした。
とりあえず色々調べてコメント書いていたら途中でリバートされていることに気づきました。最悪。
- See: [Revert "kubeadm: FeatureGate MergeCLIArgumentsWithConfig is added for ignorePreflightErrors"](https://github.com/kubernetes/kubernetes/pull/121290)
:::

- `kubeadm` のバージョンよりも3バージョン古い `kubelet` のデプロイができるようになりました。これは最近の SIG Architecture による control plane と kubelet のサポートされるバージョンギャップを拡張する変更と揃えた修正です。`init`, `join` と `upgrade` のサブコマンドでこの `kubelet` のバージョンギャップが許容されます。`kubeadm` ユーザーが `kubeadm` バージョンよりも古いcontrol planeのバージョンを適用した場合 (最大 N-1) 、`kubelet` と control plane間のギャップは最大 N-2 になることに注意してください。 ([#120825](https://github.com/kubernetes/kubernetes/pull/120825), [@pacoxu](https://github.com/pacoxu))

### ドキュメンテーション (Documentation)

- None

### 失敗するテスト (Failing Test)

- None

### バグ、もしくはリグレッション (Bug or Regression)

- `kubeadm`: `reset` もしくは `join` 時のデフォルトコンポーネント設定の表示はサポートされなくなりました。 ([#119346](https://github.com/kubernetes/kubernetes/pull/119346), [@chendave](https://github.com/chendave))

- `kubeadm`: `etcd/healthcheck-client` の証明書のサブジェクトから `system:masters` の組織が削除されました。 ([#119859](https://github.com/kubernetes/kubernetes/pull/119859), [@SataQiu](https://github.com/SataQiu))

:::note info
今までヘルスチェック用の証明書に管理者権限があったの面白い。
:::

- v1.28 で json patchにおけるネガティブインデックスの指定のハンドリングに関してリグレッションが生じていた問題を修正しました。 ([#120327](https://github.com/kubernetes/kubernetes/pull/120327), [@liggitt](https://github.com/liggitt))

:::note info
json patch の `replace` 時に以下のようにネガティブインデックスが指定できなくなっていたようです。

```bash
kubectl patch myobject --type='json' -p '[{"op":"replace","path":"/spec/somearray/-1","value":"foo"}]'
```
:::

- いくつかの不正、および重要でないログの呼び出しを修正しました。 ([#121249](https://github.com/kubernetes/kubernetes/pull/121249), [@pohly](https://github.com/pohly))

- `kubeadm`: `apiserver-kubelet-client.crt` の証明書のサブジェクトの組織を `system:masters` からより権限の少ないグループである `kubeadm:cluster-admins` に変更しました。 ([#121837](https://github.com/kubernetes/kubernetes/pull/121837), [@neolit123](https://github.com/neolit123))

- `kubeadm`: `--config` フラグが渡されると例えそのサブコマンドで不要だったとしてもCRIの検出が毎回行われていた問題を修正しました。 ([#120828](https://github.com/kubernetes/kubernetes/pull/120828), [@SataQiu](https://github.com/SataQiu))

- `kubeadm`: `etcd` のメンバーがすでに外れていた場合の `nil` ポインターを修正しました。 ([#119753](https://github.com/kubernetes/kubernetes/pull/119753), [@pacoxu](https://github.com/pacoxu))

- `kubeadm`: `--image-repository` フラグがいくつかの `init` のサブコマンドで指定できなかった問題を修正しました。 ([#120072](https://github.com/kubernetes/kubernetes/pull/120072), [@SataQiu](https://github.com/SataQiu))

- `kubeadm`: `systemd` サービスが存在するかどうかをチェックするロジックを改善しました。 ([#120514](https://github.com/kubernetes/kubernetes/pull/120514), [@fengxsong](https://github.com/fengxsong))

- `kubeadm`: static podのデコードに `UniversalDesirializer` を使うようになりました。 ([#120549](https://github.com/kubernetes/kubernetes/pull/120549), [@pacoxu](https://github.com/pacoxu))

### その他 (Cleanup or Flake)

- `kubeadm`: `apiserver-etcd-client` の証明書のサブジェクトから `system:masters` の組織を削除しました。 ([#120521](https://github.com/kubernetes/kubernetes/pull/120521), [@SataQiu](https://github.com/SataQiu))

- `kubeadm`: `init` の `certs` フェーズはアルファ機能でなくなったため、`kubeadm init phase certs`コマンドのヘルプ画面に表示されていた免責事項を削除しました。 ([#121172](https://github.com/kubernetes/kubernetes/pull/121172), [@SataQiu](https://github.com/SataQiu))

- `kubeadm` swap を検出した際の警告を更新しました。Linuxにおいて swap が有効化されていた際、`kubeadm` は swap が cgroup v2 でのみサポートされており、ベータ機能であるがデフォルトで無効化されていることを警告します。 ([#120198](https://github.com/kubernetes/kubernetes/pull/120198), [@pacoxu](https://github.com/pacoxu))