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

## はじめに

ついにKubernetes v1.15がリリースされました :tada:
API Machineryは、API serverやAdmission Control、CRDなどなどKubernetesのAPIに関わる機能をまるっと担当しているSIGですが、CRDのGAが近いこともあり、CRD周りで多くの機能が追加されています。

ここからは、ChangeLog v1.15のAPI Machineryに関連する変更点に絞って紹介していきます。
<https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG-1.15.md>

:memo: がついた文章は、ChangeLogの公式内容ではなく、私の所感を表しているのでご注意ください


## 1.15 What’s New     :sparkles:


### CustomResourceDefinitions Pruning

-   データの一貫性とセキュリティを高めるためのPruning機能がAlphaからBetaに昇格しました
    -   これは、Kubernetes APIへのリクエストデータから"unknown"なフィールドを取り除いてくれる機能です
    -   "unknown"かどうかは、OpenAPI validation schemaによって判定されます(トップレベル or バージョンごとの設定が必須)
    -   Nativeリソースはすでに対応済みです
-   v1.15でのデフォルトでは `spec.preserveUnknownFields: false` ですが、GA時にはデフォルトtrueになる予定です
    -   :memo: CRDを使った開発者でValidation設定していない人はそろそろ対応を始めた方が良いでしょう。 値が飛ぶと悲惨なので設定の生成を自動化したり、テスト強化したいところ


### CustomResourceDefinition Defaulting

-   CRDが新しくデフォルティングをサポートしました
    -   OpenAPI validation schemaで `default` が使えるようになります
    -   1.15ではalphaです
-   :memo: 去年からまってた機能。めでたい。これでSyntaxはこちら、SemanticなvalidationはAdmissionControllerと使い分けられるんじゃないだろうか


### CustomResourceDefinition OpenAPI Publishing

-   OpenAPI specが `/openapi/v2` から引ける機能がv1.15からはBetaに昇格しました
    -   kubectlのclient-side validationとか、explainとか、client generatorとかその他色々なコンポーネントで利用されています
    -   このOpenAPI schemaはCRDでも利用できます
    -   修正が必要なscheme用に `NonStructuralSchema` conditionも追加されています
-   :memo: explainとかが整備されればCRDの使い方がkubectlからも分かりやすくなり、CRD validationをメンテするメリットも増えるはず


### :memo: この辺りの話をもう少し日本語で知りたい人向け

古いので参考程度に

