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

# はじめに

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

今バージョンでは、2018年から開発がすすめられていた `InPlacePodVerticalScaling` がついにBetaに昇格し、デフォルト有効になりました! めでたい。VPAの[In-Place対応](https://github.com/kubernetes/autoscaler/pull/7673)もv1.4.0でリリースされました。他にも、HPAのscaling toleranceやPod lifecycleのStopSignal、kubectlの新設定ファイルkuberc、Node情報のDownward API対応など便利機能も色々入っています。APIに限ったものだと、引き続きWatchCacheまわりの改善が多いです。

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

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


# 🗑️ Deprecation (非推奨になった機能)

-   `WatchFromStorageWithoutResourceVersion` FeatureGateはDeprecatedになりました。今後は有効にできません。([#129930](https://github.com/kubernetes/kubernetes/pull/129930))
    
    :::note
    📝 v1.27で入った変更により、resource-versionが指定されていないときにユーザがetcdから直接データをWatchできるようになっており、これによるetcdの負荷が問題になっていました。etcdを保護するため、FeatureGateが無効の時にetcdにバイパスせずキャッシュからレスポンスを返す機能が1.27(default false)から追加されました。今後もetcdへ直接watchを許可する計画がないため、廃止になりました。(今までもデフォルト無効のため、ほとんどの人は影響が無いはず。)
    :::
-   Pod の `status.resize` フィールドは非推奨になりました。今後は設定されません。Pod のリサイズ状況は、新しいコンディション `PodResizeInProgress` および `PodResizePending` に設定されます。([#130733](https://github.com/kubernetes/kubernetes/pull/130733))
    
    :::note
    📝 今回Betaに昇格したInPlacePodVerticalScaling用のフィールドです。今まではPodのstatusとして個別に管理されていましたが、Podのconditionにマージされました。(こちらの変更も、In-Placeがデフォルト有効になったのは今回のv1.33からなので、影響あるひとはほぼいないはず。)
    :::
-   v1のEndpoints APIは正式に非推奨となりました(ひきつづきサポートはされています)。APIは削除されませんが、EndpointSlice APIに移行してください。([#130098](https://github.com/kubernetes/kubernetes/pull/130098))


# 🌏 API Changes (API周りの変更)

-   `HorizontalPodAutoscaler` に `tolerance` フィールドが追加されました。cluster-wideのデフォルト値を上書きできます。HPAConfigurableTolerance アルファ FeatureGateから有効化できます。([#130797](https://github.com/kubernetes/kubernetes/pull/130797))
    
    :::note
    📝 HPAがピーキーな動きをしないように、 `desiredMetricValue/currentMetricValue` の比率が指定したtolerance範囲内だった場合、スケールさせない為の機能です。デフォルト値は10%なので、メトリクスの比率が90%～110%の場合はスケールしません。また、この値は各HPAごとにスケールアップ/ダウン個別に指定できます。cluster-wideの値はkube-controller-managerの `--horizontal-pod-autoscaler-tolerance` フラグから変更できます。現在はアルファでデフォルト無効です。例:
    
    ```yaml
    behavior:
      scaleUp:
        tolerance: 0.01 # 1%
        ...
      scaleDown:
        tolerance: 0.05 # 5%
        ...
    ```
    :::
-   StopSignal コンテナライフサイクルを使ってカスタムの停止シグナルを設定できるようになりました。([#130556](https://github.com/kubernetes/kubernetes/pull/130556))
    
    :::note
    📝 STOPSIGNALをデフォルトのSIGTERMからManifest経由で変更できるようになりました。DockerfileのSTOPSIGNALとおなじ用に上書きできますが、マニフェストから変更できるので、コンテナイメージの再ビルドが不要になっています。現在アルファで、デフォルト無効です。利用にはFeatureGate`ContainerStopSignals`の有効化が必要です。 例:
    
    ```yaml
    containers:
      - name: app
        lifecycle:
          stopSignal: SIGINT
        ...
    ```
    :::
-   Sidecar(`initContainers` のうち、 `restartPolicy` が `Always` に設定されたコンテナ)を含む Pod のInplace 垂直スケーリングがサポートされました。([#128367](https://github.com/kubernetes/kubernetes/pull/128367))
-   CPUManager Policy Options が GA になりました。([#130535](https://github.com/kubernetes/kubernetes/pull/130535))
-   PodAffinity（PodAntiAffinity）の `MatchLabelKeys` （MismatchLabelKeys）機能が GA になりました。([#130463](https://github.com/kubernetes/kubernetes/pull/130463))
-   Deployment および ReplicaSet に、終了中の Pod を追跡する新しい `.status.terminatingReplicas` フィールドが実装されました。このフィールドは `DeploymentPodReplacementPolicy` FeatureGateが有効な場合に表示されます。([#128546](https://github.com/kubernetes/kubernetes/pull/128546))
    
    :::note
    📝 ChangeLogではFeatureGate名が `DeploymentPodReplacementPolicy` になっていますが、正しくは `DeploymentReplicaSetTerminatingReplicas` です。
    :::
-   Protobuf フォーマットのListリクエストに対する API サーバのレスポンスが改善されました。Protobuf の list レスポンスは要素ごとにマーシャリングされ、大規模コレクションへの対応で必要なメモリが大幅に削減されます。ストリーミング list レスポンスは `StreamingCollectionEncodingToProtobuf` FeatureGateで無効化できます。([#129407](https://github.com/kubernetes/kubernetes/pull/129407))
    
    :::note
    📝  WatchListの代替としてAlphaをスキップして今バージョンでBetaデフォルト有効で導入されました。 `StreamingCollectionEncodingToJSON` の方はなぜか機能追加の方にありますが、併せてBetaとしてデフォルト有効で導入されています。
    :::
-   API タイプ `coordination.k8s.io/v1beta1/LeaseCandidate` が導入され `CoordinatedLeaderElection` 機能が Beta に移行されました。([#130751](https://github.com/kubernetes/kubernetes/pull/130751)), ([#130291](https://github.com/kubernetes/kubernetes/pull/130291))
    
    :::note
    📝 k8sクラスタのアップグレード/ロールバック時の安定性向上を目的にv1.31で導入された `CoordinatedLeaderElection` がBetaに昇格しました。ひきつづきデフォルト無効です。
    :::
-   `VolumeAttributesClass` という新しいスコープ名が導入されました。これは特定のボリューム属性クラスを持つすべての PVC オブジェクトにマッチします。特定の属性クラスを持つ PVC の数を制限したい場合は、このスコープ名と `matchExpressions` を持つクォータオブジェクトを作成できます。([#124360](https://github.com/kubernetes/kubernetes/pull/124360))
-   kubectl: `kubecfg` とは別に `kuberc` ファイルからの設定によって `kubectl` の動作をカスタマイズするアルファサポートが追加されました。([#125230](https://github.com/kubernetes/kubernetes/pull/125230))
    
    :::note
    📝 (k9sのconfigのようなフォーマットの)kubercファイルでkubectlのコマンドのデフォルト挙動をカスタマイズできるようになっています。現在アルファでデフォルト無効です。使うには `KUBECTL_KUBERC=true` 環境変数を設定してください。よくつかうカスタムカラムとかを設定すると便利そうですね。
    
    ```yaml
    apiVersion: kubectl.config.k8s.io/v1alpha1
    kind: Preference
    aliases:
    - name: runx
      command: run
      flags:
      - name: image
        default: nginx
      - name: labels
        default: app=test,env=test
    overrides:
    - command: apply
      flags:
      - name: server-side
        default: "true"
      - name: dry-run
        default: "server"
      - name: validate
        default: "strict"
    ```
    :::
-   `JobSuccessPolicy` が Stable に昇格しました。([#130536](https://github.com/kubernetes/kubernetes/pull/130536))
-   Job の `JobBackoffLimitPerIndex` FeatureGateが Stable に昇格しました。([#130061](https://github.com/kubernetes/kubernetes/pull/130061))
-   GAのFeatureGate `CPUManager` が削除されました。([#129296](https://github.com/kubernetes/kubernetes/pull/129296))
-   GAのFeatureGate `PDBUnhealthyPodEvictionPolicy` が削除されました。([#129500](https://github.com/kubernetes/kubernetes/pull/129500))
-   `node.status.nodeSystemInfo` に swap 容量が追加されました。([#129954](https://github.com/kubernetes/kubernetes/pull/129954))
-   `ClusterTrustBundle` API が `v1beta1` に移行しました。kubelet 側で `ClusterTrustBundleProjection` 機能を動作させるには、この API が `v1beta1` バージョンで利用可能で、かつ `ClusterTrustBundleProjection` FeatureGateが有効である必要があります。kubelet 起動後に API が利用可能になった場合は kubelet を再起動してください。([#128499](https://github.com/kubernetes/kubernetes/pull/128499))
-   `PodObservedGenerationTracking` FeatureGateが設定されている場合、kubelet は Pod の最新の `metadata.generation` を反映するために `status.observedGeneration` を設定します。([#130352](https://github.com/kubernetes/kubernetes/pull/130352))
-   `PodObservedGenerationTracking` FeatureGateが設定されていると、kube-controller-manager は pod のコンディションに `observedGeneration` フィールドを設定します。([#130650](https://github.com/kubernetes/kubernetes/pull/130650))
    
    :::note
    📝 ResourceなどPodが変更できるようになっているので、statusがどの段階のPod(`metadata.generation`)の状態を示しているのかを判別できるようにフィールドが追加されました。詳しくは `KEP-5067` を参照してください。 例:
    
    ```yaml
    status:
      conditions:
      - lastTransitionTime: "2025-05-05T02:15:36Z"
        observedGeneration: 1
        status: "True"
        type: PodReadyToStartContainers
      ...
    ```
    :::
-   ReplicationController の `replicas` および `minReadySeconds` フィールドの最小値検証が宣言的バリデーションに移行されました。両フィールドの必須性も宣言的に検証されます。 `DeclarativeValidation` FeatureGateが有効な場合、既存のバリデーションとの不一致はメトリクスで報告されます。 `DeclarativeValidationTakeover` が有効な場合、移行済みフィールドに関しては宣言的バリデーションが主なエラー源となります。([#130725](https://github.com/kubernetes/kubernetes/pull/130725))
    
    :::note
    📝 新たに `DeclarativeValidation` と `DeclarativeValidationTakeover` のFeatureGateがAlphaをスキップしてBeta追加されました。前者はデフォルト有効、後者はデフォルト無効です。 DeclarativeValidationでは、以下のようにインターフェース定義言語(IDL)で宣言的にAPIのバリデーションを定義するというものです。DeclarativeValidationが有効の場合、従来のバリデーションに加えて宣言的バリデーションも検証されます。また、不一致があった場合はログとメトリクスに記録されます。検証結果のハンドリングについては、 `DeclarativeValidationTakeover` の方で制御しており、有効の場合のみ宣言的バリデーションの結果が使われます。詳しくは `KEP-5073` を参照してください。
    
    ```go
    // ReplicationControllerSpec is the specification of a replication controller.
    type ReplicationControllerSpec struct {
        // +k8s:optional
        // +k8s:minimum=0
        Replicas *int32 `json:"replicas,omitempty" protobuf:"varint,1,opt,name=replicas"`
    }
    ```
    :::
-   `resource.k8s.io/v1beta1` API は非推奨となり、1.36 で削除されます。代わりに `v1beta2` を使用してください。([#129970](https://github.com/kubernetes/kubernetes/pull/129970))
-   `PreferSameTrafficDistribution` FeatureGateが有効な場合、新しい `trafficDistribution` 値 `PreferSameNode` が利用可能になり、クライアントと同じノード上のエンドポイントに常にルーティングしようとします。さらに `PreferSameZone` が `PreferClose` の別名として導入されました。([#130844](https://github.com/kubernetes/kubernetes/pull/130844))
-   `apidiscovery.k8s.io/v2beta1` API グループをデフォルト無効化します。([#130347](https://github.com/kubernetes/kubernetes/pull/130347))


# ✨ Features (機能追加)

-   `ListFromCacheSnapshot` FeatureGateを追加し、apiserver がキャッシュからの正確な RV および continuation による LIST を提供できるようにしました。 ([#130423](https://github.com/kubernetes/kubernetes/pull/130423))
    
    :::note
    📝 今回GAになった `BtreeWatchCache` の拡張機能のようなものです。ページネーションのあるListリクエストなどはwatch-cacheをバイパスしてetcdから直接データを取得していましたが、大量にメモリを消費したり、APFの予測コストと実際の使用量が正確に反映できないという問題がありました。これを解決するため、B-Treeベースのキャッシュのスナップショットを作成し、このキャッシュからListリクエストを返すための機能です。詳しくは `KEP-4988` を参照してください。
    :::
-   新しい CLI フラグ `--emulation-forward-compatible` を追加、新しい CLI `--runtime-config-emulation-forward-compatible` を追加しました。 ([#130354](https://github.com/kubernetes/kubernetes/pull/130354))
-   アルファFeatureGate `OrderedNamespaceDeletion` を追加しました。有効化すると、Namespace 削除時に Pod リソースが他のリソースより先に削除されます。 ([#130035](https://github.com/kubernetes/kubernetes/pull/130035))
-   `OrderedNamespaceDeletion` FeatureGateをデフォルトで有効にしました。 ([#130507](https://github.com/kubernetes/kubernetes/pull/130507))
-   CustomResourceDefinitions における CEL およびパターンの検証用ユニットテストヘルパーを追加しました。 ([#129028](https://github.com/kubernetes/kubernetes/pull/129028))
-   kube-controller-manager に `/flagz` エンドポイントを追加しました。 ([#128824](https://github.com/kubernetes/kubernetes/pull/128824))
-   Node にスケジュールされる際、Node オブジェクトの `topology.k8s.io/zone`, `topology.k8s.io/region`, `kubernetes.io/hostname` ラベルを Pod に自動的にコピーするようにし、アプリケーションが Node トポロジ情報を `get node` 権限なしで Downward API 経由で取得できるようにしました。 ([#127092](https://github.com/kubernetes/kubernetes/pull/127092))
-   `cel-go` を `v0.23.2` に更新しました。 ([#129844](https://github.com/kubernetes/kubernetes/pull/129844))
-   初期化されていないキャッシュから返された apiserver のエラーには、最後の etcd エラーが含まれるようになりました。 ([#130899](https://github.com/kubernetes/kubernetes/pull/130899))
-   `BtreeWatchCache` FeatureGateが GA に昇格しました。 ([#129934](https://github.com/kubernetes/kubernetes/pull/129934))
    
    :::note
    📝 Alphaをスキップして前バージョンの1.32でBeta(デフォルト有効)で導入されたBtreeWatchCacheがGAになりました。元々watch-cacheはHashMapベースでしたが、B-Treeベースにかえることで、APIサーバのリソース取得時のパフォーマンス向上とetcdの負荷軽減を目的としたものです。
    :::
-   `client-go/rest` におけるcontext loggingを実装しました。 `BackoffManager` の代わりに `BackoffManagerWithContext` を使用して、呼び出し側がスリープを中断できるようにしました。 ([#127709](https://github.com/kubernetes/kubernetes/pull/127709))
-   レスポンスフォーマットが JSON にネゴシエートされる ****list**** リクエストへの API サーバーのレスポンス方法を改善しました。JSON のリストレスポンスは 1 要素ずつマーシャリングされ、大量のコレクション提供時のメモリ使用量が大幅に削減されます。リストレスポンスのストリーミングは `StreamingJSONListEncoding` FeatureGateで無効にできます。 ([#129334](https://github.com/kubernetes/kubernetes/pull/129334))
    
    :::note
    📝 ChangeLogではFeatureGateの名が  `StreamingJSONListEncoding` になっていますが、正しくは `StreamingCollectionEncodingToJSON` です。 WatchListの代替としてAlphaをスキップして今バージョンでBetaデフォルト有効で導入されています。
    :::
-   `CRDValidationRatcheting` FeatureGateを 1.33 で GA に昇格しました。 ([#130013](https://github.com/kubernetes/kubernetes/pull/130013))
-   kube-apiserver への認証済みリクエストに対して、受信トレースコンテキストを尊重するようになりました。 ([#127053](https://github.com/kubernetes/kubernetes/pull/127053))
-   `RemoteRequestHeaderUID` 機能がベータになり、デフォルトで有効になりました。これにより、kube-apiserver は `X-Remote-Uid` ヘッダーで UID をAggregated API サーバーに伝播します。このヘッダーは受信リクエストではデフォルトで無視されますが `--requestheader-uid-headers` フラグを設定することで有効にできます。 ([#130560](https://github.com/kubernetes/kubernetes/pull/130560))
-   `DeclarativeValidation` FeatureGateがデフォルトで有効になりました。有効時は、既存の手書きバリデーションとの不一致がメトリクスで報告されます。 `DeclarativeValidationTakeover` FeatureGateはデフォルトでは無効のままです。無効な場合、手書きバリデーションによるエラーは常に呼び出し元に返されます。移行されたフィールドのエラーの主な情報源を宣言的バリデーションに切り替えるには、このFeatureGateを有効にしてください。 ([#130728](https://github.com/kubernetes/kubernetes/pull/130728))
-   `/version` レスポンスを更新し、バイナリバージョン情報を互換性バージョンと分けて報告するようにしました。 ([#130019](https://github.com/kubernetes/kubernetes/pull/130019))
-   `StorageCapacityScoring` FeatureGateを追加し、利用可能なストレージ容量に基づいてノードにスコアを付けるようにしました。現在アルファで、デフォルト無効です。アルファ機能 `VolumeCapacityPriority` はこれに置き換えられ、デフォルトの動作も変更されました。以前は割り当て可能量が最も少ないノードを優先していましたが、新機能では最大の割り当て可能量を持つノードが優先されます。詳細は [KEP-4049](<https://github.com/kubernetes/enhancements/blob/master/keps/sig-storage/4049-storage-capacity-scoring-of-nodes-for-dynamic-provisioning/README.md>) を参照してください。 ([#128184](https://github.com/kubernetes/kubernetes/pull/128184))


# 🐛 Bug or Regression (バグ修正)

-   CustomResourceDefinitions の `status` サブリソースに対して ratcheting validation を有効にしました。([#129506](https://github.com/kubernetes/kubernetes/pull/129506))
-   &#x2013;feature-gate=InOrderInformers（デフォルト有効）は、Informerが同じアイテムの更新をまとめるのではなく、順序通りに処理します。client-go を使っていて、かつFeatureGateを設定していないバイナリは、 `KUBE_FEATURE_InOrderInformers=false` を設定すると無効化できます。([#129568](https://github.com/kubernetes/kubernetes/pull/129568))
-   kube-apiserver が、前のイベントの復号に失敗して送信されなかった場合でも、次のウォッチイベントを送信してしまうバグを修正しました。([#131020](https://github.com/kubernetes/kubernetes/pull/131020))
-   register-gen が、k8s.io/apimachinery/pkg/runtime と k8s.io/apimachinery/pkg/runtime/schema のインポートが漏れていた問題を修正しました。([#129307](https://github.com/kubernetes/kubernetes/pull/129307))
-   CEL CIDR ライブラリが、他の CIDR に含まれているサブネットが誤って含まれていないと判断する問題を修正しました。([#130450](https://github.com/kubernetes/kubernetes/pull/130450))
-   参照オブジェクト名が有効な Event 名でない場合、Eventの作成に失敗するバグを修正しました。参照オブジェクト名とタイムスタンプのサフィックスの代わりに UUID が名前として使用されます。([#129790](https://github.com/kubernetes/kubernetes/pull/129790))
-   WebSockets HTTPS プロキシサポートを追加しました。([#129872](https://github.com/kubernetes/kubernetes/pull/129872))
-   kube-apiserver: リソースが更新されたとき（たとえば既存の Pod の `terminationGracePeriodSeconds` フィールドを設定または解除した場合など） `ResourceQuota` Admissionプラグインが、スコープの変更を無視するバグを修正しました。([#130060](https://github.com/kubernetes/kubernetes/pull/130060))
-   kube-apiserver: Pod 削除時にグレース期間を短縮しても `metadata.deletionTimestamp` が過去に移動しないように修正しました。([#122646](https://github.com/kubernetes/kubernetes/pull/122646))
-   ツールのバージョンを使用者が直接指定できるように、追加の関数引数を提供しました。([#129658](https://github.com/kubernetes/kubernetes/pull/129658))
-   `ConsistentListFromCache` 機能に関連する、1.31+ のデフォルト構成でのパフォーマンスの低下を解消しました。これは、異なる名前空間での API の急速な作成/更新リクエスト時に遅延が増加していた問題です。([#130113](https://github.com/kubernetes/kubernetes/pull/130113))
-   kube-apiserver の `/flagz` エンドポイントは `ComponentFlagz` feature-gate が有効な場合に解析されたフラグの値を正しく返すようになりました。([#130328](https://github.com/kubernetes/kubernetes/pull/130328))
-   kube-apiserver の `/flagz` エンドポイントのレスポンスが、解析されたフラグの値を正しく返すようになりました。([#129996](https://github.com/kubernetes/kubernetes/pull/129996))
-   JSON と誤解釈される可能性のあったYAMLが、正しく処理されるようになりました。([#130666](https://github.com/kubernetes/kubernetes/pull/130666))
-   kube-apiserver: `--service-cluster-ip-range` フラグが単一スタックからデュアルスタックに変更された場合、デフォルトの ServiceCIDR API オブジェクトの更新やデュアルスタック Service API オブジェクトの作成に失敗する問題を修正しました。([#131263](https://github.com/kubernetes/kubernetes/pull/131263))


# 🔬 Others (その他修正)

-   `client-gen` は、ソートされていない入力でも安定した出力生成を保証するために、入力された group/version をソートするようになりました ([#130626](https://github.com/kubernetes/kubernetes/pull/130626))
-   `SeparateCacheWatchRPC` feature gate は非推奨となり、デフォルトで無効になりました ([#129929](https://github.com/kubernetes/kubernetes/pull/129929))
    
    :::note
    📝 `SeparateCacheWatchRPC` はAlphaをスキップして1.28からBeta(デフォルト有効)で導入された機能です。watch-cache用とそれ以外のwatch用にetcdとのRPCを分けることでパフォーマンスと信頼性の向上を目的とした機能でしたが、 `WatchFromStorageWithoutResourceVersion` と同じく今後もユーザからのリクエストをetcdにバイパスさせない方針のため廃止されました。
    :::
-   etcd クライアントライブラリを `v3.5.21` に更新しました ([#131103](https://github.com/kubernetes/kubernetes/pull/131103))
-   kube-apiserver は 1.33 で beta の WatchList 機能をデフォルトで無効にし、代わりに `StreamingCollectionEncodingToJSON` および `StreamingCollectionEncodingToProtobuf` 機能を使用します。kube-controller-manager は 1.33 で WatchListClient 機能を有効化しないようになりました ([#131359](https://github.com/kubernetes/kubernetes/pull/131359))
    
    :::note
    📝 WatchListは1.27でAlpha導入され、前バージョンの1.32でBetaに昇格しデフォルトで有効になっていました。しかし、今バージョンの1.33からデフォルト無効になりました。代わりとして、 `StreamingCollectionEncodingToJSON` と `StreamingCollectionEncodingToProtobuf` がAlphaをSkipしてBeta(デフォルト有効)として導入されました。WatchListはメモリを大量に消費していた(主にInformerからの)ページングベースのListリクエストをWatch-Cacheからのストリームに置き換える機能で、 `StreamingCollectionEncodingToXXX` はエンコードレスポンスをメモリブロックに保持しつづけるのではなく、エンコード処理がストリーミング化することでメモリ量を減らすことを目的にしたものです。どちらもアプローチは違いますが、APIサーバのメモリ負荷の軽減を目的とした機能です。今回、WatchListよりStreamingEncodingの方が効率的ということで、切り替わりました。
    :::