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

# はじめに

Kubernetes 1.21がリリースされました :tada:

今回API Machineryの変更は少なめです。大きな変更はないですが、CronJobとPDBがついにv1になりました。
また、Generic Ephemeral VolumeとBound Service Account TokensがBetaに昇格したので本バージョンよりデフォルト有効になります。
恩恵を受ける人が多そうな変更としては、Probe失敗時のterminationGracePeriodSecondsを指定するフィールドの追加があります。

それでは、今回もAPI周りを担当するSIG-API Machineryの変更点を[CHANGELOG](https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.21.md)からピックアップします。
(:pencil: がついた文章は、CHANGELOGの公式内容ではなく筆者の補足です)

> SIG, KEPについては[コチラ](https://qiita.com/Ladicle/items/24cff72f5e8f4bd293a6)を参照

# :wastebasket: Deprecation (非推奨になったAPI)

- `etcd_object_counts`メトリクス名を`apiserver_storage_object_counts`に変更しました。元の`etcd_object_counts`メトリクスは非推奨となり、将来的に削除されます。 ([#99785](https://github.com/kubernetes/kubernetes/pull/99785))
- CronJobの`batch/v2alpha1`とそのクライアントが非推奨となり、削除されました。 ([#96987](https://github.com/kubernetes/kubernetes/pull/96987))
- クエリパラメータの`export`が完全に削除されました。(APIリソースによって一貫性がなく、v1.14から非推奨になっています) このクエリパラメータが設定されたリクエストを受け取ると、Statusコード400を返します. ([#98312](https://github.com/kubernetes/kubernetes/pull/98312))
  - :memo: クエリパラメータの`export`は、v1.17まで`kubectl get -o yaml --export deploy/hoo`のように`--export`フラグを付与した時に設定されていたパラメータです。上記を実行するとクラスタに依存する値を除いてくれるのでマニフェスト作成などに使われていました。しかし、前述の通りリソースによって一貫性がなく関連Issueが色々作られたり、Server-Sideでやる必要がある?みたいな話があり非推奨になりました。(kubectl pluginを作っている人もいます)

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

- 1. PodAffinityTermはラベルを使って対象となるNamespaceを選択するため、namespaceSelectorフィールドを持ちます。 
  2. 新しいCrossNamespacePodAffinity quota scope APIは、namespaceSelectorやnamespaceフィールドを通して指定する、cross-namespaceなPodAffinityTermのNamespaceを制限します。([#98582](https://github.com/kubernetes/kubernetes/pull/98582))
     - :memo: [KEP-2249: Namespace Selector For Pod Affinity](https://github.com/ahg-g/enhancements/blob/f9f8782c0ec730802368eed63e20ad3d4ca7a62e/keps/sig-scheduling/2249-pod-affinity-namespace-selector/README.md)
       - デフォルトのPodAffinityでは同じNamespaceに属するPodを考慮してスケジュール先を計算しますが、この機能を利用すると対象となるNamespaceを拡張できます。
- ProbeレベルのterminationGracePeriodSecondsフィールドを追加します。 ([#99375](https://github.com/kubernetes/kubernetes/pull/99375))
  - :memo: [KEP-2238: Liveness Probe Grace Periods](https://github.com/kubernetes/enhancements/tree/master/keps/sig-node/2238-liveness-probe-grace-period)
    - `terminationGracePeriodSeconds`はシャットダウン時とprobe失敗時の両方で利用されています。そのため、正常時のグレースフルなシャットダウン用に`terminationGracePeriodSeconds`に長い時間を設定していると、probeに失敗した時は即座に再起動させたい場合でも、すぐには再起動されないという問題があります。この問題を解決するため、xxxProve.terminationGracePeriodSecondsフィールドによってprove時の終了待ちの時間を別途設定できるようになりました。
- 接続を維持するためSPDY pingsが有効になりました。この変更により、`kubectl exec`と`kubectl portforward`が切断されなくなります。([#97083](https://github.com/kubernetes/kubernetes/pull/97083))
- FieldManagerが永続化前にリセットされるフィールドを持たなくなりました。 (例: "status wiping") ([#99661](https://github.com/kubernetes/kubernetes/pull/99661))
  - :memo: [KEP-0006 Apply - Status Wiping](https://github.com/kwiesmueller/enhancements/blob/b4bd10c4de770f785a614765f4989f6549875aa7/keps/sig-api-machinery/0006-apply.md#status-wiping)
    - status wipingはKEP-006で提案されている機能です。
    - etcdに永続化される前にリソースに応じてstatusの除去などいくつかの前処理が実施されますが、この時に除去されるフィールドの所有者がユーザになってしまうという問題がありました。
- Generic ephemeral volumesがベータになりました。([#99643](https://github.com/kubernetes/kubernetes/pull/99643))
  - :memo: [KEP-1698 Generic Ephemeral Volumes](https://github.com/kubernetes/enhancements/tree/master/keps/sig-storage/1698-generic-ephemeral-volumes)
    - Betaになったのでデフォルトで有効になります。
- Namespace APIオブジェクトが`kubernetes.io/metadata.name`ラベルを持つようになりました。これにより、metadata.nameフィールドがLabelセレクタで選択できるようになりました。([#96968](https://github.com/kubernetes/kubernetes/pull/96968))
- `InternalTrafficPolicy`フィールドがServiceに追加されました。
  クラスタの内部トラフィックを全Endpointにルーティングする必要があるか、もしくはNode内部のEndpointだけで良いのかを指定できるようになりました。
  `Cluster`は内部トラフィックをサービスの全Endpointにルーティングします。
  `Local`はNode内部のEndpointにトラフィックをルーティングします。Node内部にReadyなEndpointが存在しない場合、トラフィックはドロップします。
  デフォルト値は"Cluster"です。 ([#96600](https://github.com/kubernetes/kubernetes/pull/96600))
- CronJobsがbatch/v1に昇格しました。 ([#99423](https://github.com/kubernetes/kubernetes/pull/99423))
  - :memo: [KEP-19 Graduate CronJob to Stable ](https://github.com/kubernetes/enhancements/tree/master/keps/sig-apps/19-Graduate-CronJob-to-Stable) 
    - フィールドに変更はありません。
- Bazelを利用したKubernetesビルドのサポートを廃止します。([#99561](https://github.com/kubernetes/kubernetes/pull/99561))
  - :memo: [KEP-2420 Reducing Kubernetes Build Maintenance](https://github.com/kubernetes/enhancements/tree/master/keps/sig-testing/2420-reducing-kubernetes-build-maintenance)
- BoundServiceAccountTokenVolume機能がベータに昇格し、デフォルトで有効になりました。
  - この変更により、`/var/run/secrets/kubernetes.io/serviceaccount/token`で提供されているトークンは、期限付きかつ自動更新、また、Pod削除時に無効化されます。
  - 有効なトークンを利用し続けるためには、クライアントはトークンを定期的に読み込む必要が有ります。(推奨は1分間隔です) `k8s.io/client-go`のバージョンv11.0.0+とv0.15.0+では、トークンが自動再読込されます。
  - デフォルトでは、挿入されたトークンは生存期間が延長されるため、Refreshトークンが発行された後も有効です。`serviceaccount_stale_tokens_total`メトリクスは、Refreshトークンが提供された後も生存期間が延長されたトークンを利用し続けるワークロードの監視に利用します。 このメトリクスで生存期間が延長されたトークンをどのワークロードも利用していないことが確認できた場合は、生存期間を`kube-apiserver`の`--service-account-extend-token-expiration=false`フラグから1時間に短縮できます。 ([#95667](https://github.com/kubernetes/kubernetes/pull/95667))
    - :memo: [KEP-1205 Bound Service Account Tokens](https://github.com/kubernetes/enhancements/tree/master/keps/sig-auth/1205-bound-service-account-tokens)
      - 詳しくは [Bound Service Account Tokenとは何か](https://qiita.com/hiyosi/items/e4fb3d9188f8d6e650b2) を参照
- PodDisruptionBudget APIオブジェクトがstatusにconditionを持つようになりました。([#98127](https://github.com/kubernetes/kubernetes/pull/98127))
- PodDisruptionBudget APIがpolicy/v1に昇格しました。スキーマに変更ありません。これに伴う機能変更は、空のセレクタ(`{}`)がpolicy/v1のPodDisruptionBudgetに書き込まれた場合、Namespaceの全Podが選択されるようになった点のみです。policy/v1beta1 APIの挙動は変更されていません。policy/v1beta1のPodDisruptionBudget APIは非推奨となり、1.25+で削除予定です。([#99290](https://github.com/kubernetes/kubernetes/pull/99290))
  - :memo: [KEP-85 Graduate PDB to Stable](https://github.com/kubernetes/enhancements/tree/master/keps/sig-apps/85-Graduate-PDB-to-Stable)
    - v1.5からbetaのままだったPDBがv1に昇格しました。
- Topology Aware Hintsがアルファになりました。Feature Gateの`TopologyAwareHints`から有効にできます。([#99522](https://github.com/kubernetes/kubernetes/pull/99522))
  - :memo: [KEP-2433 Topology Aware Hints](https://github.com/kubernetes/enhancements/tree/master/keps/sig-network/2433-topology-aware-hints)

# :sparkle: Features (機能追加)

- client-goのメトリクスに`rest_client_exec_plugin_call_total`が追加されました。client-goのcredentialプラグインの呼び出し回数を記録します。([#98892](https://github.com/kubernetes/kubernetes/pull/98892))
- kube-apiserverに`--lease-reuse-duration-seconds`フラグが追加されました。このフラグにより、Etcd leaseの再利用期間を設定できます。([#97009](https://github.com/kubernetes/kubernetes/pull/97009))
- kube-apiserverに`etcd_lease_object_counts`メトリクスを追加しました。1つのEtcd leaseに紐づく最大のオブジェクト数を観測できます。([#97480](https://github.com/kubernetes/kubernetes/pull/97480))
- kube-controller-managerに`ephemeral_volume_controller_create[_failures]_total`メトリクスが追加されました。([#99115](https://github.com/kubernetes/kubernetes/pull/99115))
- Component ownerは、'--allow-metric-labels'フラグを利用してメトリクスラベルの許可リストを設定できます。 ([#99385](https://github.com/kubernetes/kubernetes/pull/99385), [#99738](https://github.com/kubernetes/kubernetes/pull/99738))
- KubernetesがGolang 1.16でビルドされるようになりました。([#98572](https://github.com/kubernetes/kubernetes/pull/98572))
- `ServiceAccountIssuerDiscovery`がGAとなり、常時有効となります。Feature Gateの`ServiceAccountIssuerDiscovery`は1.22で削除予定です。([#98553](https://github.com/kubernetes/kubernetes/pull/98553))
- kubeletがPodのコンテナの環境変数として設定されているConfigMapやSecretをwatchする時、指定した期間だけwatchを保持するようになりました。この変更により、大規模クラスタのkube-apiserverのメモリ使用量を削減します。([#99393](https://github.com/kubernetes/kubernetes/pull/99393))
  
# :bug: Bug or Regressions (バグ修正)

- client-goのEventBroadcasterがシャットダウン中に競合しないようになりました。([#95664](https://github.com/kubernetes/kubernetes/pull/95664))
- service/nodeport/loadbalancerのクオータ確認時のカウントエラーが修正されました。([#97451](https://github.com/kubernetes/kubernetes/pull/97451))
- APIサーバ起動時の競合状態を修正しました。最初の書き込み要求が受け付けられる前に、事前に作成されたWebhookConfigurationが有効になります。([#95783](https://github.com/kubernetes/kubernetes/pull/95783))
- Garbage Collectionが不正な参照を持つクラスタスコープオブジェクトによってNamespaceの子オブジェクトの片付けに失敗する問題が修正されました。([#98068](https://github.com/kubernetes/kubernetes/pull/98068))
- パフォーマンスのリグレッション問題(#97685)が修正されました。([#97860](https://github.com/kubernetes/kubernetes/pull/97860))
  - :memo: 関連Issue: [Regression on ARM: 1.20 apiserver has high cpu usage](https://github.com/kubernetes/kubernetes/issues/97685), [32-bit random data corruption](https://github.com/golang/go/issues/43570)
- リクエストに付与された不正なタイムアウト値がAudit Logに正しく記録されるようになりました。([#96901](https://github.com/kubernetes/kubernetes/pull/96901))
- 同じexec auth configに複数のクライアントが設定されている際に、kubectlでexec auth pluginを利用しても警告が表示されなくなりました。([#97857](https://github.com/kubernetes/kubernetes/pull/97857))
- `kubectl exec`と`kubectl attach`が`--quiet`フラグを尊重するようになりました。このフラグはリモートコマンドの出力との混乱を防ぐため、ローカルバイナリの出力を抑制します(エラー以外の全ての出力を隠します)。また、execとattachでデフォルトの1つ目のspec.containerが使われる場合、他のコンテナリストをインライン表示します。([#99004](https://github.com/kubernetes/kubernetes/pull/99004))

# :microscope: Others (その他修正)

- `Apiserver_request_duration_seconds`がstableに昇格しました。([#99925](https://github.com/kubernetes/kubernetes/pull/99925))
- github.com/Azure/go-autorest/autorestがv0.11.12にバージョンアップしました。 ([#97033](https://github.com/kubernetes/kubernetes/pull/97033))
- Kube-apiserver: OIDC認証において、Tokenの検証に利用するメタデータの再取得前に10秒待たなくなりました。([#97693](https://github.com/kubernetes/kubernetes/pull/97693))
- Windowsにおいて、起動時間として現在のプロセス情報を利用するようになりました。([#97491](https://github.com/kubernetes/kubernetes/pull/97491))
- デフォルトの委任認証オプションにおいて、healthz, readyz, livezに対する非認証時のアクセスが可能になりました。([#98325](https://github.com/kubernetes/kubernetes/pull/98325))
- 新しい`-gce-zones`フラグが`e2e.test`バイナリに追加されました。このフラグは、クラスタがどのようにクラウドのzoneリストに対するクエリ制限に影響するのかをチェックするテストを指示します。もし設定されなかった場合、現在の挙動と同じく、マルチゾーンクラスタで使用可能な全てのゾーンをクラウドプロバイダに要求します。([#98787](https://github.com/kubernetes/kubernetes/pull/98787))