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


## はじめに

ついにKubernetes 1.19がリリースされました :tada:いつもどおりAPI Machineryの変更内容を紹介していきたいと思います。(今回はリリースが遅れたのでいつもより変更点が多めです!)

バージョンをちゃんと上げていこうという方針により、Ingressがついにv1に昇格しました。その他使われていないalpha機能が削除されたり、beta機能がv1に昇格したりしています。

それとともに、非推奨となったバージョンへの警告表示機能がもろもろ追加されています。全ユーザが関わりそうなところはkubectlで非推奨APIを実行したときのWarning表示です。Kubernetesの拡張機能を実装している開発者であれば、WebhookによるCRDのwarningメッセージ追加やclient-goの非推奨APIのwarningログなどは便利になるでしょう。また、管理者は非推奨APIの利用情報がメトリクスから取得できるようになるのでユーザの移行状況の把握に使えそうです(Auditのログにもwarningアノテーションが付与されます)。

今回はアップグレード前の注意点も多めです。(全体のアップグレード前の注意点は後日公開されるのでそちらも参照ください。) その他の注意点は、Goのv1.15でX.509証明書のSANが設定されてないときにCNをホスト名として扱われなくなった点です。該当していないか要チェックです。

> :pencil: がついた文章は、CHANGELOGの公式内容ではなく筆者の補足です。

## :warning: Urgent Upgrade Notes (アップグレード前の注意点)