-   [Recap API Machinery Deep Dive - Speaker Deck](https://speakerdeck.com/ladicle/recap-api-machinery-deep-dive?slide=8)
-   [CustomResourceDefinitions の Validation の紹介 - Qiita](https://qiita.com/shmurata/items/86f3a0c2a2431cec410e)


## 既知の問題点

-   なし


## アップグレード前に絶対に確認が必要な変更点

-   `k8s.io/kubernetes` 等のリポジトリ依存管理ツールが、go moduleに対応しました ([#74877](https://github.com/kubernetes/kubernetes/pull/74877))
    -   client-goでの取り扱い方法など、詳しくは[go-modules](http://git.k8s.io/client-go/INSTALL.md#go-modules)を参照してください
        -   :memo: Go moduleについてはclient-goのドキュメント内でも参照している本家の[wiki](https://github.com/golang/go/wiki/Modules)が一番まとまっているかと


## 非推奨 or 廃止される機能


### kube-apiserver

-   `--enable-logs-handler` が非推奨になりました。v1.19で廃止予定です ([#77611](https://github.com/kubernetes/kubernetes/pull/77611))
    -   :memo: [Directory traversal (or path traversal)? · Issue #77182 · kubernetes/kubernetes](https://github.com/kubernetes/kubernetes/issues/77182#issuecomment-487439173) にまつわる話で、RBACでちゃんと制限かけられているがdefault有効なのはよくないのでGAに向けて無くしましょうという話


### API

-   Ingressリソースの `extensions/v1beta` はv1.19で廃止されるので `networking.k8s.io/v1beta1` (v1.14+) に移行しましょう
-   NetworkPolicyの `extensions/v1beta1` はv1.16で廃止されるので `networking.k8s.io/v1` (v1.8+) に移行しましょう
    -   既存のデータは `networking.k8s.io/v1` APIから取得できます
-   PodSecurityPolicyの `extensions/v1beta1` はv1.16で廃止されるので `policy/v1beta1` (v1.10+) に移行しましょう
    -   既存のデータは `policy/v1beta1` APIから取得できます
-   DaemonSet、Deployment、ReplicaSetの `extensions/v1beta1`, `apps/v1beta1`, `apps/v1beta2` はv1.16で廃止されるので `apps/v1` (v1.9+) に移行しましょう
    -   既存のデータは `apps/v1` APIから取得できます
-   PriorityClassリソースの `scheduling.k8s.io/v1beta1` & `scheduling.k8s.io/v1alph` はv1.17で廃止されるので、 `scheduling.k8s.io/v1` (v1.14+)に移行しましょう
    -   既存のデータは `scheduling.k8s.io/v1` APIから取得できます
-   v1.14から非推奨になっているList APIの `export` クエリはv1.18で削除されます
-   Event API `events.k8s.io/v1beta1` の `series.state` フィールドが非推奨になりました。v1.18で削除されます


## 注目機能


### Stableな変更

-   kube-apiseverの `watch` 用に `--watch-cache-size` フラグが有効になりました ([#74321](https://github.com/kubernetes/kubernetes/pull/74321))
    -   :memo: 廃止になった `series.state` もそうだが、今Event APIは主にパフォーマンス面で再設計が走っているところ


### Betaになった変更

-   AdmissionWebhookでリソースに対して `apps/v1 deployments` などの単一バージョンを指定できるようになりました
    -   他のバージョンのリソースが変更された時にも、登録した単一バージョンのリソースに対して呼び出されます
    -   これにより、新バージョンをAdmissionWebhookのアップデート無しに処理できるようになります
    -   詳しくはMutatingWebhookConfigurationとValidatingWebhookConfigurationに追加された `matchPolicy: Equivalent` のAPIドキュメントを読んでください
        -   :memo: `matchPolicy` は Exact か Equivalent で、ChangeLogの内容だけだと分かりづらいけどconversionされるようになったという話

-   BetaになったCustomResourcePublishOpenAPIについては what's new? と同じなので省略


### Alphaな変更

-   ListOptionsにalphaな `AllowWatchBookmarks` が追加されました
    -   apiserver側のWatchBookmark実装はFeatureGateから有効にできます
    -   :memo: ちょい前からWatchのパフォーマンス改善のために再設計が走っていて、その実装のBookmark使って転送量を減らそうというもの ([#74074](https://github.com/kubernetes/kubernetes/pull/74074))


### その他

-   Content-Encodingとして `proxy/transport` がサポートされました ([#76551](https://github.com/kubernetes/kubernetes/pull/76551))
-   AdmissionWebhookがscaleとdeployments/rollbackのsubresourceでも正常に呼ばれるようになりました ([#76849](https://github.com/kubernetes/kubernetes/pull/76849))
-   CRDの `spec.preserveUnknownFields` がv1beta1でfalseに設定されました。v1でtrueになります
    -   :memo: pruningの話のこと
-   chunked listの逐次処理を有効にするため、ListPager.EachListItemのユーティリティ関数がclient-goに追加されました ([#75849](https://github.com/kubernetes/kubernetes/pull/75849))


## その他の注目機能

-   `port` 設定がAdmissionWebhookConfiguration、AuditSinkWebhookConfigration、CRD ConversionWebhook、kube-aggregatorのServiceReferenceに追加されました ([#74855](https://github.com/kubernetes/kubernetes/pull/74855))
-   重複排除用のロジックがv1beta1.Event APIに入りました ([#65782](https://github.com/kubernetes/kubernetes/pull/65782))
    -   :memo: client-goのEventRecorderの実装ががっつり変わりました
-   AdmissionWebhookConfigrationに `objectSelector` が追加されました
-   WatchレスポンスがTableかPartialObjectMetadata形式への変換をサポートしました ([#71548](https://github.com/kubernetes/kubernetes/pull/71548))
-   CRD ConversionWebhookで、LabelとAnnotation以外のメータデータへの変更を無視するようになりました ([#77743](https://github.com/kubernetes/kubernetes/pull/77743))
-   ListMeta.RemainingItemCountが追加されました。List時、サーバ側にまだデータが残っている場合にはListOptions.RemainingItemCountに残りのオブジェクト数が設定されます ([#75993](https://github.com/kubernetes/kubernetes/pull/75993))
-   clientがv1 TableかPartialObjectMetadata形式のレスポンスをリクエストできるようになりました ([#77448](https://github.com/kubernetes/kubernetes/pull/77448))
-   マルチバージョンのCRDで、statusサブリソースを変更するときに発生するバージョンエラーのバグが修正されました ([#78713](https://github.com/kubernetes/kubernetes/pull/78713))
-   Delete直後に追加されたFinalizerが無視されるapiserverストレージのバグが修正されました ([#77619](https://github.com/kubernetes/kubernetes/pull/77619))
-   AdmissionWebhookでHTTP status codeに400以上を指定してrejectした場合、400ステータスコードが割り当たるようになりました ([#77022](https://github.com/kubernetes/kubernetes/pull/77022))
-   CRDの変更中にCRDにAPIリクエストが発生する一時的なバグを修正しました ([#77816](https://github.com/kubernetes/kubernetes/pull/77816))
-   client-go dynamic clientのメソッド名バリデーションを追加しました ([#75072](https://github.com/kubernetes/kubernetes/pull/75072))
-   OpenAPI v3 validation schemaに無効な正規表現が含まれている場合、structuredとは見なさなくなりました ([#78453](https://github.com/kubernetes/kubernetes/pull/78453))
-   k8s.io/apiserverとk8s.io/sample-apiserverのAPIページングの推奨値がtrueになりました ([#77278](https://github.com/kubernetes/kubernetes/pull/77278))
-   CVE-2019-11244にまつわるclient-goとkubectlがキャッシュされたdiscovery fileに対してworld-writeableパーミッションで書き込まないように修正しました ([#77874](https://github.com/kubernetes/kubernetes/pull/77874))
-   ログが溢れないようにOpenAPI aggregationログのレベルを上げました ([#75781](https://github.com/kubernetes/kubernetes/pull/75781))
-   k8s.io/client-go/dynamic/dynamicinformer.NewFilteredDynamicSharedInformerFactoryがnamespace引数を処理するようになりました ([#77945](https://github.com/kubernetes/kubernetes/pull/77945))
-   `DelayingQueue.ShutDown()` がClosedChannelのエラーを起こすことなく複数回呼び出せるようになりました ([#77170](https://github.com/kubernetes/kubernetes/pull/77170))
-   EtcdがnilなオブジェクトのUpdate/Deleteイベントを検知するとInformerがスタックするエラーを修正しました ([#76675](https://github.com/kubernetes/kubernetes/pull/76675))
-   ラベルに不正な値を設定したとき、どのラベルの値が不正かがエラーメッセージに表示されるようになりました ([#77144](https://github.com/kubernetes/kubernetes/pull/77144))
-   DryRunがPod/evictionのサブリソースに効いていないバグを修正しました([#76969](https://github.com/kubernetes/kubernetes/pull/76969))
-   DeleteCollectionエンドポイントのDeleteOptionパラメータがOpenAPI specに含まれるようになりました ([#77843](https://github.com/kubernetes/kubernetes/pull/77843))
-   ResourceQuotaControllerのデッドロッグバグが修正されました ([#74747](https://github.com/kubernetes/kubernetes/pull/74747))
    -   リソース使用量の一部しか処理できない場合にも、複数リソースを指定しているQuotaオブジェクトを部分更新できるようになりました
-   ValidatingAdmissionWebhooksがpods/binding、pods/eviction、bindingsのCREATEリクエストの時でも正常に呼ばれるようになりました ([#76910](https://github.com/kubernetes/kubernetes/pull/76910))
-   ストレージが削除された時、CustomResourceのWatchが正常に終了するようになりました ([#78029](https://github.com/kubernetes/kubernetes/pull/78029))
-   終了処理中オブジェクトの `metadata.deletionGracePeriodSeconds` が0 or nilだった場合、 `metadata.finalizers` から全てのfinalizerを削除すると即座にオブジェクトが削除されるようになりました ([#77952](https://github.com/kubernetes/kubernetes/pull/77952))
-   `rest.AnonymousClientConfig(*rest.Config) *rest.Config` というHelper関数が `Transport` と `WrapTransport` をコピーしなくなりました ([#75771](https://github.com/kubernetes/kubernetes/pull/75771))
-   Parallelize関数が非推奨になりました。代わりにParallelizeUtilを利用してください ([#76595](https://github.com/kubernetes/kubernetes/pull/76595))