Kubernetes 1.29: SIG-Network の変更内容

[Kubernetes 1.29](https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.29.md) の SIG-Network の変更内容をまとめました。v1.29 ではアルファ機能として kube-proxy の nftables モードが追加されています。将来的に iptables モードを置き換えることが目標とされているため、個人的に注目しています。


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

- [Kubernetes 1.28: SIG-Network の変更内容](https://qiita.com/tkusumi/items/eaec7845fb391346c768)
- [Kubernetes 1.27: SIG-Network の変更内容](https://qiita.com/tkusumi/items/e50129395698d2a15e73)
- [Kubernetes 1.26: SIG-Network の変更内容](https://qiita.com/tkusumi/items/bc3b6c8073c5b3785741)
- [Kubernetes 1.25: SIG-Network の変更内容](https://qiita.com/tkusumi/items/a41ed4ffd67dd7b3ed23)
- [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.29 の Changelog](https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.29.md) を和訳したものです。:memo: の部分は筆者の補足になります。

## :memo: Kubernetes 1.28 と 1.29 の API 差分
Kubernetes API (`/api/`, `/apis/`) から取得した情報を使って、Kubernetes 1.28 と 1.29 のデフォルトで有効な API の差分を確認しました。今回は v1.29 で GA となった [API Priority and Fairness 機能](https://qiita.com/shmurata/items/155d7df295fd2786cd5f) に関するオブジェクト `FlowSchema`, `PriorityLevelConfiguration` の変更のみです。

- API の追加:
    - flowcontrol.apiserver.k8s.io/v1/flowschemas
    - flowcontrol.apiserver.k8s.io/v1/prioritylevelconfigurations
- API の削除:
    - flowcontrol.apiserver.k8s.io/v1beta2/flowschemas D
    - flowcontrol.apiserver.k8s.io/v1beta2/prioritylevelconfigurations D
- Deprecation の指定:
    - flowcontrol.apiserver.k8s.io/v1beta3/flowschemas D
    - flowcontrol.apiserver.k8s.io/v1beta3/prioritylevelconfigurations D

[各 Kubernetes の API バージョン対応表](https://qiita.com/tkusumi/items/cb2dc318875fbef19468)も、Kubernetes 1.29 時点での情報に更新しました。

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

### :memo: デフォルトで有効な API の変遷
デフォルトで有効な Kubernetes API の v1.14 から v1.29 までの変遷を確認してみました。基本的に API の追加は少なく、削除の方が多いことがわかります (APIGroup もしくは Version が違うものは別 API としてカウント)。新規のベータ API はデフォルト無効とする方針が v1.24 から入ったこともあり、かなり安定していると感じます ([KEP-3136: Beta APIs Are Off by Default](https://github.com/kubernetes/enhancements/tree/master/keps/sig-architecture/3136-beta-apis-off-by-default))。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100377/e93bec65-d5aa-0f9b-3cf1-c13da41a8420.png)

:::note info
追加・削除の詳細を見ると、ほとんどはバージョンの昇格に伴うものでした。Kubernetes v1.14 と v1.29 の API を比べて、バージョンの変更を除いて新規に追加された API は、下記の 6 API だけでした。

API | 初出  | ベータ初出
--- | --- | ---
authentication.k8s.io/v1/selfsubjectreviews | v1.28 | ベータなし
discovery.k8s.io/v1/endpointslices | v1.21 | v1.17
flowcontrol.apiserver.k8s.io/v1/flowschemas | v1.29 | v1.20
flowcontrol.apiserver.k8s.io/v1/prioritylevelconfigurations | v1.29 | v1.20
networking.k8s.io/v1/ingressclasses | v1.19 | v1.18
storage.k8s.io/v1/csistoragecapacities | v1.24 | v1.21
:::


## Deprecation (非推奨)
- Networking のアルファ API だった `ClusterCIDR` が削除されました。 ([#121229](https://github.com/kubernetes/kubernetes/pull/121229), [@aojea](https://github.com/aojea))
    - :memo: [KEP-2593: Enhanced NodeIPAM to support Discontiguous Cluster CIDR](https://github.com/kubernetes/enhancements/tree/master/keps/sig-network/2593-multiple-cluster-cidrs) で進められていた機能です。[この KEP は取り下げられ](https://groups.google.com/g/kubernetes-sig-network/c/nts1xEZ--gQ/m/2aTOUNFFAAAJ)、out-of-tree で開発される方針となりました。

## API Change (API の変更)
- 新しく `ServiceCIDR` タイプが追加され、Service ClusterIP アドレスの割当に使用されるクラスタの範囲を動的に設定できるようになりました。([#116516](https://github.com/kubernetes/kubernetes/pull/116516), [@aojea](https://github.com/aojea))
    - :memo: [KEP-1880: Multiple Service CIDRs](https://github.com/kubernetes/enhancements/tree/master/keps/sig-network/1880-multiple-service-cidrs) で進められているアルファの機能です。
- `type` を`LoadBalancer` に設定している Service の `.status` に、新しい `ipMode` フィールドを追加しました。この新しいフィールドは `LoadBalancerIPMode` フィーチャーゲートによって有効になります。([#119937](https://github.com/kubernetes/kubernetes/pull/119937), [@RyanAoh](https://github.com/RyanAoh)) [SIG API Machinery, Apps, Cloud Provider, Network and Testing]
- netfilter conntrack サブシステムの変数 `nf_conntrack_udp_timeout` および  `nf_conntrack_udp_timeout_stream` を設定するためのオプションを追加しました。([#120808](https://github.com/kubernetes/kubernetes/pull/120808), [@aroradaman](https://github.com/aroradaman))
    - :memo: kube-proxy に新しく `--conntrack-udp-timeout`, `--conntrack-udp-timeout-stream` フラグが追加されました。
- kube-proxy のコマンドラインのドキュメントで `--bind-address` は実際にはアドレスのバインドはせず、多くの場合使用するべきでないことが明記されました。([#120274](https://github.com/kubernetes/kubernetes/pull/120274), [@danwinship](https://github.com/danwinship))
    - :memo: `--bind-address` は kube-proxy の認識する Node のプライマリ IP アドレスを上書き指定するものです。
- `kube-proxy` に新しく nftables ベースのモードが追加されました。次のように実行することで利用可能です。

      kube-proxy --feature-gates NFTablesProxyMode=true --proxy-mode nftables

    現在はアルファ段階の機能であり、おそらくデータを食べてしまうことはありませんが、少しかじるようなことはあるかもしれません。(e2e テストは合格していますが実世界ではまだ使われていません)

    現時点では、127.0.1.1 上の Service ノードポートをサポートをしない点を除けば、機能的にはほとんど iptables モードと同じはずです。(現在は nftables 固有のコマンドライン引数は存在しないため、`--iptables-xxx` 引数に相当する値を設定したい場合は、設定ファイルを使う必要があります。)

    このコードは非常に新しいため、十分に最適化されていません。最終的には iptables バックエンドよりも高いパフォーマンスが期待されていますが、現時点ではほとんどパフォーマンステストは実施されていません。 ([#121046](https://github.com/kubernetes/kubernetes/pull/121046), [@danwinship](https://github.com/danwinship))
- `kube-proxy`: `nf_conntrack_tcp_be_liberal` sysctl  (カーネルの netfilter conntrack サブシステムの一部) を設定するオプション・フラグを追加しました。これを有効にした場合、`kube-proxy` は無効な conntrack 状態に対する `DROP` ルールをインストールしなくなります。これにより、非対称ルーティングのユーザに影響を与えている問題が解決します。([#120354](https://github.com/kubernetes/kubernetes/pull/120354), [@aroradaman](https://github.com/aroradaman))

### :memo: kube-proxy の nftables モードが追加された背景
v1.29 でアルファとして追加された kube-proxy の `nftables` モードは、最終的に `iptables` と `ipvs` バックエンドを置き換える機能として計画されています。[KEP-3866: Add an nftables-based kube-proxy backend](https://github.com/kubernetes/enhancements/blob/master/keps/sig-network/3866-nftables-proxy/README.md) によれば次のような背景があるようです。

1. iptables の修復できないパフォーマンス問題
    - iptables はインクリメンタルな変更をサポートしないためルールセット全体の更新が必要
    - このため Service 数などが増えルールのサイズが大きくなるに連れて遅くなる
1. iptables から nftables への移行
    - Linux カーネルでの iptables の開発はほぼ停止しており nftables に移行している
    - Linux ディストリビューションで iptables のサポートが廃止される可能性がある
        - [RHEL 9 は iptables を deprecated に指定](https://access.redhat.com/solutions/6739041)
        - [Debian 11 は `iptables` を必須パッケージから外した](https://salsa.debian.org/pkg-netfilter-team/pkg-iptables/-/commit/c59797aab9)
1. `ipvs` モードでは解決しない問題
    - 様々な問題がありデフォルトとはならなかった
    - iptables の API を多く使っているため iptables の廃止に対処できない
    - IPVS 自体が現在は活発に開発されていない
1. iptables の `nf_tables` モードでは解決しない問題
    - 多くの Linux ディストリビューションは iptables が内部的に nftable API を使う `nf_tables` モードになっている
    - しかしこのモードでは nftables の map のような新機能が使えない
1. `iptables` モードは複雑となっている
    - 後方互換性のため微妙な機能が残っている
1. 2 つのバックエンドを 1 つにしたい
    - 最終的に `iptables`, `ipvs` を非推奨とし `nftables` 1 つにしたい
1. 新しいモードによってクリーンアップやリファクタリングが進む
    - kube-proxy のライブラリ化([KEP-3786](https://github.com/kubernetes/enhancements/issues/3786)) に向けての話

### :memo: nftables モードを kind で試す

nftables モードを kind で試す場合は、下記のような設定が必要でした(参考: [Allow kubeProxyMode: "nftables" in the networking configuration #3434](https://github.com/kubernetes-sigs/kind/issues/3434))。[nft のバージョンによる問題](https://github.com/kubernetes/kubernetes/issues/122743)か Docker for Mac 4.26.1 では動作しなかったため、Ubuntu 22.04 上で確認しました。

```yaml
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
featureGates:
  NFTablesProxyMode: true
nodes:
- role: control-plane
  image: kindest/node:v1.29.0
- role: worker
  image: kindest/node:v1.29.0
- role: worker
  image: kindest/node:v1.29.0
kubeadmConfigPatches:
- |
  kind: KubeProxyConfiguration
  mode: "nftables"
```

nftables モードがの反映は [kube-proxy のログ](https://github.com/kubernetes/kubernetes/blob/v1.29.0/cmd/kube-proxy/app/server_others.go#L307)から確認できます。

```
I0115 08:47:17.526453       1 server_others.go:307] "Using nftables Proxier"
```

## Feature (機能追加)
- `kube-proxy` に新しく `--init-only` コマンドラインフラグを追加しました。このフラグを設定すると、kube-proxy が特権が必要な初期設定を実行し終了します。`--int-only` モードは特権を持った init container で実行することを意図しており、これによりメインのコンテナは厳格な `securityContext` で実行されるようにできます。([#120864](https://github.com/kubernetes/kubernetes/pull/120864), [@uablrek](https://github.com/uablrek)) [SIG Network and Scalability]
    - :memo: メインの kube-proxy コンテナでは privileged が不要となり、`NET_ADMIN`, `SYS_RESOURCE` の capabilities で動作するようになります。
- `Node` オブジェクトの `PodCIDR`が変更されたとき、`kube-proxy` が終了時にパニックになる問題を修正しました。([#120375](https://github.com/kubernetes/kubernetes/pull/120375), [@pegasas](https://github.com/pegasas))
- `PodHostIPs` がベータに昇格しました。([#120257](https://github.com/kubernetes/kubernetes/pull/120257), [@wzshiming](https://github.com/wzshiming))
    - :memo: この PR は [#121445](https://github.com/kubernetes/kubernetes/pull/121445) で revert されています。
- `PodHostIPs` がベータに昇格しました。([#121477](https://github.com/kubernetes/kubernetes/pull/121477), [@wzshiming](https://github.com/wzshiming))
- `ServiceNodePortStaticSubrange` が stable に昇格しデフォルトに固定されました。([#120233](https://github.com/kubernetes/kubernetes/pull/120233), [@xuzhenglun](https://github.com/xuzhenglun))
    - :memo: この機能については [Kubernetes: Service の静的ノードポート用レンジを分割する (ServiceNodePortStaticSubrange)](https://qiita.com/tkusumi/items/4c5bdf3cc83daadb7f24) にまとめています。
- `CloudDualStackNodeIPs` 機能がベータとなりました。この機能をサポートするように更新された外部クラウドプロバイダを使用する場合、`kubelet` にコンマ区切りのデュアルスタックの `--node-ips` を渡すことで、クラウドプロバイダが両方の IP を考慮できるようになります。
- `kube-apiserver` は clusterIP と nodePort の割当ロジックにおけるエラーを知らせる 4 つの新しいメトリクスを公開しました。([#120843](https://github.com/kubernetes/kubernetes/pull/120843), [@aojea](https://github.com/aojea))
    - :memo: 下記の 4 メトリクスです。ClucsterIP、NodePort それぞれの修復ループで発見したエラー数と修復に失敗した数です。
    - [`apiserver_clusterip_repair_ip_errors_total`](https://github.com/kubernetes/kubernetes/pull/120843/files#diff-96f41ed96286a8930eba6a49da2d226d315b515f45ef7f3c0b39626f074d878fR35)
    - [`apiserver_clusterip_repair_reconcile_errors_total`](https://github.com/kubernetes/kubernetes/pull/120843/files#diff-96f41ed96286a8930eba6a49da2d226d315b515f45ef7f3c0b39626f074d878fR47)
    - [`apiserver_nodeport_repair_port_errors_total`](https://github.com/kubernetes/kubernetes/pull/120843/files#diff-dcb4436c1f8005b04dd400de06265d75b850b5a7e942d4856634eaafd90fd715R35)
    - [`apiserver_nodeport_repair_reconcile_errors_total`](https://github.com/kubernetes/kubernetes/pull/120843/files#diff-dcb4436c1f8005b04dd400de06265d75b850b5a7e942d4856634eaafd90fd715R47)
- `kube-proxy` は `nf_conntrack_tcp_be_liberal` が未設定のときのみ、無効な `conntrack` 状態に対する `DROP` ルールをインストールするようになりました。 ([#120412](https://github.com/kubernetes/kubernetes/pull/120412), [@aojea](https://github.com/aojea))
- `kubelet` がデフォルトで Pod の `net.ipv4.tcp_keepalive_time` sysctl の使用を許可するようになりました。カーネルの最低バージョンは 4.5 となります。Pod Security Admission は `v1.29+` バージョンの baseline, restricted ポリシーでこの sysctl を許可します。([#118846](https://github.com/kubernetes/kubernetes/pull/118846), [@cyclinder](https://github.com/cyclinder))


## Failing Test (失敗しているテスト)
- Windows 向け `kubeproxy` のユニットテストでモックフレームワークをサポートしました。([#120105](https://github.com/kubernetes/kubernetes/pull/120105), [@princepereira](https://github.com/princepereira))

## Bug or Regression (バグまたはリグレッション)
- `ExternalIPs` を持つ `Service` に `ExternalTrafficPolicy` の指定を許可しました。([#119150](https://github.com/kubernetes/kubernetes/pull/119150), [@tnqn](https://github.com/tnqn))
- `externalTrafficPolicy: Local` を指定した Service に対する readiness predicate を再導入することで、[121094](https://github.com/kubernetes/kubernetes/issues/121094) の問題を修正しました。([#121116](https://github.com/kubernetes/kubernetes/pull/121116), [@alexanderConstantinescu](https://github.com/alexanderConstantinescu))
- 負のインデックスの JSON パッチの処理に関する `v1.28` のリグレッションが修正されました。([#120327](https://github.com/kubernetes/kubernetes/pull/120327), [@liggitt](https://github.com/liggitt))
- Service がファイナライザを使用しそのファイナライザが status サブリソースを使って削除された場合、`ClusterIP` および `NodePort` で割り当てられたリソースを期待より長く保持するバグを修正しました。([#120623](https://github.com/kubernetes/kubernetes/pull/120623), [@aojea](https://github.com/aojea))
- `TopologyCache` の `HasPopulatedHints` メソッドの並列に map にアクセスする問題を修正しました。([#118189](https://github.com/kubernetes/kubernetes/pull/118189), [@Miciah](https://github.com/Miciah))
- `kube-proxy` で、ノードが `IPv4` と `IPv6` の両方のを持ちシングルスタックの `IPv6` 設定が与えられた場合に起動しないリグレッションが修正されました。([#121008](https://github.com/kubernetes/kubernetes/pull/121008), [@danwinship](https://github.com/danwinship))
- `kubeproxy` のモックテストフレームワークで、`loadbalancer`, `endpoint` に対する ID 生成の増加の問題を修正しました。([#120723](https://github.com/kubernetes/kubernetes/pull/120723), [@princepereira](https://github.com/princepereira))
- KCCM: 変更が多い大規模クラスタでのロードバランサの同期中に、#121090 によって引き起こされる一時的なノードの追加・削除の問題を修正しました。([#121091](https://github.com/kubernetes/kubernetes/pull/121091), [@alexanderConstantinescu](https://github.com/alexanderConstantinescu))
- Service Controller: ノードの `ProviderID` が変更されたあと、ロードバランサのホストが更新されるようになりました。([#120492](https://github.com/kubernetes/kubernetes/pull/120492), [@cezarygerard](https://github.com/cezarygerard))
- `--bind-address` パラメータは誤解を招きやすく、このアドレスでポートは開かれません。代わりに、内部的には "nodeIP" に変換されます。両方のファミリ(:memo: IPv4 / IPv6) に対する nodeIP は、`--bind-address`が未指定もしくは "any" アドレス(0.0.0.0 または ::)が指定されたとき、Node オブジェクトから取得されるようになりました。`--bind-address` を未指定にするとが推奨され、特に localhost (127.0.0.1 またｈ ::1) を設定しないように注意してください。([#119525](https://github.com/kubernetes/kubernetes/pull/119525), [@uablrek](https://github.com/uablrek)) [SIG Network and Scalability]
    - :memo: kube-proxy についての話です
- デュアルスタッククラスタで片方の IP ファミリのみに問題がある場合に、`kube-proxy` はそのヘルス状態をより正確に報告するようになりました。([#118146](https://github.com/kubernetes/kubernetes/pull/118146), [@aroradaman](https://github.com/aroradaman))


## Other (Cleanup or Flake) (その他)
- `local-up-cluster.sh` で CNI バイナリを自動的にダウンロードするようになり、ローカルでのデバッグを容易にしました。 ([#120312](https://github.com/kubernetes/kubernetes/pull/120312), [@HirazawaUi](https://github.com/HirazawaUi))
- `kube-proxy` の挙動を変更し、`sysctl` の値を既存の値より低い値に設定できるようにしました。([#120448](https://github.com/kubernetes/kubernetes/pull/120448), [@aroradaman](https://github.com/aroradaman))
- `Service` が指定されたポートおよびプロトコルでのみトラフィックを転送することを検証するテストをコンフォーマンスに昇格しました。([#120069](https://github.com/kubernetes/kubernetes/pull/120069), [@aojea](https://github.com/aojea))
    - :memo: 「コンフォーマンス」は Kubernetes クラスタの適合性を検証するための e2e テストのサブセットです。(参考: [Conformance Testing in Kubernetes](https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/conformance-tests.md))
- `ComponentSLIs` フィーチャーゲートによって制御され、`/metrics/slis` で提供されるメトリクスは、GA となり無条件に有効となりました。このフィーチャーゲートは `v1.31` で削除されます。([#120574](https://github.com/kubernetes/kubernetes/pull/120574), [@logicalhan](https://github.com/logicalhan))