-   **要事前対応**: `--basic-auth-file` フラグによるBASIC認証のサポートが無くなりました。事前に `--token-auth-file` などに移行してください。([#89069](https://github.com/kubernetes/kubernetes/pull/89069))
-   CVE-2020-8559(Medium): Kubeletへのリクエストを攻撃者に傍受されると元のリクエストの認証情報を利用できる問題(詳細はこちら[#92914](https://github.com/kubernetes/kubernetes/pull/92914))に対応するため、APIサーバは101以外のアップグレードリクエストをプロキシしなくなりました。101レスポンス以外をレスポンスするバックエンド(拡張APIサーバなど)が動かなくなる可能性があります。 ([#929441](https://github.com/kubernetes/kubernetes/pull/929441))


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

-   apiextensions.k8s.io/v1beta1が非推奨になりました。apiextensions.k8s.io/v1に移行してください。([#90673](https://github.com/kubernetes/kubernetes/pull/90673))
-   apiregistration.k8s.io/v1beta1が非推奨になりました。apiregistration.k8s.io/v1に移行してください。 ([#90672](https://github.com/kubernetes/kubernetes/pull/90672))
-   authentication.k8s.io/v1beta1とauthorization.k8s.io/v1beta1が非推奨になりました。1.22で削除されるため、v1に移行してください。 ([#90458](https://github.com/kubernetes/kubernetes/pull/90458))
-   kube-apiserver: componentstatus APIが非推奨になりました。このAPIはetcd, kube-scheduler, kube-controller-managerのステータスを提供するものでしたが、kube-schedulerとkube-controller-managerがローカルに対してunsecureなエンドポイントを公開したときのみ有効でした。このAPIの代わりに、kube-apiserverのhealth checkにetcdも含まれるようになりました。また、kube-scheduler/kube-controller-managerのhealth checkエンドポイントにより、コンポーネントに対して直接確認できるようになりました。 ([#93570](https://github.com/kubernetes/kubernetes/pull/93570))


## :earth\_asia: API Changes (API周りの変更)

-   CSIDriversにアルファバージョンの `SupportsFsGroup` フィールドが追加されました。これによりボリュームのownershipとpermissionを変更できます。このフィールドを利用するには、feature gateの `CSIVolumeSupportFSGroup` を有効にしてください。 ([#92001](https://github.com/kubernetes/kubernetes/pull/92001))
-   Admission webhookがAdmissionReviewレスポンスの `.response.warnings` フィールドを使ってwarningメッセージを返せるようになりました。
    -   :pencil: 前から待ってた機能がついに!これでユーザへのwarning通知がしやすくなりますね。
-   CertificateSigningRequest APIのconditionが変更されました。 ([#90191](https://github.com/kubernetes/kubernetes/pull/90191))
    -   `status` フィールドが追加されました。デフォルトは `True` で、 `Approved`, `Denied`, `Failed` conditionに対して設定されます
    -   `lastTransitionTime` フィールドも追加されました
    -   `Failed` conditionタイプは署名者が永続的な失敗を指定できるように追加されました。このconditionは、 `certificatesigningrequest/status` サブリソースから追加できます
    -   `Approved`, `Denied` は相互に排他なconditionです。
    -   `Approved`, `Denied`, `Failed` conditionはCSRから削除できなくなりました。
        -   :pencil: いままでのCSRは簡素でしたが、だいぶ分かりやすいCondition設計に修正されました。詳しい仕様は[KEP Certificates API](https://github.com/kubernetes/enhancements/blob/master/keps/sig-auth/20190607-certificates-api.md)に書かれています。
    -   Custom Endpointが新しいEndpointSliceMirroringコントローラによってEndpointSliceにミラーされるようになりました。([#91637](https://github.com/kubernetes/kubernetes/pull/91637))
        -   :pencil: EndpointSliceはパフォーマンス/スケーラビリティ向上のためv1.16から導入された機能です。この前のKubeConEuro'20でv1.16からどう改善しているのかについての面白い発表があったのでおすすめです。詳しい仕様は[KEP EndpointSlices](https://github.com/kubernetes/enhancements/blob/master/keps/sig-network/20190603-endpointslices/README.md)に書かれています。
-   CRDに非推奨になったバージョンを設定するフィールド `spec.versions[*].deprecated` と、オプションとして警告を表示するための `spec.versions[*].deprecationWarning` フィールドが追加されました。 ([#92329](https://github.com/kubernetes/kubernetes/pull/92329))
    -   :pencil: 本体のAPIがdeprecated versionに対して警告出せるようになったことに合わせてCRDへの対応も同じタイミングで入りました。いぜんはCRDは遅れてサポートされることが多かった印象ですが、それだけカスタムする人が増えたのかもしれませんね。
-   "Too large resource version" エラーからreflectorが復帰しないバグが修正されました。 ([#92537](https://github.com/kubernetes/kubernetes/pull/92537))
-   `EmptyDir` ボリュームの代わりとなる、より柔軟性の高い `GenericEphemeralVolume` がfeature gateに追加されました。 `Emptydir` と同様にKubernetesにより自動的にPodごとのvolumeが作成、削除されます。しかし、PVCを利用した通常のプロビジョニングプロセスで提供されるので、サードパーティのストレージベンダや通常のボリューム機能が利用できます。また、ストレージが空という制約がないので、スナップショットからの復元もサポートできます。 ([#92784](https://github.com/kubernetes/kubernetes/pull/92784))
-   Kubernetesのビルドに必要なGoの最低サポートバージョンがv1.14.4になりました。 ([#92438](https://github.com/kubernetes/kubernetes/pull/92438))
-   scheme.Convert() は明示的に登録されたconversionのみで利用できるようになりました。 よって、デフォルトのreflectionベースのconversionは廃止になります。また、 `k8s.io/code-generator` を持つコンポーネントは `+k8s:conversion-gen` タグを使ってconversionを生成できます。 ([#90018](https://github.com/kubernetes/kubernetes/pull/90018))
-   CRD生成のため、kubebuilderのバリデーションタグがmetav1.Conditionに付与されます。 ([#92660](https://github.com/kubernetes/kubernetes/pull/92660))
    -   :pencil: CRD生成のためkubebuilder使って無くてもkubebuilderのタグを付与するのは皆やることではありますが、それが公式のk8sでも。 (従来の `// +k8s:` で統一してほしかった気がしなくもない)
-   structured loggingのため、kubeletに `--logging-format` フラグが追加されました。 ([#91532](https://github.com/kubernetes/kubernetes/pull/91532))
-   KubernetesがGolang v1.15.0-rc.1 によるビルドが始まりました。 ([#93264](https://github.com/kubernetes/kubernetes/pull/93264))
    -   X.509証明書にSubject Alternative Nameが設定されていない場合、デフォルトでCommonNameフィールドをホスト名として扱うレガシーな挙動は廃止になりました。この挙動は、x509ignoreCN=0というデバッグ用環境変数を設定することで、一時的に有効にできます。
        -   :pencil: Go v1.15の変更ですが、使っているシステムが該当していると影響がでかいので要チェック。
-   Volumeが紐付けられていないPodのスケジュール前に、ストレージの容量を確認するオプション機能が追加されました。(feature gateのalpha機能 `CSIStorageCapacity` の有効化が必要です) ([#92387](https://github.com/kubernetes/kubernetes/pull/92387))
-   CertificatesSigningRequest APIがcertificates.k8s.io/v1に昇格しました。これに伴い以下の変更が加えられています。 ([#91685](https://github.com/kubernetes/kubernetes/pull/91685))
    -   `spec.signerName` が必須値となりました。また、 `kubernetes.io/legacy-unknown` リクエストは `certificates.k8s.io/v1` 経由で作成できなくなりました。
    -   `spec.usage` が必須値となりました。ユニーク、かつ既知のusageのみを設定できます。
    -   `status.conditions` 重複したtypeは設定できません。
    -   `status.conditions[*].status` が必須になりました。
    -   `status.certificate` はPEMエンコードされ、CERTIFICATEブロックのみを含む必要があります。
-   `DefaultIngressClass` がGAになりました。 `--feature-gate` パラメータは1.20で削除されます ([#91957](https://github.com/kubernetes/kubernetes/pull/91957))
-   Feature GateのAlphaだった `DynamicAuditing` と、 `auditregistration.k8s.io/v1alpha1` APIのサポートが終了し削除されました。([#91502](https://github.com/kubernetes/kubernetes/pull/91502))
-   kube-controller-managerが管理するsignerが明示的に署名用の証明書と鍵を持つようになりました。詳しくは `--cluster-signing-[signer-name]-{cert,key}-file` を見てください。デフォルトは現在も `--cluster-signing-{cert,key}-file` です。 ([#90822](https://github.com/kubernetes/kubernetes/pull/90822))
-   Goのバージョンがv1.14.4にアップデートされました。 ([#88638](https://github.com/kubernetes/kubernetes/pull/88638))
-   `Ingress` と `IngressClass` リソースが `networking.k8s.io/v1` に昇格しました。 `extensions/v1beta1` と `networking.k8s.io/v1beta1` のIngressとIngressClassタイプは非推奨になり、1.22+で削除されます。v1beta1からv1 Ingressオプジェクトフィールドの主な変更は以下のとおりです。 ([#89778](https://github.com/kubernetes/kubernetes/pull/89778))
    -   `spec.backend` -> `spec.defaultBackend`
    -   `serviceName` -> `service.Name`
    -   `servicePort` -> `service.port.name` (文字列用)
    -   `servicePort` -> `service.port.number` (数値用)
    -   `pathType` がデフォルト値を持たなくなりました。"Exact", "Prefix", "ImplementationSpecific" のいずれかの設定が必要です。
    -   backendとしてリソース、もしくはサービスバックエンドが指定できます。
    -   `path` に有効な正規表現を指定する必要はなくなりました。


## :sparkle: Features (機能追加)

-   非推奨となったAPIリクエストにはAPIレスポンスにWarningヘッダが付与されるようになりました。また、非推奨のAPIの利用状況を示すメトリクスを公開しました。 ([#73032](https://github.com/kubernetes/kubernetes/pull/73032))
    -   kubectlはWarningを標準エラーに出力し、Warningをなエラーとして扱うための `--warhnings-as-erros` オプションを受け入れます。
    -   `k8s.io/client-go` はデフォルトでWarningを標準エラーに出力します。; クライアントごとに `config.WarningHandler` を設定するか、プロセスごとに `rest.SetDefaultwarninghandler()` を使って制御できます。
    -   kube-apiserverは、 `apiserver_requested_deprecated_apis` を Gague メトリクスとして非推奨になったAPIへのリクエストメトリクスを公開します。
-   異なる粒度でFlowControlシステム内部をダンプするため、 `/debug/flowcontrol/*` プレフィックス配下にデバッグ用エンドポイントを追加します。 ([#90967](https://github.com/kubernetes/kubernetes/pull/90967))
-   非推奨になったAPIへの監査イベントに対し、 `k8s.io/deprecated: "true"` アノテーションが付与されるようになりました。削除されるリリースバージョンが決まっているものに関しては、 `k8s.io/removal-release: "<majourVersion>.<minorVersion>"` アノテーションも付与されます。
-   kube-apiserverは、etcd3のデータベースファイルサイズメトリクスも公開するようになりました。 ([#89151](https://github.com/kubernetes/kubernetes/pull/89151))
-   kube-apiserver、kube-scheduler、kube-controller-managerは、 `--bind-address` と `--secure-port` フラグで指定されたアドレスをListenするときに `SO_REUSEPORT` socketオプションを使うようになりました。(Unixシステムのときのみで、Windowsは対象外です) これにより、同じ設定を持つ単一ホスト上で複数インスタンスのプロセスを動かすことができます。つまり、update/restartをダウンタイムなしにグレースフルに実行できます。 ([#88893](https://github.com/kubernetes/kubernetes/pull/88893))
-   structuredロギングサポートのため、 `--logging-format` フラグがkube-controller-managerでサポートされました。 ([#91521](https://github.com/kubernetes/kubernetes/pull/91521))
-   structuredロギングサポートのため、 `--logging-format` フラグがkube-schedulerでサポートされました。 ([#91522](https://github.com/kubernetes/kubernetes/pull/91522))
-   以前は環境変数からのみ設定可能であったプロキシ設定が、 `Rest.Config` フラグから設定できるようになりました。 ([#81443](https://github.com/kubernetes/kubernetes/pull/81443))
-   Server Side Applyにおいて、適用済みの設定からフィールドが削除された場合の挙動が正規化されました。Ownerが存在しない場合は削除、存在する場合はデフォルト値にリセットされます。安全なOwnershipの移譲のため、ユーザからデフォルト値へのリセットなしのHPAへのreplicasフィールド移譲については、Transferring Ownershipにドキュメントがあります。 ([#92661](https://github.com/kubernetes/kubernetes/pull/92661))
    -   :pencil: 言及されているドキュメントはこちら -> [Transferring Ownership](https://kubernetes.io/docs/reference/using-api/api-concepts/#transferring-ownership)。
-   client-side applyからserver-side applyへのコンフリクトしないスムーズなアップグレードをサポートします。また、ダウングレードにも対応しました。([#90187](https://github.com/kubernetes/kubernetes/pull/90187))
-   etcdイメージをマイグレーションスクリプトでdebianからdistrolessへスイッチしました。 ([#91171](https://github.com/kubernetes/kubernetes/pull/91171))
-   apiserverログのTrace出力が整理され、より網羅的になりました。Traceはネストしており、短時間実行されるすべてのエンドポイントに対して、フィルターチェーン全体が計測されるようになりました。(例: 認証チェックなど) ([#88936](https://github.com/kubernetes/kubernetes/pull/88936))
-   Etcdクライアントのバージョンをv3.4.9にアップデートしました。 ([#92075](https://github.com/kubernetes/kubernetes/pull/92075))


## :bug: Bug or Regression (バグやリグレッションの修正)

-   informer-syncのヘルスチェックによってapiserverがpanicする問題が修正されました。 ([#93600](https://github.com/kubernetes/kubernetes/pull/93600))
-   client-goにおいて、informersがtimeoutしたときにwatchを再接続するのではなく、full listリクエストを投げる問題を修正しました。 ([#89652](https://github.com/kubernetes/kubernetes/pull/89652))
-   ビルドインオブジェクトと同じ名前を持つCRDリソースもexplainできるようにしました。 ([#89505](https://github.com/kubernetes/kubernetes/pull/89505))
-   内部informerが動悸されていることを確認するため、kube-apiserverの `/readyz` を新しい "informer-sync" で拡張しました。 ([#92644](https://github.com/kubernetes/kubernetes/pull/92644))
-   先頭に0がついたIPv6アドレスが利用できないバグを修正しました。 ([#92644](https://github.com/kubernetes/kubernetes/pull/92644))
-   xfsマウント停止による xfs\_repair のバグを修正しました。 ([#89444](https://github.com/kubernetes/kubernetes/pull/89444))
-   イメージファイルシステムの検出、devicemapperのディスクメトリクス、Linuxカーネル5.0+によるOOM Killerの検出を修正しました。 ([#92919](https://github.com/kubernetes/kubernetes/pull/92919))
-   etcdイメージのマイグレーションスクリプト内のetcdバージョンを修正しました。 ([#91925](https://github.com/kubernetes/kubernetes/pull/91925))
-   kube-apiserver起動時、readinessにレポートされるより前にAPIServiceがHTTPハンドラにインストールされるのを待機するよう修正しました。 ([#91925](https://github.com/kubernetes/kubernetes/pull/91925))
-   kubectlのバージョン情報がconfigファイル無しに出力できるよう修正しました。 ([#89913](https://github.com/kubernetes/kubernetes/pull/89913))
-   無視されたオブジェクトの平均値のためのプリンタを修正しました。 ([#89142](https://github.com/kubernetes/kubernetes/pull/89142))
-   1.18でリグレッションした `wait.Forever` が初回リピート時にbackoff periodを無視する問題を修正しました。 ([#90476](https://github.com/kubernetes/kubernetes/pull/90476))
-   出力にjsonpathを指定したkubectl実行時に、ネストされた範囲が無視される問題を修正しました。 ([#88464](https://github.com/kubernetes/kubernetes/pull/88464))
-   ネスト深いオブジェクトのjsonパッチ適用のパオーマンスを修正しました。 ([#92069](https://github.com/kubernetes/kubernetes/pull/92069))
    -   :pencil: validationによってCRDのネストが深く,適用に時間がかかってきてたので嬉しい修正
-   kubeconfigファイルがない時に、 `--local` か `--dry-run` フラグを付けたkubectlコマンドの実行がリグレッションしていた問題を修正しました。 ([#90243](https://github.com/kubernetes/kubernetes/pull/90243))
-   kubectlでbearerトークンが設定され(kubectl &#x2013;token=..)、かつexec credentialプラグインが同じコンテキストに設定された場合の曖昧な挙動を修正しました。bearerトークンが優先されます。 ([#91745](https://github.com/kubernetes/kubernetes/pull/91745))
-   informerを利用した際のCSIボリュームアタッチメントのスケール問題を修正しました。 ([#91307](https://github.com/kubernetes/kubernetes/pull/91307))
-   scaleサブリソースを持つCRDのreplicasフィールドに、デフォルト値が設定されるバグを修正しました。 ([#89833](https://github.com/kubernetes/kubernetes/pull/89833))
-   1.17にリグレッションしたAPIリクエストのcache-controlヘッダが落ちるバグが修正されました。 ([#90468](https://github.com/kubernetes/kubernetes/pull/90468))
-   kubectlとclient-goのjsonpathが、map/slice/structなどの複雑なタイプをGo構文ではなくjsonとしてシリアライズします。 ([#89660](https://github.com/kubernetes/kubernetes/pull/89660))
    -   :pencil: mapなどがGo構文になっていたため、jsonを操作する他のツールと連携できないという問題がこれで解決しました。
-   kube-aggregatorの証明書に変更があった際に、ディスクから動的に読み込みます。 ([#92791](https://github.com/kubernetes/kubernetes/pull/92791))
-   kube-apiserverが、カスタムリソースのprinter columnにおいて、jsonpathの再帰降下演算子を評価しなくなりました。 ([#93408](https://github.com/kubernetes/kubernetes/pull/93408))
-   kube-apiserverがX-Stream-Protocol-Versionの複数ヘッダに加え、単一ヘッダの場合もコンマ区切りで複数のプロトコルを指定できるようになりました。RFC2616に準拠しています。 ([#89857](https://github.com/kubernetes/kubernetes/pull/89857))
-   kubeletのbootstrap証明書のsignalを認識させるようになりました。 ([#92786](https://github.com/kubernetes/kubernetes/pull/92786))
-   server-side applyを使わなかった際のmetadata.managedFieldのcreate/update/pathリクエストのハンドリングのリグレッションを解決しました。 ([#91690](https://github.com/kubernetes/kubernetes/pull/91690))
-   以下の空ではなく、フラグ以外の引数を期待しないコンポーネントは、引数が指定された場合エラーメッセージを表示して終了するようになりました。 ([#91349](https://github.com/kubernetes/kubernetes/pull/91349))
    -   cloud-controller-manager, kube-apiserver, kube-controller-manager, kube-proxy, kubeadm {alpha|config|token|version}, kubemark
    -   フラグのプレフィックスとして、ショートの場合シングルダッシュ"-"(0x45)で、ロングの場合ダブルダッシュ"&#x2013;"が必要です。
    -   この変更以前は、不正なフラグとして(例: "–"(0x8211)などのASCII以外のダッシュ文字)は位置引数として扱われ、無視されていました。
-   readinessにレポートされる前に、すべてのCRDがdiscovery endpointに公開されるのを待つようになりました。 ([#89145](https://github.com/kubernetes/kubernetes/pull/89145))
-   evictする際PDBのチェック無しにPending状態のPodが削除できるようになりました。([#83906](https://github.com/kubernetes/kubernetes/pull/83906))
    -   :pencil: 元のIssueは [PDBs using minUnavailable prevent draining unready pods](https://github.com/kubernetes/kubernetes/issues/80389) で、週っせいによりevictionがスタックする問題の一部(PendingのPodの場合)はこれで解決するようになりました。ただし、UnhealthyなPodの削除については [k/k #94381](https://github.com/kubernetes/kubernetes/pull/94381#issue-476525265) で対応中です。
-   `golang.org/x/text/encoding/unicode` の脆弱性が修正されました。 ([#92219](https://github.com/kubernetes/kubernetes/pull/92219))


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

-   `--cache-dir` でhttpとdiscovery用のキャッシュディレクトリを設定できるようになりました。デフォルトは `$HOME/.kube/cache` です。 ([#92910](https://github.com/kubernetes/kubernetes/pull/92910))
-   `DISABLE_KUBECONFIG_LOCK` 環境変数でkubeconfigファイルのロックを無効化できるようになりました。 ([#92513](https://github.com/kubernetes/kubernetes/pull/92513))
-   ベースイメージに debian-base:v2.1.0を使うようになりました。 ([#90679](https://github.com/kubernetes/kubernetes/pull/90679))
-   debian-base@v2.1.2とdebian-iptables@v12.1.1のアップデートしました。 ([#93667](https://github.com/kubernetes/kubernetes/pull/93667))
-   `--target-ram-md` フラグが廃止になりました。 ([#91818](https://github.com/kubernetes/kubernetes/pull/91818))
-   `IsFullyQualifiedDomainName()` が `IsDNs1123Label` に基づいてバリデーションするようになりました。 ([#91818](https://github.com/kubernetes/kubernetes/pull/91818))
-   kube-apiserverが標準のListMeta schemeの定義を参照するカスタムリソースのopenapi schemaを公開するようになりました。 ([#92546](https://github.com/kubernetes/kubernetes/pull/92546))
-   kube-apiserverの `--kubelet-https` フラグが廃止になりました。v1.0以前からapiserverは設定されたendpointに対して無条件にhttpsを利用してapiserverと通信しています。 ([#92546](https://github.com/kubernetes/kubernetes/pull/92546))
-   Etcdのデフォルトサーババージョンが3.4.9にアップデートされました。 ([#92349](https://github.com/kubernetes/kubernetes/pull/92349))