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

他のSIGについても順次公開される予定です :muscle: 

## :memo: はじめに

Kubernetes v1.17 が12/8にリリースされました!!! 今回はAPI Machineryに大きな変更はありませんが、細かい変更は通常通り一杯あります。延期になったAPI Priority & FairnessやSidecarあたりは次バージョンで動きがあるかもしれません... :eyes:

k8s本体ではないですが、client-goライブラリを直接使ってコントローラ等を書いている人には注意点があります。v1.17.0では、DiscoveryClientがAPIサーバからリソースを取得する際に`Throttling request`メッセージが多発する点です。このバグ[#86149](https://github.com/kubernetes/kubernetes/issues/86149)は既に解決済みで、次のv1.17.1に修正が入ります。

ここからは、[ChangeLog v1.17](https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG-1.17.md#api-machinery)のSIG-API Machineryの内容だけピックアップしていきます。`そのほかの変更内`の分類は自身が見やすいように分類したもので公式のものではありません。
また、:memo: マークはChangeLog関係なく所感や追加の解説です。

## 主要な変更

`特になし`

## そのほかの変更

### :sparkles: 追加機能

> :pencil: 便利機能としては、apiserverの各種証明書が再読み込みされるようになっています
> また#72170のベースになっている[#59848](https://github.com/kubernetes/kubernetes/issues/59848)は長らく続いていた話がついに進捗しました! 読むと面白いと思うので個人的にオススメです :eye: kind/bugの#83520も同じ話です

- kube-apiserverが配信している証明書を毎分diskから読み込むようになりました ([#84200](https://github.com/kubernetes/kubernetes/pull/84200))
- client-ca bundleのファイルに変更があった場合、generic-apiserverをベースとしている全てのサーバで動的に読み込まれるようになりました ([#83579](https://github.com/kubernetes/kubernetes/pull/83579))
- kube-apiserverがSNI証明書をディスクから毎分読み込むようになりました ([#84303](https://github.com/kubernetes/kubernetes/pull/84303))
- informer-genでパッケージ名に`.`を含められるようになりました ([#82410](https://github.com/kubernetes/kubernetes/pull/82410))
- kube-proxyの`--config`フラグで指定した設定ファイルが、strict deserializationを使って読み込まれるようになり、設定ファイルが重複 or 存在しないフィールドを保持していた場合にエラーになります。これにより、予期せず不正な設定ファイルでサーバが起動してしまうことを防げるようになりました。 ([#82927](https://github.com/kubernetes/kubernetes/pull/82927))
- `--runtime-config=api/beta=fase`と`--feature-gates=AllBeta=false`フラグが追加され、一括でBeta機能を無効化が可能になりました ([#84304](https://github.com/kubernetes/kubernetes/pull/84304))
- kube-apiserverに`--show-hidden-metrics-for-version`フラグが追加されました。これを有効にすると、前Minorリリースでdeprecatedになった非公開メトリクスが全て表示されます ([#84292](https://github.com/kubernetes/kubernetes/pull/84292))
- CRD schemaのOpenAPI v3 formatについてドキュメントが追加されました ([#85381](https://github.com/kubernetes/kubernetes/pull/85381))
- 今まではv1.15以前のk8sとの後方互換性のためv1beta1もサポートする必要がありましたが、1.17+のAPIサーバでは、Mutating/ValidatingWebhookConfigurationで`v1`のAdmissionReviewのみ受け付けるように設定できるようになりました ([#82707](https://github.com/kubernetes/kubernetes/pull/82707))
- ListのResourceVersionオプションは、常に最小許容ResourceVersionとして処理されるようになりました。以前は、クライアントがwatchキャッシュを無効化している場合、List時に指定した特定のResourceVersionのsnapshotが取得できました。クライアントリクエストが現在の状態よりも新しいResourceVersionを要求した場合、TimeoutErrorを返し、数秒以内のリトライを推奨します。この挙動により、watchキャッシュの有効・無効に関わらず単一リソースの取得とList時の一貫性が保たれます。 ([#72170](https://github.com/kubernetes/kubernetes/pull/72170))

### :up: バージョンup

> :pencil: CRD defaultingがついにGAになりました :clap: また、AdmissionRegistrationとそのConfigurationもv1に上がっています!

- Mutating/Validating Admission Webhookプラグインが `admissionregistration.k8s.io/v1` APIを呼ぶようになりました ([#80883](https://github.com/kubernetes/kubernetes/pull/80883))
    - :pencil: 次のPRに関連していて、kube-apiserverの起動フラグで指定する設定ファイルバージョンも変更になっています
- kube-apiserverに`--admission-control-config-file`で指定するAdmissionWebhook(WebhookAdmissionConfiguration)とResourceQuota(ResourceQuotaConfiguration)の設定ファイルバージョンが`apiserver.config.k8s.io/v1`に上がりました ([#85138](https://github.com/kubernetes/kubernetes/pull/85138), [#85099](https://github.com/kubernetes/kubernetes/pull/85099))
- CRDのdefaultingがGAになりました。FeatureGateの`CustomResourceDefaulting`はv1.18で削除されます ([#84713](https://github.com/kubernetes/kubernetes/pull/84713))

### :warning: セキュリティ関連

- 危険なJSONの構築方法を取っている箇所が修正されました ([#81158](https://github.com/kubernetes/kubernetes/pull/81158))
    - :pencil: CNCFがk8sのペネトレーションテストを委託した時に報告された脆弱性の1つです(TOB-K8S-016の重要度は低)。フルレポートは[Kubernetes Final Report](https://github.com/kubernetes/community/blob/master/wg-security-audit/findings/Kubernetes%20Final%20Report.pdf)に公開されています
- CVE-2019-11253の対応で、サーバのリソースを大量に消費する巨大なor不正な形式のデコードを制限するという修正です。通常のAPIリクエスト(Create/Delete/Update/Patch)のBodyは3MBに制限されました。 ([#83261](https://github.com/kubernetes/kubernetes/pull/83261))
    - :pencil: v1.13以前のデフォルトRBACでは匿名ユーザもこのリクエストの送信が可能なこともあり、初期重大度が高と評価され一時期話題になってたやつです

### :bug: バグ修正系

> :pencil: 今回はgorutineリークのバグ修正が多いですね。[Understanding real-world concurrency bugs in Go](https://dl.acm.org/citation.cfm?id=3304069), ASPLOS’19 を思いだします...

- kube-apiserverのWebsocket WatcherによるEncoding中にエラーが発生するとgorutineがリークするバグが修正されました ([#84693](https://github.com/kubernetes/kubernetes/pull/84693))
- Endpointに変更がない場合でもEndpointSlice機能がが後から有効になった時にreconcileするよう修正されました ([#84421](https://github.com/kubernetes/kubernetes/pull/84421))
- IntOrString型のサイズの決まっていないintがproto.Mergeで壊れる問題が修正されました ([#83956](https://github.com/kubernetes/kubernetes/pull/83956))
    - :memo: Protoのserializationではすでにint64が使われていたため、後方互換性の観点からintからint64への変更になっています
- client-goのworkqueueにおいて、長いdelayが追加queueがキューイングされた時のメモリとタイマーのリークを防ぐため、アロケーション方法が修正されました ([#83945](https://github.com/kubernetes/kubernetes/pull/83945))
- informerが即座にdelete/create(replace)したオブジェクトのAddedのNotificationをロストする問題が修正されました ([#83911](https://github.com/kubernetes/kubernetes/pull/83911))
- `x-kubernetes-int-or-string`タイプを持つCRDのCRにアクセスしようとするとpanicする問題が修正されました ([#83787](https://github.com/kubernetes/kubernetes/pull/83787))
- kube-apiserverへのリクエストがtimeoutしてもgorutineがリークしないよう修正されました ([#83333](https://github.com/kubernetes/kubernetes/pull/83333))
- informer-genがnonNamespaced tagを持つリソースのコードを正しく生成できない問題が修正されました ([#80458](https://github.com/kubernetes/kubernetes/pull/80458))
    - :pencil: nonNamespacedリソースでもinformerにnamespaceが付与されてしまっていたため、社内ではv1.17が出るまでコード生成した後、patchする暫定対応してました
- Internal APIサーバ通信がgoroutineの増大によってAPIサーバのパフォーマンスに影響を与えているため、QPSのリミットが排除されました ([#80465](https://github.com/kubernetes/kubernetes/pull/80465))
    - :pencil: `--max-mutating-requests-inflight`など、clientとの通信は制限できる機能がすでに入っている & この機能を削除すると大幅な変更になるためQPSに-1設定するというhackyな対応になっています。今後Refactoringされるようです。そしてこの修正が`はじめに`で紹介したclient-goのバグに関連しています
- KMSとetcdのヘルスチェックが正しく `/lizvez`, `/readyz`エンドポイントに設定されていない問題が修正されました([#82713](https://github.com/kubernetes/kubernetes/pull/82713))
- バックエンドによってプロキシとの通信が切断された時に、不正なトレースが記録されるのを防ぐよう修正されました(デグレ対応) ([#82588](https://github.com/kubernetes/kubernetes/pull/82588))
- kubectlがrequiredフィールドのnull値を拒否するのを防ぐため、OpenAPI Schemaの内容をフィルタするようになりました ([#85722](https://github.com/kubernetes/kubernetes/pull/85722))
- kube-apiserverが`gracePeriodSeconds=0`の時にPodを何度も削除しようとconflictエラーが発生する問題を、削除開始時にprecondition.resourceVersionを取り除くことで解決しました ([#85516](https://github.com/kubernetes/kubernetes/pull/85516))
- http.CloseNotifierの代わりにcontextを使ってclientのクローズを検出するように変更しました。これにより、protoのリクエストがHTTP/2.xの場合、使用するgorutineが1つ削減できます ([#85408](https://github.com/kubernetes/kubernetes/pull/85408))
    - :pencil: http.CloseNotifierは非推奨になっています
- kube-apiserverの受け付けるpatchリクエストサイズが1MB以下になるように修正されました(デグレ対応) ([#84963](https://github.com/kubernetes/kubernetes/pull/84963))
- コンポーネント・ステータスをテーブル形式で表示するためのコンバータが追加されました(デグレ対応) ([#85174](https://github.com/kubernetes/kubernetes/pull/85174))
- CRにresourceVersionが付与されていなかった場合、scaleに失敗する問題が修正されました ([#80572](https://github.com/kubernetes/kubernetes/pull/80572))
- go-clientのreflactorが再度Listを呼び出したとき、すでに処理したものを取得しないよう、ListオプションのResourceVersionにはreflectorの最後に同期したリソースバージョンが設定されるようになりました。サーバがHTTP 410(Gone)ステータスを返してきた場合は、resourceVersionに空を設定してフォールバックします ([#83520](https://github.com/kubernetes/kubernetes/pull/83520))
    - :pencil: #72170と関連するPR
- v1.15.xより前のバージョンとの後方互換性を保つため、non-structural schemaなCRDはOpenAPIでpublishされなくなりました ([#82653](https://github.com/kubernetes/kubernetes/pull/82653))
- CRDが`type`フィールドの値として`array`を持ち、そのネスト配列が`items`フィールドを持っていた場合、バリデーションに失敗する問題が修正されました ([#85223](https://github.com/kubernetes/kubernetes/pull/85223))
- IPv6がアサインされている場合はIPv6なエンドポイントでkube-apiserverが公開されるようになりました ([#84727](https://github.com/kubernetes/kubernetes/pull/84727))

### Misc
- FeatureGateの`RequestManagement`が`APIPriorityAndFairness`にリネームされました。APIPriorityANdFairnessはまだalpha & 機能は実装されていません ([#85260](https://github.com/kubernetes/kubernetes/pull/85260))
- サンプル用のAPIグループ名が`wardle.k8s.io`から`wardle.example.com`にリネームされました ([#81670](https://github.com/kubernetes/kubernetes/pull/81670))

## :memo: おわりに

今回...(今回も)liggittさん大活躍です。理解しやすいIssue/PRを書かれるので参考になります :pray: