Kubernetes 1.14: SIG API Machinery の変更内容

# はじめに

ここでは、Kubernetes 1.14 の CHANGELOG から SIG API Machinery の取り組みについてまとめています。

https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG-1.14.md

# 主な変更点(1.14 What’s New)

1.14 では SIG API Machinery が主体となった大きな変更点はありませんでした。関連している変更はありますが、それは別の SIG のページを参照してください。

# 追加された点

- APIサーバーのクライアント証明書の期限を示すメトリクスである `certificate_expiration_seconds` の resolution を上げて、有効期間の短い（6時間以内）クライアント証明書に対応するように改善しました。([#74806](https://github.com/kubernetes/kubernetes/issues/74806), mxinden)
- API Aggregation のテストが conformance テストに新規追加されました([#63947](https://github.com/kubernetes/kubernetes/issues/63947), jennybuckley)
- すべてのリソースに対して `storageVersionHash` フィールドが追加されました。この値は不透明として扱わなければいけません。この値は等価的に比較することだけ有効です。([#73191](https://github.com/kubernetes/kubernetes/issues/73191), caesarxuchao)
    - :memo: 不透明というのは [Opaque_data_type](https://en.wikipedia.org/wiki/Opaque_data_type) という意味のようです。
    - :memo: APIResource リソースに `storageVersionHash` のフィールドが追加されたという話です。これは その APIResource の etcd に保存されている内部ストレージバージョンを取得するために追加されたフィールドのようです。
- 次のメトリクスに `dry_run` ラベルが追加されました。（dryRun query を切り分けるため） また、`"Content-Type: apply-patch+yaml"` での PATCH リクエストを切り分けるため `verb` ラベルに `APPLY` value が追加されました。これは実験的な値で ServerSideApply alpha機能を有効にした場合のみ有効です。([#74997](https://github.com/kubernetes/kubernetes/issues/74997), jennybuckley)
    - `apiserver_request_total`
    - `apiserver_request_duration_seconds`
    - :memo: 個人的に待っていた [ServerSideApply](https://github.com/kubernetes/kubernetes/issues/73723) が v1.14 で Alpha として追加されましたが、ChangeLog にはここにしか記載がないようです :cry:

# バグ修正等

- client-go: `PortForwarder.GetPorts()` はポートフォワーダの設定時に最初にローカルポートが指定されていなかった場合でも正しいローカルポートを返すようになりました。([#73676](https://github.com/kubernetes/kubernetes/issues/73676), martin-helmich)
- admission webhook で送られるオブジェクトのデータの中に `apiVersion/kind` が含まれていなかった問題が修正されました([#74448](https://github.com/kubernetes/kubernetes/issues/74448), liggitt)
    - :memo: オブジェクトの作成または変更のリクエストを投げると apiserver から admission webhook を受ける際に生のオブジェクトのデータ送られますがそこに GVK (GroupVersionKind) が含まれていないということのようです
    - :memo: これが含まれていないと json.Unmarshal するときなどに困ることがあるようです
- `crd_autoregister` と `crd_finalizer`, `crd_naming_condition_controller` が Prometheus メトリクスとして公開されました。([#71767](https://github.com/kubernetes/kubernetes/issues/71767), roycaihw)
    - :memo: これらのメトリクスはよくある Informer のキューのメトリクスのようです
    - :memo: これはもともと追加されていたようですが名前が不正で登録に失敗していたため名前を変えて再公開したという体のようです
    - :memo: PR の修正を見る限りは `crd_autoregister` ではなく `crd_autoregistration_controller` のような気がします
- admission 関連のメトリクスが秒単位に修正されました([#72343](https://github.com/kubernetes/kubernetes/issues/72343), danielqsj)
    - :memo: 従来は `*_admission_latencies_seconds` のようなメトリクスが実際にはマイクロ秒を返していましたが、秒を返すように修正されたということのようです
- HTTP2 ロードバランサーによって接続が切れた場合にエラーログが出力されていましたが、それをデフォルトではスキップするように変更しました (多分[#73277](https://github.com/kubernetes/kubernetes/pull/73277))
- kubectl が kube-apiserver からディスカバリー情報を取得するときに10秒より速くしました([#73345](https://github.com/kubernetes/kubernetes/issues/73345), sttts)
    - :memo: apigroup が 40 以上登録されているような apiserver だとこれらをシーケンシャルに取得していたため遅くなっていた問題があり、これを並列で取得することで高速化したようです
- 同じイベントのセットを何度も送信しないように監視し、watcher が間に合うようにしました([#73845](https://github.com/kubernetes/kubernetes/pull/73845), wojtek-t) ([#73277](https://github.com/kubernetes/kubernetes/pull/73277), smarterclayton)
    - :memo: apiserver の API をウォッチするライブラリで初回のイベントを送ったあとに再度同じイベントを送るようになっていたため、それを送らないように修正したということのようです
- `default/kubernetes` Service の endpoint の作成を apiserver リクエストを受け付けることができるようになる(readiness)前に作成していた問題を修正しました。また kube-apiserver が以前にクラッシュした場合などで古い endpoint が残っている場合があるので起動時に古いエンドポイントが合った場合は削除するようにしました。([#74668](https://github.com/kubernetes/kubernetes/issues/74668), sttts)
    - :memo: 原文だと同じ修正が微妙に異なる文言で2行ありましたが1行にしています
- admission webhook の validating/mutating のタイムアウトを短縮するための設定フィールドを追加します。 タイムアウト値は1から30秒の間でなければなりません。 指定しない場合のデフォルトは30秒です。([#74562](https://github.com/kubernetes/kubernetes/issues/74562), roycaihw)
- jsonパッチに10,000を超える操作が含まれている場合、kube-apiserverと汎用apiserverライブラリで構築されたapiserverの両方を含むapiserverは、413 RequestEntityTooLargeエラーを返すようになりました。([#74000](https://github.com/kubernetes/kubernetes/issues/74000), caesarxuchao)
    - :memo: CVE-2019-1002100 の修正パッチですね
- 複数のマイナーバージョンのapiserverが混在している環境で監視イベントの処理に問題があったため修正しました([#73482](https://github.com/kubernetes/kubernetes/issues/73482), liggitt)
    - :memo: ストレージから event をデコードするときにサポートしていないバージョンのリソースが合った場合にエラーにしていた部分を、エラーにしないようにしたようです
- `[start:end:step]` を含む jsonpath が正しく評価されるようになりました([#73149](https://github.com/kubernetes/kubernetes/issues/73149), liggitt)
- Finalizer を含むリソースに対して繰り返し削除を行った場合に、 `metadata.deletionTimestamp` が未来に移動されなくなりました。([#73138](https://github.com/kubernetes/kubernetes/issues/73138), liggitt)
- 長い duration の間も `watch.Until` が動作するようになりました([#67350](https://github.com/kubernetes/kubernetes/issues/67350), tnozicka)
    - :memo: RetryWatcher という新たな Watcher が追加され、一度接続が途切れても最後の resourceVersion が etcd に残っていれば再開して Watch し続ける？
- CRD webhook converter のためのメトリクスが追加されました([#74376](https://github.com/kubernetes/kubernetes/issues/74376), mbohlool)
- いくつかのプラットフォームで keymutex がクラッシュする問題が修正されました([#74348](https://github.com/kubernetes/kubernetes/issues/74348), danielqsj)
- Aggregated API Server から OpenAPI 仕様を集約する際の kube-apiserver の CPU負荷を大幅に削減しました。([#71223](https://github.com/kubernetes/kubernetes/issues/71223), sttts)
- 終了処理の前に送信しているデータを失わないように apiserver のグレースフルシャットダウンを修正しました([#72970](https://github.com/kubernetes/kubernetes/issues/72970), sttts)
    - :memo: http2の場合などで正常にグレースフルシャットダウンできていなかったようです

# alpha, beta のみ記載の変更点から抜粋

- Admission webhook のルールに namespaced または cluster-scoped のリソースを限定できるようになりました。"Cluster" または "Namespaced" または "*" を指定することで限定できます。([#74477](https://github.com/kubernetes/kubernetes/issues/74477), liggitt)
  - :memo: beta.1 の Changes
- CustomResourceDefinition OpenAPI の validation schema で nullable をサポートしました([#74804](https://github.com/kubernetes/kubernetes/issues/74804), sttts)
- 以下のメトリクスの名前を latency から duration に変更しました。([#74418](https://github.com/kubernetes/kubernetes/issues/74418), danielqsj)
  - `rest_client_request_latency_seconds` -> `rest_client_request_duration_seconds`
  - `apiserver_proxy_tunnel_sync_latency_secs` -> `apiserver_proxy_tunnel_sync_duration_seconds`
  - `scheduler_scheduling_latency_seconds` -> `scheduler_scheduling_duration_seconds`
  - :memo: beta.1 の Changes
- PriorityClass APIが `scheduling.k8s.io/v1` で提供されました。内容は beta から変更ありません。それに伴い `scheduling.k8s.io/v1beta1` のバージョンは deprecated となり、v1.17 でデフォルトで廃止予定です。([#73555](https://github.com/kubernetes/kubernetes/issues/73555), bsalamat)
- Ingress リソースが `networking.k8s.io/v1beta1` で利用可能になりました。`extensions/v1beta1` は deprecated となり、v1.18 で廃止予定です。([#74057](https://github.com/kubernetes/kubernetes/issues/74057), liggitt)
- 以下の apiserver のメトリクス名がガイドラインに従った名前に変更されました。それに伴い以前のメトリクスは deprecated になりました。それらは将来のリリースで削除される予定です。([#72336](https://github.com/kubernetes/kubernetes/issues/72336), danielqsj)
  - 追加されたメトリクス
      - `apiserver_request_total`
      - `apiserver_request_latency_seconds`
      - `apiserver_dropped_requests_total`
      - `etcd_helper_cache_hit_total`
      - `etcd_helper_cache_miss_total`
      - `etcd_helper_cache_entry_total`
      - `etcd_request_cache_get_latency_seconds`
      - `etcd_request_cache_add_latency_seconds`
      - `etcd_request_latency_seconds`
      - `transformation_latencies_seconds`
      - `data_key_generation_latencies_seconds`
  - 廃止予定となったメトリクス
      - `apiserver_request_count`
      - `apiserver_request_latencies`
      - `apiserver_request_latencies_summary`
      - `apiserver_dropped_requests`
      - `etcd_helper_cache_hit_count`
      - `etcd_helper_cache_miss_count`
      - `etcd_helper_cache_entry_count`
      - `etcd_request_cache_get_latencies_summary`
      - `etcd_request_cache_add_latencies_summary`
      - `etcd_request_latencies_summary`
      - `transformation_latencies_microseconds`
      - `data_key_generation_latencies_microseconds`

# 所感

1.14 では apiserver の高速化やメトリクスの整理などが行われているようです。
それとまだ Alpha ですが個人的には待望の [ServerSideApply](https://github.com/kubernetes/enhancements/issues/555) の機能が追加されました。今までは kubectl apply 相当の機能を利用する場合は kubectl バイナリを利用することが簡単でしたが、client-go などから直接 apply 相当のことができるようになりそうです。
利用方法は[こちら](https://kubernetes.io/docs/reference/using-api/api-concepts/#server-side-apply)に記載されていますが、PATCHのリクエストを `application/apply-patch+yaml`つきでリクエストすることでできるようです。なお、ServerSideApply では `last-applied` アノテーションは利用せず `metadata.managedFields` でそのあたりを管理するようになるようです。
~~managedFields の詳しい動作については別途調べてまとめたいと思います。~~
@superbrothers によって[まとめた記事](https://qiita.com/superbrothers/items/aeba9406691388b6a19e)が公開されました :tada: