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

# はじめに

Kubernetes v1.24がリリースされました :tada:

SIG-APIのメジャーな変更は、OpenAPI v3のエンドポイントが生えたことです。CRDは以前からOpneAPI v3(※初期はJSON Schema)でしたが、APIサーバのエンドポイントは `/openapi/v2` のままでした。2019年からv3にあげようというKEPが進められ、ついにv3へ上がりました。

他にも、小粒ですがいろいろ変更が入っています。例えば、[前リリースのv1.23](https://qiita.com/Ladicle/items/a37d040dddfd7a982fb2)で入ったCRDのCELによるバリデーションは着々と強化されています。まだアルファですが今後が楽しみな機能です。

それでは、API周りの変更を担当するSIG-API Machineryの変更点を[CHANGELOG](https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.24.md)からピックアックします。(:memo:がついた文章は、CHANGELOGの公式の内容ではなく筆者の補足です。また、:star:は[k8s変更点共有会](https://kubernetes-updates.connpass.com/event/246716/)でピックアップ予定の変更内容です。)

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


# :wastebasket: Deprecation (非推奨になったAPI)

-   :star: Kube-apiserver: lease reconcilerの方が好ましいため `--master-count` フラグと `--endpoint-reconciler-type=master-count` フラグが非推奨になりました。([#108062](https://github.com/kubernetes/kubernetes/pull/108062))
    -   :memo: Leaseがデフォルトになったのは1.11とかなり前なので私も存在を忘れていましたが、master-countフラグが非推奨になっていなかったようです。
-   Kube-apiserver: 1.20から非推奨となっていた `--address`, `--insecure-bind-address`, `--port`, `--insecure-port` フラグが削除されました。([#106859](https://github.com/kubernetes/kubernetes/pull/106859))
-   非推奨になっていたFeature Gateの `ValidateProxyRedirects` と `StreamingProxyRedirects` が削除されました。([#106830](https://github.com/kubernetes/kubernetes/pull/106830))
-   `client.authentication.k8s.io/v1alpha1` のExecCredential APIが削除されました。client-goのv1alpha1 APIのcredentialプラグインを利用している場合はv1 APIに移行してください。([#108616](https://github.com/kubernetes/kubernetes/pull/108616))
-   `node.k8s.io/v1alpha1` のRuntimeClass APIが非公開になりました。代わりにv1.20より有効な `node.k8s.io/v1` APIを利用して下さい。([#103061](https://github.com/kubernetes/kubernetes/pull/103061))
-   kube-controller-manager: v1.20から無効化されていた `--address` と `--port` フラグがv1.24で削除されました。([#106860](https://github.com/kubernetes/kubernetes/pull/106860))
-   :star: metadata.clusterNameフィールドが非推奨になりました。このフィールドは書き込み不可かつ、常に空の状態なため混乱を生んでいました。そのため、次のリリースで削除します。間違ってこのフィールドを利用しているclientを発見するために、本リリースではgo構造体の名前を変更しています。([#108717](https://github.com/kubernetes/kubernetes/pull/108717))


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

-   winkernelモード用に2つのオプションを追加しました。 `--forward-healthcheck-vip` フラグを有効にした場合、ヘルスチェックのトラッフィクの宛先はService VIPとなるので、kube-proxyのヘルスチェックServiceにフォワードされます。 `--root-hnsendpoint-name` はrootネットワークの名前空間用のhnsエンドポイントの名前を指定します。このオプションはロードバランサのパススルーを可能にします。例えば、GoogleのGCLBは正しくバックエンドサービスのヘルスチェックができます。この変更が未適応の場合、WindowsノードではこのようなロードバランサをUnhealthyと判定しません。([#99287](https://github.com/kubernetes/kubernetes/pull/99287))
-   :star: CELランタイムのコスト計算をCustomerResourceバリデーションに追加しました。ランタイムコストが予算を超過した場合、CustomerResourceのバリデーションで失敗します。([#108482](https://github.com/kubernetes/kubernetes/pull/108482))
    -   :memo: 今回もいくつかCommon Expression Language(CEL)まわりの変更が入っています。これは、カスタムリソースをCELをつかって(Admission Webhookを使わず)手軽にリッチなバリデーションできるようにしようというものです。この機能はv1.24現在アルファなため利用にはFeatureGateの有効化が必要です。詳しくは [KEP-2876](https://github.com/kubernetes/enhancements/tree/master/keps/sig-api-machinery/2876-crd-validation-expression-language#graduation-criteria)を参照してください。
-   CEL CRDバリデーションにおいて、既存のオブジェクト状態を `oldSelf` 識別子をつかって参照できるようになります。([#108073](https://github.com/kubernetes/kubernetes/pull/108073))
-   Network PolicyオブジェクトにStatusサブリソースを追加しました。([#107963](https://github.com/kubernetes/kubernetes/pull/107963))
-   CELバリデーションルールが `oldSelf` 識別子をサポートしていないスキーマを参照する場合、CRDの書き込みはバリデーションエラーになります。([#108013](https://github.com/kubernetes/kubernetes/pull/108013))
-   `--detect-local-mode` オプションの引数として `InterfaceNamePrefix` と `BridgeInterface` をサポートしました。また、新しい `--pod-interface-name-prefix` と `--pod-bridge-interface` フラグもkube-proxyに追加しています。([#95400](https://github.com/kubernetes/kubernetes/pull/95400))
-   CRDのdeepコピーはshwllowコピーの `JSONSchemaProps.XValidations` を含まなくなります。([#107956](https://github.com/kubernetes/kubernetes/pull/107956))
-   `fieldValidation=Strict` を指定したカスタムリソースのリクエストでは、non-strictリクエストと一致させるため、 `apiVersion` と `kind` が必須になりました。([#109019](https://github.com/kubernetes/kubernetes/pull/109019))
-   `PodOverhead` がGAになりました。([#108441](https://github.com/kubernetes/kubernetes/pull/108441))
-   x-kubernetes-validationsフィールドのOpenAPIのシリアライズが修正されました。([#107970](https://github.com/kubernetes/kubernetes/pull/107970))
-   kubectlのユーザーヘルプコマンドの可読性が向上しました。([#104736](https://github.com/kubernetes/kubernetes/pull/104736))
-   ClusterCIDRConfigにv1alpha1 networking APIが追加されました。([#108290](https://github.com/kubernetes/kubernetes/pull/108290))
-   ClusterCIDRConfigのv1alpha1 networking APIが削除されました。([#109436](https://github.com/kubernetes/kubernetes/pull/109436))
    -   :memo: 上記のPRがrevertされています
-   JobReadyPodsがベータに昇格し、デフォルトで有効になりました。([#107476](https://github.com/kubernetes/kubernetes/pull/107476))
    -   :memo: 前リリースにAlphaで入った機能で、デフォルト有効になりました。Jobの `.status.active` には `Pending` のJobも含まれていましたが、その場合コンテナイメージサイズが大きくPullに時間が掛かるコンテナであったり、クラスタのリソースが枯渇していてスケジューリングできなかったりする場合に正しく状況が把握できないという問題がありました。そこで、 `.status.ready` フィールドを追加することで、真にReadyなPodの数を把握できるようになりました。詳しくは[KEP-2879](https://github.com/kubernetes/enhancements/tree/master/keps/sig-apps/2879-ready-pods-job-status)を参照してください。
-   Kube-apiserver: `--audit-log-version` と `--audit-webhook-version` はデフォルト値の `audit.k8s.io/v1` のみをサポートするようになりました。 1.13 から廃止された v1alpha1 と v1beta1 監査ログバージョンは削除されています。([#108092](https://github.com/kubernetes/kubernetes/pull/108092))
-   Kube-apiserver: `metadata.selfLink` フィールドは kube-apiserver によって挿入されなくなりました。1.16で非推奨、1.20+からはデフォルトで挿入されなくなっています。([#107527](https://github.com/kubernetes/kubernetes/pull/107527))
-   Kubeletの外部クレデンシャルプロバイダはベータに昇格しました。Credential Provider PluginおよびCredential Provider Config APIはv1alpha1からv1beta1へ更新されています。APIの変更はありません。([#108847](https://github.com/kubernetes/kubernetes/pull/108847))
-   StatefulSetsのMaxUnavailableにおいて、1つ以上のPodを停止させることでRollingUpdateを高速化できるようになりました。RollingUpdate中に停止させたいPodの数は、maxUnavailableパラメータから設定できます。([#82162](https://github.com/kubernetes/kubernetes/pull/82162))
-   :star: OpenAPI V3がデフォルト有効になります。([#109031](https://github.com/kubernetes/kubernetes/pull/109031))
    -   :memo: "はじめに"でも触れたとおり、CRDではOpenAPI v3でスキーマ定義しています。しかし、k8sのエンドポイントではv2で公開されていたため、v3をv2に変換する過程で一部の情報が欠落するという問題がありました(e.g. `anyOf`)。詳しくは[KEP-2896](https://github.com/kubernetes/enhancements/tree/master/keps/sig-api-machinery/2896-openapi-v3)を参照してください。
-   Pod Affinity Namespace SelectorとCross-Namespace QuotaがGAに昇格しました。Feature Gateの `PodAffinityNamespaceSelector` はロックされ、1.26で削除予定です。([#108136](https://github.com/kubernetes/kubernetes/pull/108136))
-   IdentifyPodOSがベータ昇格しました。([#107859](https://github.com/kubernetes/kubernetes/pull/107859))
-   OpenAPIv3スキーマに根本的なエラーがある場合、x-kubernetes-validationsルールをスキップするようになりました。([#108859](https://github.com/kubernetes/kubernetes/pull/108859))
-   :star: gRPC proveのサポートがベータ版になりました。GRPCContainerProbe機能ゲートはデフォルトで有効です。([#108522](https://github.com/kubernetes/kubernetes/pull/108522))
    -   :memo: これは地味に嬉しい人が多いと思われる機能です。HTTPだけでなく、gRPCをつかっているアプリのHealthchekも直接できるようになりました。
-   CertificateSigningRequest `spec.expirationSeconds` APIフィールドがGAに昇格しました。Feature Gateの `CSRDuration` は常に有効となり、1.26で削除予定です。 ([#108782](https://github.com/kubernetes/kubernetes/pull/108782))
-   `ServerSideFieldValidation` がベータに昇格し、デフォルト有効になりました。kubectl 1.24以降では、この機能が有効な状態でAPIサーバに書き込むと、クライアント側ではなくサーバ側でバリデーションされます。([#108889](https://github.com/kubernetes/kubernetes/pull/108889))
    -   :memo: バグのため、[#109271](https://github.com/kubernetes/kubernetes/pull/109271)でRevertされています。1.25で再度ベータを目指すようです。
-   :star: <https://git.k8s.io/kubernetes/api/openapi-spec> でキャプチャされたStaticなOpenAPIファイルからEnumの定義を省略します。このファイルはAPIクライアントの生成に利用されています。生成されたクライアントでEnum(!=文字列)を使用すると、該当フィールドに将来的に追加される値との前方互換性が損なわれる可能性があります。詳しくは <https://issue.k8s.io/109177> を参照してください。([#109178](https://github.com/kubernetes/kubernetes/pull/109178))
    -   :memo: v1.24(後述の[#108898](https://github.com/kubernetes/kubernetes/pull/108898))でOpenAPIのEnum Typeがベータに昇格し、デフォルト有効になりました。しかし、この修正では後方互換性のために `hack/update-openapi-spec.sh` でFeatureGateのOpenAPIEnumsを無効化しています。これにより、 `api/openapi-spec/v3/*.json` に出力されるOpenAPIからEnumフィールドが除去されました。ここで触れられているIssueの#109177が解決するまで、OpenAPI Enum TypesはGAしない予定のようです。
-   コンテキストロギングの基盤が整いました(Feature Gateの実装 & JSONバックエンドの準備)。 ([#108995](https://github.com/kubernetes/kubernetes/pull/108995))
-   kube-controller-manager: 非推奨の'&#x2013;deployment-controller-sync-period'フラグが削除されました。([#107178](https://github.com/kubernetes/kubernetes/pull/107178))
-   CronJobに `timeZone` フィールドを追加しました。これにより、特定のタイムゾーンでCronJobを実行できます。([#108032](https://github.com/kubernetes/kubernetes/pull/108032))
    -   :memo: UTCでそろえているパターンが多いと思いますが、ついにCronJobのタイムゾーンを変更できるようになりました。
-   controller-managerによるEndpoint/ConfigMapの操作がleader-electionの優先順位に依存することを避けるため、デフォルトAPIのpriority-and-fairness設定を修正しました。([#106725](https://github.com/kubernetes/kubernetes/pull/106725))
-   `topologySpreadConstraints` は、トポロジードメインの最小数を制限する `minDomains` フィールドを含んでいます。([#107674](https://github.com/kubernetes/kubernetes/pull/107674))


# :sparkle: Features (機能追加)

-   :star: `SharedInformer` に `SetTransform` を追加し、保存前にオブジェクトを変換できるようになりました。([#107507](https://github.com/kubernetes/kubernetes/pull/107507))
    -   :memo: モチベーションとしては、client-goでオブジェクトをキャッシュしているコントローラ等で、使ってないフィールドを保存前に落とせるように追加されてます。Authorの人は、managedFieldが入ってからキャッシュのデータ量が増えすぎてOOM頻度が上がったのを回避したいようでした。
-   :star: SOCKS5プロキシ経由のkubectlコマンド(`kubectl exec` と `kubectl port-forward`)がサポートがされました。([#105632](https://github.com/kubernetes/kubernetes/pull/105632))
    -   :memo: [公式ドキュメント](https://kubernetes.io/docs/tasks/extend-kubernetes/socks5-proxy-access-api/)に使い方のページも追加されています。内容は、SSHトンネルをローカルとリモートのk8sクラスタ間に張り、SOCKS5プロキシ経由でkubectlを叩くチュートリアルです。
-   OpenAPI v3 Schemaのドキュメントを取得を可能にするため、 `DiscoveryClient` に `OpenAPIV3SchemaInterface` を追加しました。([#108992](https://github.com/kubernetes/kubernetes/pull/108992))
-   現在Alphaの `--subresource` フラグが、kubectlのget, patch, edit replaceコマンドに追加されました。これにより、statusやscaleサブリソースの取得や更新が可能になります。([#99556](https://github.com/kubernetes/kubernetes/pull/99556))
    -   :memo: 開発中のカスタムリソースのstatus修正したいときにkubectl経由でシュっとやりたかったので嬉しい。
-   x-kubernetes-valiation ルール内の文字列として定義されているCEL正規表現パターンは、CRDがcreate/updateされるときにコンパイルされます。正規表現コンパイル時のエラーは、CRDのcreate/update時のバリデーション検証エラーとしてレポートされます。([#108617](https://github.com/kubernetes/kubernetes/pull/108617))
-   CRD `x-kubernetes-validations` ルールが CEL 関数 `isSorted`, `sum`, `min`, `max`, `indexOf`, `lastIndexOf`, `find` と `findAll` をサポートしました。 ([#108312](https://github.com/kubernetes/kubernetes/pull/108312))
-   false/ignore - バリデーションを行わず、オブジェクトから無効なフィールドを取り除きます。([#108350](https://github.com/kubernetes/kubernetes/pull/108350))
-   Kube-apiserver: `status` や `scale` などのサブリソースが、表形式の出力をサポートしました。([#103516](https://github.com/kubernetes/kubernetes/pull/103516))
-   Kube-apiserver: リストをマージする際、Server Side Apply は既存のPersistedオブジェクトではなく、送信されたリクエストの順序を優先するようになりました。([#107565](https://github.com/kubernetes/kubernetes/pull/107565))
    -   :memo: バグがあったため、#106660でRevertされています。
-   :star: Kubernetes 1.24はGo 1.18でビルドされています。デフォルトは SHA-1 ハッシュアルゴリズムで署名された証明書を検証しません。詳しくは <https://golang.org/doc/go1.18#sha1> をご覧ください。このような証明書をAdmissionやConversionで使用している場合に注意して下さい。([#109024](https://github.com/kubernetes/kubernetes/pull/109024))
    -   :memo: Goの1.8では、クライアントのTLS 1.0とTLS 1.1をデフォルト無効化、SHA-1で署名された証明書を拒否するように変更されています。
-   volume expansionがGAに昇格しました。([#108929](https://github.com/kubernetes/kubernetes/pull/108929))
-   :star: kube-apiserverが提供するOpenAPI定義に、デフォルトでEnum型が含まれるようになりました。([#108898](https://github.com/kubernetes/kubernetes/pull/108898))
    -   :memo: OpenAPIのEnum型がデフォルト有効になりました。Enum型サポートのモチベーションとしては、APIを定義する構造体に"コレはEnum型ですよ"とマークするためのマーカを定義し、(kubebuilderなどの)generatorから便利に使えるようにしたいというものです。ただし、Enum型を使ったValidationはゴールに含まれていません。詳しくは[KEP-2887](https://github.com/kubernetes/enhancements/blob/master/keps/sig-api-machinery/2887-openapi-enum-types/README.md)を参照してください。また、前述の[#109178](https://github.com/kubernetes/kubernetes/pull/109178)に注意してください。
-   `LeaderMigrationConfiguration` の `v1` 版は、 `leases` API のみをサポートします。前バージョンでサポートされていた機能を使うには、引き続き `v1beta1` を使用してください。 ([#108016](https://github.com/kubernetes/kubernetes/pull/108016))
-   golang.org/x/net を v0.0.0-20211209124913-491a49abca63 に更新しました。([#106949](https://github.com/kubernetes/kubernetes/pull/106949))


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

-   client-go: client-goのclientはUser Agentをdefaultにせず、全リクエストにgolang Agentを利用していました。([#108772](https://github.com/kubernetes/kubernetes/pull/108772))
-   kube-apiserver: egress selectorをgRPCモードで利用するとkube-apiserverのgoroutieがリークする問題を修正するため、 `sigs.k8s.io/apiserver-network-proxy/konnectivity-client@v0.0.30` にアップデートしました。([#108437](https://github.com/kubernetes/kubernetes/pull/108437))
-   CEL Validationの失敗時に、オジェクトの代わりにオブジェクトの型を返すようになりました。([#107090](https://github.com/kubernetes/kubernetes/pull/107090))
-   Client-go: Pagingが開始されると、 `ResourceVersionMatch` が設定されたPagingリストの呼び出しに失敗する問題を修正しました。([#107311](https://github.com/kubernetes/kubernetes/pull/107311))
-   :star: Etcd: v3.5.3にアップデートしました。([#109471](https://github.com/kubernetes/kubernetes/pull/109471))
-   kube-apiserverのクラッシュの原因となるTimeout Handlerの競合を修正しました。([#108455](https://github.com/kubernetes/kubernetes/pull/108455))
-   kube-apiserverのAPI Priority & Fairnessにおいて、委任されたAPIリクエストのコストが過大に評価されていた問題を修正しました。([#109188](https://github.com/kubernetes/kubernetes/pull/109188))
-   execプラグインのCredentialが、kubeconfigに設定されたstaticな証明書を上書きするバグを修正しました。([#107410](https://github.com/kubernetes/kubernetes/pull/107410))
-   `/healthz` リクエストがタイムアウトした際に、panicを引き起こす懸念があるバグを修正しました。([#107034](https://github.com/kubernetes/kubernetes/pull/107034))
-   `create --dry-run` から不要なフィールドが返されるバグを修正しました: uid と generateName が使用された場合は name が返されていました。([#107088](https://github.com/kubernetes/kubernetes/pull/107088))
-   Timeoutするリクエストを処理する際に、稀に発生していた競合状態を修正しました。([#107452](https://github.com/kubernetes/kubernetes/pull/107452))
-   1.23で、 `x-kubernetes-preserve-unknown-fields: true` を設定したカスタムリソースの配列の要素から不正にデータが削除される回帰バグを修正しました。 ([#107688](https://github.com/kubernetes/kubernetes/pull/107688))
-   無効なセレクタを持つオブジェクトの取り扱いを修正しました。([#107559](https://github.com/kubernetes/kubernetes/pull/107559))
-   kube-apiserver: <http://issue.k8s.io/104641> が解決されるまで、Server-Side-Applyのマージ順はv1.22の挙動に合うように修正します。([#106660](https://github.com/kubernetes/kubernetes/pull/106660))
-   kube-apiserver: admission webhooksに送信されるオブジェクトの名前空間が、リクエストの名前空間と一致することを保証します。以前は、名前空間が設定されていないオブジェクトは、Admissionによる更新後にリクエスト名前空間が入力され、リクエストの名前空間と一致しない名前空間を持つオブジェクトは、Admission後に拒否されていました。([#94637](https://github.com/kubernetes/kubernetes/pull/94637))
-   kube-apiserver: リクエストユーザが特定できるような `apf_fd` をサーバーログから削除しました。([#108631](https://github.com/kubernetes/kubernetes/pull/108631))
-   kubectlのverboseログにレスポンスのステータスとヘッダを再追加しました。([#108505](https://github.com/kubernetes/kubernetes/pull/108505))
-   `ServerSideFieldValidation` 機能が 1.24でalphaに戻りました。([#109271](https://github.com/kubernetes/kubernetes/pull/109271))
-   非推奨フラグ `--really-crash-for-testing` は削除されました。([#101719](https://github.com/kubernetes/kubernetes/pull/101719))
-   Kubeletは、Heartbeat失敗時にアクティブな接続を強制的に閉じず、HTTP2ヘルスチェック機構により壊れた接続を検出するようになりました。環境変数にDISABLE\_HTTP2を設定することで、以前の挙動に戻せます。([#108107](https://github.com/kubernetes/kubernetes/pull/108107))
-   `apiserver` が `kubernetes.default` ServiceのEndpointを照合するように設定している場合、設定されたService IPの範囲がapi-serverのpublic IPアドレスのIP familyと一致するか確認します。一致しない場合、起動に失敗します。([#106721](https://github.com/kubernetes/kubernetes/pull/106721))
-   APIサーバの非推奨のフラグ `--target-ram-mb` が削除されました。([#108457](https://github.com/kubernetes/kubernetes/pull/108457))
-   client-go: リトライ前にBodyのリセットに失敗した場合、エラーが表示されるようになりました。([#109050](https://github.com/kubernetes/kubernetes/pull/109050))
-   `k8s.io/apimachinery/util/clock` は非推奨になりました。代わりに `k8s.io/utils/clock` を利用してください。([#106850](https://github.com/kubernetes/kubernetes/pull/106850))
-   client-goのSPDY Transportはリダイレクトを追従しなくなりました。([#108531](https://github.com/kubernetes/kubernetes/pull/108531))
-   kube-apiserver: 非推奨フラグの `--deserialization-cache-size` が削除されました。([#108448](https://github.com/kubernetes/kubernetes/pull/108448))
-   エラーメッセージに `--max-resource-write-bytes` & `--json-patch-max-copy-bytes` の文字列を使用しなくなりました。([#106875](https://github.com/kubernetes/kubernetes/pull/106875))