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


## はじめに

ついにKubernetes v1.18がリリースされました :tada:

今回のSIG-API Machinery[^1][^2]には大きな新機能の追加はありませんが、このタイミングでIngressリソースに変更が入ったり、client-goにcontextが入ったりと予想してなかった変更が入っていて面白いリリースでした。その分(client-go使っている人は特に!)アップグレード前の事前準備に注意しましょう。

この記事はKubernetesの[CHANGELOG v1.18](https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.18.md#v1180)から、SIG API Machineryに関連する項目をピックアップして翻訳したものです。他のSIGについてもZ Labの他のメンバーが紹介しているのでそちらもご参照ください :pray: 

:memo: が付いている文章は公式内容ではなく筆者の補足事項です。

[^1]: Special Interest Groups(SIG)は、特定の分野(ex. API/Storage/Network)の特化した開発を進めるためのグループです。SIGの中でさらに複数のサブプロジェクトに分かれていることもあります。
[^2]: API serverやAdmission Control、CRDなどなどKubernetesのAPIに関わる機能をまるっと担当しているSIG。

## :mega: What's New (新情報)

### Serverside Apply - Beta 2

1.16でベータに昇格したServer-side Applyが1.18でBeta2になりました。新バージョンでは、全Kubernetesオブジェクトに対してフィールド変更の追跡と管理ができます。これにより、リソースの何がいつ変更されたのかを把握できます。

### Extending Ingress with and replacing a deprecated annotation with IngressClass

Kubernetes 1.18では、Ingressに`pathType`フィールドと新しいIngressClassリソースが追加されました! `pathType`フィールドはパスのマッチ方法を指定できます。デフォルトの`ImplementationSpecific`タイプに加えて、新たに`Exact`と`Prefix`が追加されました。

`IngressClass`リソースはKubernetesクラスタ内のIngressタイプを示すために利用します。Ingressは新規追加された`ingressClassName`フィールドを利用して、関連づけるクラスを指定できます。これにより、廃止になった`kubernetes.io/ingress.class`アノテーションは新しいフィールドに置き換えられます。

## :warning: Urgent Upgrade Notes （アップグレード前の注意点）

:memo: ここではclient-goのみ紹介しますが、ほかにも色々あるので他の記事も参照してください。

### client-go

生成されたclientset、dynamic/metadata/scaleクライアントのメソッドは第一引数に`context.Context`をとるようになりました。また、Create、Update、Patchメソッドはそれぞれ引数にCreateOptions、UpdateOptions、PatchOptionsをとります。Delete及びDeleteCollectionメソッドはDeleteOptionsを参照ではなく値として受け付けるようになりました。
以前のインタフェースで生成されたclientsetは、新しいAPIへの逐次的な移行を可能にするために、新しい「非推奨」パッケージで追加されました。非推奨パッケージは1.21のリリース時に削除されます。この移行をサポートするためのツールは http://sigs.k8s.io/clientgofix で提供されています。

> :memo: 移行ツールの`clientgofix`はcloneしてmake installで直接インストールします。実行すると(デフォルトでは)コードが書き換えられます。やってくれることは、contextとmetav1パッケージのインポート、`context.TODO()`の挿入、参照渡し or `nil`だったDeleteOptionsの修正、各種XXXOptionsの挿入です。

```bash
$ clientgofix ./...
loaded 203 packages in 17.885371155s
/path/to/file.go
  12: Get: added context import
  12: Get: inserted context.Context as arg 0
/path/to/file2.go
  57: Do: added context import
  57: Do: inserted context.Context as arg 0
  74: Do: inserted context.Context as arg 0
```

## :wastebasket: Deprecations and Removals (廃止および削除）

### kube-apiserver

- すでに廃止になっていた以下のAPIが削除されます [#85903](https://github.com/kubernetes/kubernetes/pull/85903)
    - `apps/v1beta1`、`apps/v1beta2` (今後は`apps/v1`を使ってください)
    - `extensions/v1beta`配下の`daemonsets`、`deployment`、`replicasets` (今後は`apps/v1`を使ってください)
    - `extensions/v1beta`配下の`networkpolicies` (今後は`networking.k8s.io/v1`を使ってください)
    - `extensions/v1beta`配下の`podsecuritypolicies` (今後は`policy/v1beta1`を使ってください)

### kubelet

- StreamingProxyRedirects機能の`--redirect-container-streaming`フラグが廃止になりました。このフラグは(kubeletを経由するプロキシのストリーミングリクエストは)デフォルト無効でしたが、現在`--redirect-container-streaming=true`フラグを設定している場合この設定の修正が必要です。v1.20以降にこのフラグは削除される予定です。

## :earth_asia: API Change (API周りの変更)

### New API types/versions

Ingressの設定を改善するため、新しいIngressClassリソースが追加されました。[#88509](https://github.com/kubernetes/kubernetes/pull/88509)

### New API fields:

autoscaling/v2beta2のHorizontalPodAutoscalerにスケール方法を設定する`spec.behavior`フィールドが追加されました。behaviorフィールドはスケールアップやダウンに対して個別に設定できます。どちらの場合も、安定ウィンドウ、ポリシーのリスト、そしてどのポリシーを選択するかを指定できます。ポリシーでは、追加や削除されるPodの絶対数や割合を制限できます。[#74525](https://github.com/kubernetes/kubernetes/pull/74525)

> :memo: 詳しい指定方法については、この[KEP](https://github.com/kubernetes/enhancements/blob/master/keps/sig-autoscaling/20190307-configurable-scale-velocity-for-hpa.md)に記述されています。

### Other

- 現在Betaの`ServerSideApply`は全ての新規オブジェクトに対してフィールドの変更管理を可能にします。metadataのmanagedFieldsに自身を管理するオブジェクトと管理しているオブジェクトのリストが設定されます。
- CustomResourceDefinition schemaの`x-kubernetes-list-map-keys`は、全リストアイテムがユニークになるようなプロパティを設定するためのものです。詳しくは [k8sドキュメント: マージ戦略](https://kubernetes.io/docs/reference/using-api/api-concepts/#merge-strategy) を参照してください。[#88076](https://github.com/kubernetes/kubernetes/pull/88076)
- `x-kubernetes-list-type: map`と`x-kubernetes-list-type: set`が設定されているCustomResourceDefinition schemaも、リストアイテムが一意であることがバリデーションされるようになりました。[#84920](https://github.com/kubernetes/kubernetes/pull/84920)

## :page_facing_up: Configuration file changes (設定ファイルの変更)

### kube-apiserver

`--egress-selector-config-file`フラグに対して、apiserver.k8s.io/v1beta1のEgressSelectorConfigurationオブジェクトを定義したファイルを設定できるようになりました。また、network-proxyの接続方法に、HTTPかGRPCを選択できるようになりました。[#87179](https://github.com/kubernetes/kubernetes/pull/87179)

> :memo: 今まではGRPCをサポートしていませんでした。またChangeLogの文章には書かれていませんが、トランスポートプロトコルもTCPに加えてUDS(UnixDomainSocket)が追加されています。デフォルト値もUDSに変更になりました。詳しくはこちらの[KEP - Network Proxy](https://github.com/kubernetes/enhancements/blob/master/keps/sig-api-machinery/20190226-network-proxy.md)をご参照ください。

### kube-proxy

- kube-apiserverと同じように、kube-controller-managerとkube-schedulerもプロファイリングをデフォルトで公開するようになりました。`--enable-profiling=false`を付与すると無効化できます。[#88663](https://github.com/kubernetes/kubernetes/pull/88663)
- kube-controller-managerに`--endpointslice-updates-batch-period`が追加されました。このフラグは、Podの変更によるEndpointSliceの更新数を削減するために利用できます。[#88745](https://github.com/kubernetes/kubernetes/pull/88745)

## :rocket: Features graduated to GA (GAになった機能)

- TaintBasedEvictionsがGAしました。[#87487](https://github.com/kubernetes/kubernetes/pull/87487)
- 前のリリースで常時有効になったCustomResourceValidation、CustomResourceSubresources、CustomResourceWebhookConversion、CustomResourcePublishOpenAPI、CustomResourceDefaultingはfeature gatesから削除されます。[#87475](https://github.com/kubernetes/kubernetes/pull/87475)

## :sparkles: Feature（機能追加）

- (リクエストの比率が高い場合の)`API request throttling`ログは、client-goのログレベル2で表示されるようになりました。これは、`Throttling request took 1.50705208s, request: GET:<URL>`というフォーマットで表示されているメッセージで、管理者がクラスタをチューニングする必要があるかもしれない状態を示します。[#87740](https://github.com/kubernetes/kubernetes/pull/87740)
- APIサーバに`--goaway-chance`フラグが追加されました。これは、リクエストの割合に応じて接続をグレースフルに終了(GOAWAY)するものです。これは、HTTP/2クライアントが単一のAPIサーバでスタックすることを防ぎます。[#88567](https://github.com/kubernetes/kubernetes/pull/88567)

> :memo: HTTP2でAPIサーバとクライアントを接続した場合、別のAPIリクエストでも同じAPIサーバにヒットするためリクエストの負荷分散ができないということを解決するものです。このフラグを追加すると、確率的にHTTP2クライアントにGOAWAYを送信し、処理中のwatchリクエストを処理した後に接続が切られます(つまりこのタイミングで不可分散されます)。ロードバランサを利用していないクラスタ、masterがHA構成ではないクラスタでの利用はNGです。

- kubeadm: 試験的なPublicKeysECDSAをfeature gateに追加しました。これにより、`kubeadm init`でECDSA証明書を使ったクラスタを生成できます。また、ECDSA証明書の場合でも`kubeadm alpha certs renew`を使って証明書の更新ができます。ただし、別のアルゴリズム(RSAとECDSA)へスイッチすることはできません。[#86953](https://github.com/kubernetes/kubernetes/pull/86953)
- kubectlに`--dry-run=server`オプションを付与すると、apply/patch/create/run/annotate/label/set/autoscale/drain/rollout undo/exposeコマンドの場合Server側でdry-runを実行できるようになりました。[#87714](https://github.com/kubernetes/kubernetes/pull/87714)
- CNI versionがv0.8.5に更新されました。[#78819](https://github.com/kubernetes/kubernetes/pull/78819)
- Webhooksがnetwork proxyをalpha機能としてサポートしました。[#85870](https://github.com/kubernetes/kubernetes/pull/85870)
    - :memo: つまり、認証認可用のwebhookをnetwork proxyにも設定できます。
- クライアント証明書のファイルが提供/変更された場合、新規接続用にファイルをリロードし、それまでの接続はクローズします。[#79083](https://github.com/kubernetes/kubernetes/pull/79083)
- kubeconfigファイル、またはkubeletの`--tls-server-name`フラグによりTLSサーバ名を上書きできるようになりました。[#88769](https://github.com/kubernetes/kubernetes/pull/88769)

## :microscope: Misc (その他の軽微な修正)

> :memo: 個人的な注目ポイントはkube-apiserverのlogがgreppableになったこと、`/readyz`がシャットダウン時に正しいタイミングでエラーを返すようになったこと、kube-apiserverのローリングアップグレード中にwatch(主にkubelet/kube-proxy)が壊れる問題が修正された点です。

- api-serverのlogをgrepしやすいフォーマットに修正しました。[#87203](https://github.com/kubernetes/kubernetes/pull/87203)
- 必須ではない値が設定されていないリクエストをkubectlが間違えてリジェクトしないように、nullが設定されているOpenAPI schemaを公開されないようフィルタしました。[#85722](https://github.com/kubernetes/kubernetes/pull/85722)
- シャットダウン開始後、/readyzがerrorを即座に返すよう修正しました。以前は--shutdown-delay-durationで指定された時間が経過されるまでエラーになっていませんでした。[#88911](https://github.com/kubernetes/kubernetes/pull/88911)
- watchリクエスト中にkube-apiserverでメモリリークが発生する可能性のある問題を修正しました。[#85410](https://github.com/kubernetes/kubernetes/pull/85410)
- shared objectを何度も変更しようとするEndpointSlice controllerのバグが修正されました。[#85368](https://github.com/kubernetes/kubernetes/pull/85368)
- コントロールプレーンのローリングアップグレード中にEtcdのLISTが大量に走り可用性が落ちる問題が修正されました。[#86430](https://github.com/kubernetes/kubernetes/pull/86430)
- 複数バージョンを定義したCustom Resource(CR)が、何もしない(no-op)patchやCRの更新時に`metadata.generation`がインクリメントされ問題が修正されました。[#88995](https://github.com/kubernetes/kubernetes/pull/88995)
- サブプロトコルのネゴシエーションのため、クライアントとサーバのprotocol設定が必須になりました。[#86646](https://github.com/kubernetes/kubernetes/pull/86646)
- api-serverがサーブしている証明書のnameへ明示的にSNI証明書用のIPアドレスが設定されていた場合、接続時のレスポンスとして優先されます。[#85308](https://github.com/kubernetes/kubernetes/pull/85308)
- CVE-2020-9283を修正したバージョンの`golang.org/x/crypto`に更新しました。[#88381](https://github.com/kubernetes/kubernetes/pull/88381)
- YAMLのパース性能が向上しました。[#85458](https://github.com/kubernetes/kubernetes/pull/85458)
    - :memo: `gopkg.in/yaml.v2`がv2.2.4からv2.2.7にアップデートされています
- kube-aggregator: 現在のサービスの状態を反映するために、unavailableGaugeメトリクスが常に設定されるようになりました。[#87778](https://github.com/kubernetes/kubernetes/pull/87778)
- kube-apiserver: 退避中のgracePeriodSeconds=0を持つPodに対してprecondition.ResourceVersionを設定しようとすると競合する問題が修正されました。[#85516](https://github.com/kubernetes/kubernetes/pull/85516)
- `NewDiscoveryClientForConfig`と`NewDiscoveryClientForConfigOrDie`を利用している`kubectl get all`とclient-go discovery clientの性能劣化問題が修正されました。[#86168](https://github.com/kubernetes/kubernetes/pull/86168)
- ネットワーク切断のShared informersの信頼性が向上しました。[#86015](https://github.com/kubernetes/kubernetes/pull/86015)
- k8s.io/client-go/tools/eventsのEventRecorderが`kube-system`ではなく、`default`名前空間にeventを作成するようになりました。[#88815](https://github.com/kubernetes/kubernetes/pull/88815)