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

ZLabによる、他SIGのv1.16変更点の紹介は[こちら](https://qiita.com/uesyn/items/0246346d8958318fa1d4#_reference-b7f8be141a930bd199a0)

## :memo: はじめに

ついにKubernetes 1.16がリリースされました :tada:
今回の目玉は何と言ってもCRDとAdmission WebhookのGAです！
それに伴いdeprecatedになった`apiextensions.k8s.io/v1beta1`、`admissionregistration.k8s.io/v1beta1`APIはv1.19に非公開になります。また、Webhook GAのタイミングでデフォルト値や必須値が変わったり注意点もあります。CRD/Webhookユーザの皆さん、一緒に頑張っていきましょう :muscle:

## 主要な変更

ここからは、[ChangeLog v1.16](https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG-1.16.md#v1160)のSIG-API Machineryの内容だけピックアップしていきます。
:memo: マークはChangeLog関係なく私の所感です。

### Betaに昇格した機能

* WatchBookmarkがbetaに昇格し、デフォルトで有効になりました。これによりクライアントはWatchイベントをリクエストするときにBOOKMARKタイプを設定できるようになります。[#79786](https://github.com/kubernetes/kubernetes/pull/79786)
  * :memo: WatchBookmarkは前回の[v1.15](https://qiita.com/Ladicle/items/1cfee78ef0b520df1d4a#alpha%E3%81%AA%E5%A4%89%E6%9B%B4)の時にも紹介したやつですが、Watchのパフォーマンス改善のために追加された機能です。おそらく次の1.17にはstableになるでしょう。詳しいロジックに興味がある方は[KEP](https://github.com/kubernetes/enhancements/blob/master/keps/sig-api-machinery/20190206-watch-bookmark.md)を読むとわかります。

* Server-side applyがvalidationフィールドでOpenAPIを定義しているCRDで利用できるようになりました。[#77354](https://github.com/kubernetes/kubernetes/pull/77354)
    * :memo: 待っていたCRDのServer-side apply! ついにやってきました。Siver-side applyについては1.14の時の記事ですが @superbrothersさんが [Qiita: SSA v1.14 alpha](https://qiita.com/superbrothers/items/aeba9406691388b6a19e) で解説しています。
* CRDのdefaultingがbetaに昇格し、デフォルトで有効になりました。詳細は[こちら](https://kubernetes.io/docs/tasks/access-kubernetes-api/custom-resources/custom-resource-definitions/#specifying-a-structural-schema)をどうぞ。[#81872](https://github.com/kubernetes/kubernetes/pull/81872)
    * :memo: 1, 2年前くらいからstefanさんがKubeConでこんな機能を入れたいと発表してたやつがついにデフォルト有効になりました。k8sjpとかでも紹介しましたが、資料わかりやすいので検索してみてください。

### Misc

* Graceful Shutdownを遅らせるための `--shutdown-delay-duration`フラグがkube-apiserverに追加されました。この遅延時間は`/healthz`はsuccessし続けるのでリクエストは受け付けますが、`/readyz`はfailureステータスになります。これにより、SDNが全ノードのiptablesを変更してトラフィックを止める時間を作ることができます。[#74416](https://github.com/kubernetes/kubernetes/pull/74416)
* kube-apiserverにHealthチェック用の`/livez`も追加されました。起動フラグの `--maximum-startup-sequence-duration`を使うと、起動時のチェックを遅延できるため、即死するのを防げます。[#81969](https://github.com/kubernetes/kubernetes/pull/81969)

* :memo: 記憶が正しければ上2つとも2019 KubeCon Euroで発表があったkube-apiserverを安全にシャットダウンするために提案されていた機能です。ここら辺までk8sの手が回ってきたんだなーという感じですね。この手のReadHatが強いなという印象。

## そのほかの変更

### CRD系
* メタデータを除いてOpenAPI定義内のpruneされるCRDのデフォルト値を検証するようになりました。 [#78829](https://github.com/kubernetes/kubernetes/pull/78829)
* CRDの更新を反映するために、古くなったCRストレージを適切に再生成するようになりました [#79114](https://github.com/kubernetes/kubernetes/pull/79114)
* `CVE-2019-11247`が修正されました。これは、APIサーバがCRによる範囲外のアクセスを許可してしまうというものです。[#80750](https://github.com/kubernetes/kubernetes/pull/80750)
* conditionの`apiextensions.<v1beta1/v1>.CustomResourceDefinitionStatus`が必須値からオプションになりました。[#64996](https://github.com/kubernetes/kubernetes/pull/64996)
* CRのサーバセットアップ中にそのAPIリクエストがきた場合、404を返すようになりました。[#81244](https://github.com/kubernetes/kubernetes/pull/81244)
* CRDのOpenAPIが正しく公開できるようになったので、PATCHタイプがサポートしました。[#81515](https://github.com/kubernetes/kubernetes/pull/81515)
* CRDのステータスが変更された時のみ`LastTransitionTime`が更新されるようになりました。[#69655](https://github.com/kubernetes/kubernetes/pull/69655)
* 古いCRにもEtcdから読み出すときに`metadata.generation`が付与されていなければセットするようになりました。[#82005](https://github.com/kubernetes/kubernetes/pull/82005)
* CRDのk8sコミュニティ用APIグループを保護するため、アノテーションにPRへのリンクを値にもつ`api-approved.kubernetes.io`キーが設定されるようになりました。詳しくは[#1111](https://github.com/kubernetes/enhancements/pull/1111)をみてください。[#79992](https://github.com/kubernetes/kubernetes/pull/79992)
* CRのバリデーションエラーメッセージが改善されました。[#81212](https://github.com/kubernetes/kubernetes/pull/81212)

### Misc
* rawフィールドが必須値になっていた`io.k8s.apimachinery.pkg.runtime.RawExtension`のバグが修正されました。[#80773](https://github.com/kubernetes/kubernetes/pull/80773)
* Updateリクエスト時に、キャッシュを使った事前の状態チェックに失敗してもエラーに落とすのではなくリトライするように修正しました。[#82303](https://github.com/kubernetes/kubernetes/pull/82303)
* バックエンドによってプロキシの接続が切られた際に、過剰なスタックトレースがログに保存されないように修正しました。[#82588](https://github.com/kubernetes/kubernetes/pull/82588)
* タイムアウトを持つ非同期処理に必要なため、RateLimiterにContextベースの関数を追加しました。[#79375](https://github.com/kubernetes/kubernetes/pull/79375/)
* ScaleInterfaceにpatchが追加されました [#80699](https://github.com/kubernetes/kubernetes/pull/80699)
* kms-pluginのステータスをチェックするために、KMSプロバイダのhealthzをkube-apiserverのEncryptionConfigから設定するようになりました。[#78540](https://github.com/kubernetes/kubernetes/pull/78540)
* ReferectorのListAndWatch関数が"connection refused"エラーを返してもリトライしないバグが修正されました。[#81634](https://github.com/kubernetes/kubernetes/pull/81634)
* バックエンドにServiceを使っているAggregated APIに対する`/`のリクエストにHTTP 2xx番以外のレスポンスが返る問題が修正されました [#79895](https://github.com/kubernetes/kubernetes/pull/79895)
* `pkg/api/ref`から`GetReference()`と`GetPartialReference()`がなくなったので代わりに`staging/src/k8s.io/client-go/tools/ref`を使うようにしましょう。[#80361](https://github.com/kubernetes/kubernetes/pull/80361)
* Pod Overhead用にPodSpecとRuntimeClassタイプにOverheadフィールドが追加されました [#76968](https://github.com/kubernetes/kubernetes/pull/76968)

## :memo: おわりに
Webhookに注意しましょうといったものの補足してなかったので軽く説明しておくと、`sideEffect`のデフォルト値がなくなって必須値になりました(dry-runの挙動に影響があるやつ)。デフォルト使ってた方は適切に設定しておきましょう。また、`failurePolicy`がFailになったので証明書やサーバ障害でAPI受け付けなくなったりするので雑にWebhookを扱わないようにしましょう。Deploymentに対して全NSの更新系リクエストのWebhookとか作ってデッドロックすると悲惨です(これについてはv1.7 or v1.8あたりからWebhook Bootstrappingの機能が入って解決するかも)。セレクタとか使って範囲は必要最低限に絞りましょう。CRDもversionsへの移行とか色々あるのですが、controller-toolsの動向見つつやっていきましょう。