Kubernetes 1.25: SIG-Network の変更内容

[Kubernetes 1.25](https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.25.md) の SIG-Network の変更内容をまとめました。

今回は SIG-Network の大きな変更はありませんでしたが、1.25 では Pod Security Policyを含む複数の廃止予定だった API が削除されているためご注意ください。

<details><summary>過去の SIG-Network の変更内容</summary><div>

- [Kubernetes 1.24: SIG-Network の変更内容](https://qiita.com/tkusumi/items/8ae63017abf763b0a22d)
- [Kubernetes 1.23: SIG-Network の変更内容](https://qiita.com/tkusumi/items/9516b7955c1c33d31e8e)
- [Kubernetes 1.22: SIG-Network の変更内容](https://qiita.com/tkusumi/items/2e3c69849ce2a4b50a90)
- [Kubernetes 1.21: SIG-Network の変更内容](https://qiita.com/tkusumi/items/a816626c258735bdc98f)
- [Kubernetes 1.20: SIG-Network の変更内容](https://qiita.com/tkusumi/items/5e1c420503cfa730d940)
- [Kubernetes 1.19: SIG-Network の変更内容](https://qiita.com/tkusumi/items/ee1e100d34465ff2d764)
- [Kubernetes 1.18: SIG-Network の変更内容](https://qiita.com/tkusumi/items/e72e255363f6deee3e9b)
- [Kubernetes 1.17: SIG-Network の変更内容](https://qiita.com/superbrothers/items/fd936c4046459a16609c)
- [Kubernetes 1.16: SIG-Network の変更内容](https://qiita.com/tkusumi/items/5fc2e12a4bb8931a2eed)
- [Kubernetes 1.15: SIG-Network の変更内容](https://qiita.com/summerwind/items/e1c8d649ed8c7ae44b83)
- [Kubernetes 1.14: SIG-Network の変更内容](https://qiita.com/summerwind/items/7ca97a5d6e3e2537ebca)

</div></details>

以下は、[Kubernetes v1.25 の Changelog](https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.25.md) を和訳したものです。:memo: の部分は筆者の補足になります。

## Major Themes (主なテーマ)

### Network Policy の endPort が stable (GA) に昇格
[Network Policy](https://kubernetes.io/docs/concepts/services-networking/network-policies/#targeting-a-range-of-ports) の `endPort` が GA に昇格しました。`endPort` フィールドをサポートする Network Policy のプロバイダは、Network Policy を適用するポートの範囲を指定できるようになります。以前までは、各 Network Policy は単一のポートしか対象にできませんでした。

`endPort` フィールドが Network Policy プロバイダによって、サポートされていなければならないことに注意してください。もしあなたのプロバイダが `endPort` をサポートせず、このフィールドが Network Policy で指定された場合、Network Policy は単一の port フィールドのみをカバーしたものが作られます。

:memo: `port` に加えて `endPort` を指定した場合に、ポートの範囲を指定できる機能です。例えば次の例の場合、32000〜32768 のポートの範囲が対象となります。

`endPort` がサポートされない場合は、今まで通り `port` フィールドの値 (32000) のみが対象なります。例えば [GKE Dataplane V2 は `endPort` に未対応](https://cloud.google.com/kubernetes-engine/docs/how-to/dataplane-v2#network-policy-dataplane)のようです。(2022/09/07 時点)

```yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: multi-port-egress
  namespace: default
spec:
  podSelector:
    matchLabels:
      role: db
  policyTypes:
  - Egress
  egress:
  - to:
    - ipBlock:
        cidr: 10.0.0.0/24
    ports:
    - protocol: TCP
      # 32000〜32768 のポートが対象となる
      port: 32000
      endPort: 32768
```

## Kube-proxy イメージは distroless イメージがベースに
以前のリリースでは、kube-proxy のコンテナイメージはベースイメージに Debian を使ってビルドされていました。今回のリリースから、イメージに [distroless](https://github.com/GoogleContainerTools/distroless) を使ってビルドされるようになりました。この変更によりイメージサイズは 50％ 近く減少し、インストールされたパッケージやファイルは、kube-proxy が厳密に必要とするものだけに減少しました。

:memo: 以下は各 Kubernetes イメージ (amd64) のサイズです。確かに kube-proxy は 1.24.0 に比べて半分程度になっています。各ベースイメージは distroless に、必要なファイルのみを追加したものが使われています。

イメージ | 1.24.0 | 1.25.0 | ベースイメージ
--- | --- | --- | ---
[k8s.gcr.io/kube-apiserver](https://console.cloud.google.com/gcr/images/k8s-artifacts-prod/us/kube-apiserver) | 130MB | 128MB | [go-runner](https://github.com/kubernetes/release/tree/master/images/build/go-runner)
[k8s.gcr.io/kube-controller-manager](https://console.cloud.google.com/gcr/images/k8s-artifacts-prod/us/kube-controller-manager) | 119MB | 117MB | [go-runner](https://github.com/kubernetes/release/tree/master/images/build/go-runner)
[k8s.gcr.io/kube-scheduler](https://console.cloud.google.com/gcr/images/k8s-artifacts-prod/us/kube-scheduler) | 51MB | 50.6MB | [go-runner](https://github.com/kubernetes/release/tree/master/images/build/go-runner)
[k8s.gcr.io/kube-proxy](https://console.cloud.google.com/gcr/images/k8s-artifacts-prod/us/kube-proxy) | 130MB | 61.7MB | [distroless-iptables](https://github.com/kubernetes/release/tree/master/images/build/distroless-iptables)

## :memo: Kubernetes 1.24 と 1.25 の API 差分
Kubernetes API (`/api/`, `/apis/`) から取得した情報を使って、Kubernetes 1.24 と 1.25 の API の差分を確認しました。差分は以下になります。今回は PSP の他、deprecated だった API が複数削除されているのでご注意ください。(削除の PR は [remove enabled by default beta resources that have been removed #110010](https://github.com/kubernetes/kubernetes/pull/110010))

- API の追加: なし
- API の削除:
    - `autoscaling/v2beta1/horizontalpodautoscalers`
    - `batch/v1beta1/cronjobs`
    - `discovery.k8s.io/v1beta1/endpointslices`
    - `events.k8s.io/v1beta1/events`
    - `node.k8s.io/v1beta1/runtimeclasses`
    - `policy/v1beta1/poddisruptionbudgets`
    - `policy/v1beta1/podsecuritypolicies`
- Deprecation の指定: なし

各 Kubernetes の API バージョン対応表も、Kubernetes 1.25 時点での情報に更新しました。

https://qiita.com/tkusumi/items/cb2dc318875fbef19468

## Deprecation (非推奨)
- Windows の winkernel kube-proxy は Windows HNS v1 API をサポートしなくなりました ([#110957](https://github.com/kubernetes/kubernetes/pull/110957), [@papagalu](https://github.com/papagalu))
    - :memo: HNS v2 API のみのサポートとなりました。(HNS = [Host Networking Service](https://docs.microsoft.com/en-us/virtualization/windowscontainers/container-networking/architecture))

## API Change (API の変更)
- Pod のユーザ名前空間のアルファサポートが追加されました (KEP 127, feature gate: UserNamespacesStatelessPodsSupport) ([#111090](https://github.com/kubernetes/kubernetes/pull/111090), [@rata](https://github.com/rata))
- v1.25 の Kubernetes は Golang 1.19 が使われるようになりました。GA 版がまだ利用できないため、この PR では 1.19rc2 にアップデートします ([#111254](https://github.com/kubernetes/kubernetes/pull/111254), [@dims](https://github.com/dims))
    - :memo: 後の https://github.com/kubernetes/kubernetes/pull/111679 で 1.19 の GA 版が使われるようになっています
- アルファ機能として NodeIPAM の複数 ClusterCIDR ([#2593](https://github.com/kubernetes/enhancements/issues/2593)) のサポートが導入されました。
フィーチャーゲート `MultiCIDRRangeAllocator=true` を設定すると、`MultiCIDRRangeAllocator` を使用するかが決定され、次の kube-controller-manager フラグでアクティブなコントローラを選択します。`MultiCIDRRangeAllocator` を有効化するには、kube-controller-manager の `--cidr-allocator-type=MultiCIDRRangeAllocator` フラグを設定します。([#109090](https://github.com/kubernetes/kubernetes/pull/109090), [@sarveshr7](https://github.com/sarveshr7))
- PodSpec.Ports の説明で、この情報はただの情報で間違ったものになる可能性があることを明確にしました。([#110564](https://github.com/kubernetes/kubernetes/pull/110564), [@j4m3s-s](https://github.com/j4m3s-s)) [SIG API Machinery, Network and Node]
    - :memo: クライアントの Strategic merge patch で同一ポートで違うプロトコルを指定したときに、情報がおかしくなるようです https://github.com/kubernetes/kubernetes/issues/103544
- Network Policy の `endPort` フィールドが GA に昇格しました。
`endPort` フィールドをサポートする Network Policy のプロバイダは、Network Policy を適用するポートの範囲を指定できるようになります。以前までは、各 Network Policy は単一のポートしか対象にできませんでした。
`endPort` フィールドが Network Policy プロバイダによって、サポートされていなければならないことに注意してください。もしあなたのプロバイダが `endPort` をサポートせず、このフィールドが Network Policy で指定された場合、Network Policy は単一の port フィールドのみをカバーしたものが作られます。([#110868](https://github.com/kubernetes/kubernetes/pull/110868), [@rikatz](https://github.com/rikatz))


## Feature (機能追加)
- `ServiceIPStaticSubrange` 機能がベータ(デフォルトでは無効)になりました ([#110419](https://github.com/kubernetes/kubernetes/pull/110419), [@aojea](https://github.com/aojea))
    - :memo: 1.24 でアルファとして導入された機能です。次の 1.26 で GA となりそうです ([#112163](https://github.com/kubernetes/kubernetes/pull/112163))。
    - :memo: 参考: [Kubernetes: Service の静的 IP 用レンジを分割する (ServiceIPStaticSubrange)](https://qiita.com/tkusumi/items/da474798c5c9be88d9c5)
- Cloud Node Lifecycle コンローローラのメトリクス `running_managed_controllers` が有効になりました ([#111033](https://github.com/kubernetes/kubernetes/pull/111033), [@jprzychodzen](https://github.com/jprzychodzen))
- KCM 内の Node IPAM コントローラのメトリクス `running_managed_controllers` が有効になりました ([#111466](https://github.com/kubernetes/kubernetes/pull/111466), [@jprzychodzen](https://github.com/jprzychodzen))
    - :memo: KCM = kube-controller-manager
- KCM と CCM 内の Route、Service、Cloud Node コントローラのメトリクス `running_managed_controllers` が有効になりました ([#111462](https://github.com/kubernetes/kubernetes/pull/111462), [@jprzychodzen](https://github.com/jprzychodzen))
    - :memo: KCM = kube-controller-manager, CCM = cloud-controller-manager

## Documentation (ドキュメント)
- 存在しないノードを参照した Pod を持つ EndpointSlices は作成・更新ができませんでした。この EndpointSlices コントローラの挙動は、存在しないノードを参照した Pod を除いて EndpointSlice は更新され、全ての Pod が存在するノードを参照するまでリトライを繰り返すように変更されました。しかし `service.Spec.PublishNotReadyAddresses` が設定されたときは、全ての Pod がリトライなしで設定されます。EndpointSlice のメトリクスが、エンドポイントが存在しないときに要望する EndpointSlice の数を正しく反映するように修正されました。([#110639](https://github.com/kubernetes/kubernetes/pull/110639), [@aojea](https://github.com/aojea))


## Bug or Regression (バグまたはリグレッション)
- 削除とマークされた EndpointSlice はリコンサイル中に無視されるようになりました。([#109624](https://github.com/kubernetes/kubernetes/pull/109624), [@aryan9600](https://github.com/aryan9600))
- cluster IP アロケータが誤ったメトリクスを報告するバグを修正しました。([#110027](https://github.com/kubernetes/kubernetes/pull/110027), [@tksm](https://github.com/tksm))
    - :memo: `kube_apiserver_clusterip_allocator_*` のメトリクスは 1.24 まで正しく報告されていませんでした
- 複数の IP アドレスをもつ type `LoadBalancer` の Service と、ノード IP とオーバーラップする `LoadBalancerSourceRanges` に関わるバグを修正しました。([#109826](https://github.com/kubernetes/kubernetes/pull/109826), [@danwinship](https://github.com/danwinship))
    - :memo: kube-proxy の iptables ルール生成部分のバグ修正です
- 不適切なアノテーションがされた LoadBalancer サービスがアクティブになる可能性があるバグを修正しました。([#109601](https://github.com/kubernetes/kubernetes/pull/109601), [@mdbooth](https://github.com/mdbooth))
    - :memo: [informer から返ってきたオブジェクトを直接変更してはいけない](https://github.com/kubernetes/kubernetes/blob/f0791b50143856177878e21bb44beb5e3e36cc78/staging/src/k8s.io/client-go/tools/cache/thread_safe_store.go#L26-L40)ため、コピーして扱うようになりました
- `ServiceIPStaticSubrange` が有効なクラスタで、動的用ブロックが枯渇した場合に重複した IP アドレスがアサインされるバグを修正しました。([#109928](https://github.com/kubernetes/kubernetes/pull/109928), [@tksm](https://github.com/tksm))
- Kubernetes はホスト上の resolv.conf の "search ." を、kubelet が Pod に書き込む "resolv.conf" に "." エントリを保持するようになり、正しく処理するようになりました。([#109441](https://github.com/kubernetes/kubernetes/pull/109441), [@Miciah](https://github.com/Miciah)) [SIG Network and Node]
    - :memo: resolv.conf のパース時に末尾の `.` を取り除くする処理があり、`search .` だけの行が含まれると Pod の resolv.conf に `search` だけの行が含まれてしまっていました。これにより Pod の DNS に問題がある事象があったようです。
- Pod が停止中にその `readiness` を掲示(post)するようになった ([#110191](https://github.com/kubernetes/kubernetes/pull/110191), [@rphillips](https://github.com/rphillips))
    - :memo: 以前は Pod の停止中に readiness probe が実行されず、Pod の停止中は ready が true の状態のままとなっていたようです。
- Windows 上の `kube-proxy` で `kernelspace` モードを使ったとき、プロキシールール同期にかかる時間が減少しました。([#109124](https://github.com/kubernetes/kubernetes/pull/109124), [@daschott](https://github.com/daschott))
- ノードの ready の状態が変更したとき、externalTrafficPolicy=Local のクラスタ LB を過剰に再構成することで引き起こされていた、サービスのダウンタイムとクラウド API のコール数が現状しました (https://github.com/kubernetes/kubernetes/issues/111539)。cloud-controller-manager のサービスコントローラは、`Ready` と  `NotReady` の間の遷移にあるノードの再同期 (resync) を避けるようになりました(ETP=Local サービスの場合のみ)。これらのサービスに使われる LB は、特定のノードがトラフィックのロードバランスに使われるかを決めるのに、`healthCheckNodePort` で定義されたヘルスチェックプローブのみに依存します。([#109706](https://github.com/kubernetes/kubernetes/pull/109706), [@alexanderConstantinescu](https://github.com/alexanderConstantinescu))
    - :memo: ETP = ExternalTrafficPolicy
- ロードバランサのバックエンドプールからスケジュール不可(unschedulable)のノードが削除されないように、最近再導入されたスケジュールの predicate ([#109706](https://github.com/kubernetes/kubernetes/pull/109706)) を削除しました。([#111691](https://github.com/kubernetes/kubernetes/pull/111691), [@alexanderConstantinescu](https://github.com/alexanderConstantinescu))
    - :memo: `nodeSchedulablePredicate` というスケジューラブルかどうかの判定を行う predicate です。
- kube-proxy の `sync_proxy_rules_no_endpoints_total` メトリクスは、リモートエンドポイントを持ちローカルエンドポイントを持たない local-traffic-policy のみを数えるようになりました。([#109782](https://github.com/kubernetes/kubernetes/pull/109782), [@danwinship](https://github.com/danwinship))
- ノードアノテーション alpha.kubernetes.io/provided-node-ip は `--cloud-provider=external` が設定されたときのみ設定されなくなりました。非推奨のツリー内のプロバイダも含め `--cloud-provider` フラグが設定されている場合、kubelet 起動時にこのアノテーションが設定されるようになりました。 ([#109794](https://github.com/kubernetes/kubernetes/pull/109794), [@mdbooth](https://github.com/mdbooth)) [SIG Network and Node]
- Pod フェーズライフサイクルは、`Unready` または `Succeeded` の状態のターミナル (terminal) の Pod が、前の状態に戻ることなく全てのコンテナが終了することを保証するようになりました。したがって、ターミナルの Pod に到達されることはなく、Service の `TolerateUnready` の設定に関係なく `Endpoints` または `EndpointSlices` 上に IP アドレスを公開されるべきではありません。([#110255](https://github.com/kubernetes/kubernetes/pull/110255), [@robscott](https://github.com/robscott))
    - :memo: Pod のターミナル(terminal) は、[Pod のフェーズが `PodFailed` or `PodSucceeded` で判定](https://github.com/kubernetes/kubernetes/blob/v1.25.0/pkg/api/v1/pod/util.go#L298-L306)されています。
- kubelet が pod ネットワークの統計を生成したメトリクスが空になるケースがある問題を修正するため、cAdvisor を v0.44.1 に更新しました。([#109658](https://github.com/kubernetes/kubernetes/pull/109658), [@bobbypage](https://github.com/bobbypage))


## その他 (Cleanup or Flake)
- Linux の `kube-proxy` は、Debian ベースのイメージの代わりに新しい distroless コンテナイメージを使うようになりました。([#111060](https://github.com/kubernetes/kubernetes/pull/111060), [@aojea](https://github.com/aojea))
- 複数の IngressClass が "default" に指定されていた場合、DefaultIngressClass アドミッションコントローラは失敗させるのでなく 1 つを選択するようになりました。([#110974](https://github.com/kubernetes/kubernetes/pull/110974), [@kidddddddddddddddddddddd](https://github.com/kidddddddddddddddddddddd)) [SIG Network]
    - :memo: IngressClass の選択は、[後に作成されたものが優先される](https://github.com/kubernetes/kubernetes/blob/v1.25.0/plugin/pkg/admission/network/defaultingressclass/admission.go#L145-L150)実装になっていました。(作成時間が同じ場合は name の文字列が lower な方)
- Kube-proxy: "userspace" プロキシーモードは、Windows のデフォルトですが linux と Windows で廃止予定になりました。v1.26 で、Windows のデフォルトモードは `kernelspace` に変更されます。([#110762](https://github.com/kubernetes/kubernetes/pull/110762), [@pandaamanda](https://github.com/pandaamanda)) [SIG Network]