Kubernetes 1.28: SIG-API Machineryの変更内容

# はじめに

Kubernetes v1.28 がリリースされました 🎉

2019年から動きのあったSidecarsがついに入りました! (KEP番号も700番台) 前バージョンのv1.27のIn-Place Resizingにつづき、Podまわりの大きな変更が続いて楽しいですね。CEL(Common Expression Language)まわりも色々改善が続いており、AdmissionWebhookMatchConditionsはデフォルト有効になりました。Workaroundや運用で対処していたようなSidecarしかり、(SIG API外ではあるものの)Non Graceful Node Shutdownなどが標準機能として入ってきています(おそらく次バージョンなPreStop Hookも期待)。Kubernetesが成熟してきた感がありますね。

それでは、API周りの変更を担当するSIG-API Machineryの変更点を[CHANGELOG](https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.28.md)からピックアックします。(📝がついた文章は、CHANGELOGの公式の内容ではなく筆者の補足です)

> SIG, KEPについては[こちら](https://qiita.com/Ladicle/items/24cff72f5e8f4bd293a6)を参照ください。


# :earth\_asia: API Changes (API周りの変更)

-   Feature Gateの `AdmissionWebhookMatchCondition` がBetaに昇格しました。 ([#119380](https://github.com/kubernetes/kubernetes/pull/119380))
-   Feature Gateの `ValidtatingAdmissionPolicy` がBetaに昇格しました。デフォルト無効です。 ([#119409](https://github.com/kubernetes/kubernetes/pull/119409))
    -  :warning:  Betaになるとデフォルト有効になるケースが多いですが、ValidtaingAdmissionPolicyはデフォルト無効です。
-   APIグループの `ValidatingAdmissionPolicy` と `ValidatingAdmissionPolicyBinding` が `v1beta1` に昇格しました。 ([#118644](https://github.com/kubernetes/kubernetes/pull/118644))
-   `admissionregistration.k8s.io/v1alpha1.ValidatingAdmissionPolicy` に `namespaceParamRef` フィールドを追加しました。 ([#119215](https://github.com/kubernetes/kubernetes/pull/119215))
-   ValidatingAdmissionPolicyのCEL expressionによるNamespaceアクセスをサポートしました。 `namespaceObject` 変数から設定できます。 ([#118267](https://github.com/kubernetes/kubernetes/pull/118267))
-   Job APIに `podReplacementPolicy` と terminating フィールドを追加しました。 ([#119301](https://github.com/kubernetes/kubernetes/pull/119301))
    -   📝 着々とMLワークロードでもJobがうまく使えるようにするための変更が続いていますね。実際どう使えるかについては公式ブログの [Kubernetes 1.28: Improved failure handling for Jobs | Kubernetes](https://kubernetes.io/blog/2023/08/21/kubernetes-1-28-jobapi-update/) で解説されています。
-   CRD Validation Ruleに `reason` と `fieldPath` フィールドを追加しました。これにより、バリデーションの失敗理由を定義できます。 ([#118041](https://github.com/kubernetes/kubernetes/pull/118041))
-   Alpha機能の `CRDValidationRatcheting` を追加しました。PATCH/UPDATE Validation Ratcheting中に変更していない更箇所で発生したOpenAPI Schemaのバリデーションエラーを無視します。 ([#118990](https://github.com/kubernetes/kubernetes/pull/118990))
-   バージョン差や該当のAPIがローカルのAPIサーバで無効化されている場合に、ピアのAPIサーバにリクエストをプロキシする機能をサポートしました。 ([#117740](https://github.com/kubernetes/kubernetes/pull/117740))
    -   📝 [Kubernetes 1.28: A New (alpha) Mechanism For Safer Cluster Upgrades | Kubernetes](https://kubernetes.io/blog/2023/08/28/kubernetes-1-28-feature-mixed-version-proxy-alpha/) のリクエストフロー図がとても分かりやすかったです。
-   新しくFeature Gateに"SidecarContainers"が追加されました。この機能では、sidecar containerという他のコンテナの前に起動する新しいタイプのinitコンテナが導入されました。ただし、削除時はPodのライフサイクルの最後まで動作し続け、また、Podの終了処理はブロックしません。([#116429](https://github.com/kubernetes/kubernetes/pull/116429))
    -   📝 sidecarをinitコンテナとして起動する機能が追加されました。Sidecar導入モチベーションの一つである、コンテナ単位でRestartPolicyを制御や、起動時の順番制御ができるようになりました(終了時の順番制御はまだできません)。Sidecar ContainersについてはtoVersusさんのスライドが詳しいです。 [KEP から眺める Kubernetes -  KEP-753: Sidecar Containers (P13)](https://speakerdeck.com/toversus/kep-karatiao-meru-kubernetes?slide=13)
-   `client-go`: reflectorキャッシュが更新が低頻度な大量のオブジェクトをwatchする際のメモリ使用量を改善しました。 ([#113362](https://github.com/kubernetes/kubernetes/pull/113362))
-   `kube-controller-manager`: Feature Gateの `LegacyServiceAccountTokenCleanUp` がAlphaに追加されました(デフォルト無効です)。有効の場合、 `legacy-service-account-token-cleaner` コントローラが `--legacy-service-account-token-clean-up-period` (デフォルト1年)で指定された期間に渡って未使用かつ、ServiceAccountオブジェクトの `.secrets` リストから参照されており、どのPodからも参照されていないのService Account Token Secretを削除します。 ([#115554](https://github.com/kubernetes/kubernetes/pull/115554))
-   API Priority and Fairness機能において、 制限を免除されたPriorityレベルがNominalと貸与可能な同時実行数を受け渡し可能になりました。詳しくは [KEP-1040: P&F (Dispatching)](https://github.com/kubernetes/enhancements/tree/master/keps/sig-api-machinery/1040-priority-and-fairness#dispatching) を参照してください。 ([#118782](https://github.com/kubernetes/kubernetes/pull/118782))


## CEL系の変更まとめ

CEL系の変更が増えるに伴い、KEP番号とFeature名の迷子になることも増えてきたので表にまとめました。デフォルト値とステージについては、今回のv1.28の状態について記載しています。

| KEP                               | Feature Name                        | Default | Stage | Since | Description                                                                                                                                                                                                                                                                             |
|:----------------------------------|:------------------------------------|:--------|:------|------:|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| [2876](https://kep.k8s.io/2876)   | CustomResourceValidationExpressions | true    | Beta  |  1.25 | CELを使って柔軟なCRのValidationを定義する機能。Validation失敗時のReasonを設定するフィールドが追加された。1.29でGA予定。                                                                                                                                                                 |
| [3488](https://kep.k8s.io/3488)   | ValidatingAdmissionPolicy           | **false**| Beta  |  1.28 | Validating Webhook無しにリソースのValidationを定義できるポリシ(`ValidatingAdmissionPolicy`)と、そのポリシをリソースに紐づける(`ValidatingAdmissionPolicyBinding`)を追加する機能。Betaに昇格、namespaceObject変数の利用とparamRefと排他なnamespaceParamRefフィールドが利用可能になった。 |
| [3716](https://kep.k8s.io/3716)   | AdmissionWebhookMatchConditions     | true    | Beta  |  1.28 | AdmissionWebhookでも `matchConditions` フィールドを使ってCELによる柔軟なリソースとWebhookの紐づけを可能にする機能。Betaに昇格した。                                                                                                                                                     |
| [4008](https://kep.k8s.io/4008)   | CRDValidationRatcheting             | false   | Alpha |  1.28 | リソースのPATCH/UPDATE時に、変更していないフィールドのバリデーションエラーを無視するための機能。Alphaとして新しく追加された。                                                                                                                                                           |


# :sparkle: Features (機能追加)

-   ValidatingAdmissionPolicyの `messageExpression` フィールドが、解決した型をチェックするようになりました。 ([#119209](https://github.com/kubernetes/kubernetes/pull/119209))
-   ValidatingAdmissionPolicyの型チェックで `authorizer` 変数を正しく扱えるようになりました。 ([#118540](https://github.com/kubernetes/kubernetes/pull/118540))
-   `validatingwebhookconfigurations` と `mutatingwebhookconfigurations` リソースに対して、それぞれ `vwc` と `mwc` の省略名が導入されました。 ([#117535](https://github.com/kubernetes/kubernetes/pull/117535))
    -   📝 ~~補完も設定していない環境でkubectlを直接叩く時、両リソースの名前が長すぎて面倒だったので地味にうれしいですね!~~ とか思っていたら, official shortnameの追加方針の議論の中でこの変更はRevertされていました。shortnameが衝突した場合の挙動が予測不可能となるため、組み込みリソースへのshortname追加は原則禁止されました。この議論の中で方針についての[ドキュメント](https://github.com/kubernetes/community/pull/7299/files?short_path=54ad8ee#diff-54ad8eef5360e2f07b362fa109bc82f60bf9ec318130b56a4735a7403326d9e2)も追加されています。 (thanks [@toVersus](https://twitter.com/toversus26/status/1696509247897608244?s=20)!)
-   オプションをサポートしました(詳しくは [CEL spec proposal 246](https://github.com/google/cel-spec/wiki/proposal-246))。この機能は今後のKubernetesリリース(おそらくv1.29)まで完全には有効化されませんが、ダウングレードにおける安全なロールバックをサポートするためにv1.28に追加されました。 ([#118339](https://github.com/kubernetes/kubernetes/pull/118339))
-   CELライブラリにKubernetes Quantitiesをサポートするための新しい機能が追加されました。 ([#118803](https://github.com/kubernetes/kubernetes/pull/118803))
    -   📝 メモリ `1.5G` 等のKubernetes QuantitiesをCELで使う用の拡張です。
-   Feature Gateに、APiサーバが一貫性のあるキャッシュからのリストを提供するための `ConsistentListFromCache` が追加されました。 ([#118508](https://github.com/kubernetes/kubernetes/pull/118508))
-   既存のPodが完全に終了するまで待機するための `PodRecreationPolicy` が実装されました。 ([#117015](https://github.com/kubernetes/kubernetes/pull/117015))
-   Feature Gateの `LegacyServiceAccountTokenTracking` がGAに昇格しました。自動生成されたSecretベースのService Account Tokenが使われた場合、警告がでるようになります。また、該当のSecretには、最終利用時間がタイムスタンプとしてラベルに付与されます。(ラベルのキーは `kubernetes.io/legacy-token-last-used` です) ([#117591](https://github.com/kubernetes/kubernetes/pull/117591))
-   1つのリクエストを認可する過程で、ValidatingAdmissionPolicyプラグインは、一意な認可式ごとに1回以上の認証を行いません。同一の認可式は同じ評価を返します。 ([#116443](https://github.com/kubernetes/kubernetes/pull/116443))
-   APIサーバのデバッグエンドポイントである `/debug/api_priority_and_fairness/dump_requests` は、キューされたリクエストと同じように実行リクエストをダンプするように拡張されました。返却されるテーブルにStartTimeのカラムが追加されます。キューに入ったリクエストのStartTimeは"0001-01-01T00:00:00Z"です。実行リクエストは、-1のRequestIndexInQueueを持ちます。また、キューを持たないPriorityレベルのQueueIndexも-1になります。 ([#119009](https://github.com/kubernetes/kubernetes/pull/119009))
-   KubernetesはGo `1.20.6` でビルドされるようになりました。 ([#119324](https://github.com/kubernetes/kubernetes/pull/119324))
-   etcdのイメージが `3.5.9-0` に更新されました。 ([#117999](https://github.com/kubernetes/kubernetes/pull/117999))


# :bug: Bug or Regression (バグ修正)

-   CEL式内の `listOfStrings.join()` の結果に内部エラーが返る問題が修正されました。 ([#117593](https://github.com/kubernetes/kubernetes/pull/117593))
-   PriorityClassをそのスコープに持つResourceQuotaが不正に評価される問題が修正されました。 ([#117677](https://github.com/kubernetes/kubernetes/pull/117677))
-   `creationTimestamp: null` がEtcdへ不要な書き込みを発生させる問題が修正されました。 ([#116865](https://github.com/kubernetes/kubernetes/pull/116865))
-   `kube-apiserver` 起動時にCustom Resource用の `APIService` オブジェクトが削除・再生成される問題が修正されました。 ([#118104](https://github.com/kubernetes/kubernetes/pull/118104))
-   KubernetesのAPIサーバがAPIServiceを処理している時に発生するメモリリークが修正されました。 ([#117258](https://github.com/kubernetes/kubernetes/pull/117258))
-   Shared Informerの `Run()`, `SetTransform()`, `SetWatchErrorHandler()` 間における競合が解消されました。 ([#117870](https://github.com/kubernetes/kubernetes/pull/117870))
-   `OpenAPI` contentを提供する際の競合が解消されました。 ([#117705](https://github.com/kubernetes/kubernetes/pull/117705))
-   APIサーバがimpersonated UIDを認証Webhookに送信していない問題を修正しました。 ([#116681](https://github.com/kubernetes/kubernetes/pull/116681))
-   戦略的マージパッチで存在しないフィールドを指定した場合、リソースにpath directiveが含まれてしまう問題が修正されました。 ([#117568](https://github.com/kubernetes/kubernetes/pull/117568))
-   特定のフィールドの戦略的マージパッチで、$deleteFromPrimitiveList directiveを利用した場合、指定した値ではない他の値が削除されてしまう問題が修正されました。 ([#110472](https://github.com/kubernetes/kubernetes/pull/110472))
-   コンポーネントステータスのため、HTTP経由で呼び出しているEtcdのHealthエンドポイントは、Kubernetesにwatch starvationと他の `kube-apiserver` のprobeによる非一貫性の問題があり、修正されました。 ([#118460](https://github.com/kubernetes/kubernetes/pull/118460))
-   `openapi/v3` における `apiregistration.k8s.io` の発見しやすさが修正されました。 ([#118879](https://github.com/kubernetes/kubernetes/pull/118879))
-   Reflectorのexponential backoffが改善されました。ThrottlingリクエストによるKubernetes APIサーバの負荷が大幅に削減されます。 ([#118132](https://github.com/kubernetes/kubernetes/pull/118132))
-   OpenAPI v2がどのクライアントからもアクセスされていない場合、 `api-server` のCPUとメモリ消費量が削減されます。また、多くのCRDsがインストールされているAPIサーバのパフォーマンスも向上します。 ([#118212](https://github.com/kubernetes/kubernetes/pull/118212))
-   APIレスポンスのcontent-typeパラメータ拡張を許容することで、client-goによる間違った"Unknown discovery response content-type"エラーを解決しました。 ([#117571](https://github.com/kubernetes/kubernetes/pull/117571))
-   終了中のNamespaceで発生したFailed eventは見えなくなります。 ([#114849](https://github.com/kubernetes/kubernetes/pull/114849))
-   `kube-apiserver` の(残り1つでも)graceful shutdown中にエンドポイントが削除されるようになります。 ([#116685](https://github.com/kubernetes/kubernetes/pull/116685))
-   `wait.PollUntilContextTimeout` 関数は、immediateがtrueの場合、conditionは待機前に呼び出されます。また、contextがキャンセルされるかどうかに関係なく、conditionは少なくとも1回は呼び出されることが保証されます。 ([#118686](https://github.com/kubernetes/kubernetes/pull/118686))


# :microscope: Others (その他修正)

-   k8s.io/code-generatorの `generate-groups` と `generate-internal-groups.sh` を使っているプロジェクトでは、新しい、よりシンプルなスクリプト(`kube_codegen.sh`)が使えます。古いスクリプトは非推奨になりますが、そのまま残ります。 ([#117262](https://github.com/kubernetes/kubernetes/pull/117262))
-   OpenAPI proto deserializations では、gnosticライブラリではなく `gnostic-models` を使ってください。 ([#118384](https://github.com/kubernetes/kubernetes/pull/118384))
-   CustomResourceDefinitionsの `OpenAPI v2` fetchingが修正されました。CRDはlazyにaggregateされるようになりました。これにより、大くのCRDがインストールされるときのリソース使用量が改善されます。結果として、OpenAPIへの初回リクエストは遅くなることがあります。 ([#118808](https://github.com/kubernetes/kubernetes/pull/118808))
-   主にCPUリソース使用量を50%削減するため、 `OpenAPI v2` の仕様を50%ほど縮小しました。 ([#118204](https://github.com/kubernetes/kubernetes/pull/118204))
-   eventリソースを取得する際に、 `reportingController` と `reportingInstance` フィールドが値をもつようになります。 ([#116506](https://github.com/kubernetes/kubernetes/pull/116506))
-   `kube-apiserver`: キャッシュ上の `GetList` を実行する際のメモリ消費量が改善されました。 ([#116327](https://github.com/kubernetes/kubernetes/pull/116327))
-   `kube-controller-manager` と `cloud-controller-manager` のコントローラ名が変更されました。これは、 `--controllers` フラグからon/offできます(e.g., `pod-garbage-collector-controller`)。古い名称(e.g., `podgc`)は新しい名前にaliasできます。([#115813](https://github.com/kubernetes/kubernetes/pull/115813))
    -   📝 コントローラ名に一貫性がなかったのでcontextual loggingに移行するこのタイミング修正したようです。以前は名前にcontrollerが入っていないものもありましたが、新名称は `<name>-controller` に統一されています。名称の定義一覧は[こちら](https://github.com/atiratree/kubernetes/blob/85d9339ef8f34d1348a75dfd21e643fdd1bcfec9/cmd/kube-controller-manager/names/controller_names.go#L50-L88)を参照してください。