Kubernetes 1.20: アップグレード時の注意事項

# はじめに

このエントリは、[Kubernetes 1.20 の CHANGELOG](https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.20.md#v1200) からアップグレード時に確認すべき内容をまとめています。
具体的には以下の項目を翻訳し、適宜補足やコメントを追加しています。

- Known Issues
- Urgent Upgrade Notes

このエントリでは翻訳部分と補足などの筆者の追加のコメントは :pencil: のあとに追加するようにしています。

## Known Issues

### Summary API in kubelet doesn't have accelerator metrics
現在、cadvisor_stats_providerはAcceleratorStatsを提供していますが、cri_stats_providerは提供していません。結果として、cri_stats_providerを利用した時、kubeletのSummary APIはacceleratorメトリクスを公開しません。

- :pencil: 軽くコードを確認したところDockerやcri-oをコンテナランタイムとして利用している場合は、cadvisor_stats_providerを利用するようで影響がなさそうに見えました
  - https://github.com/kubernetes/kubernetes/blob/v1.20.0/pkg/kubelet/cadvisor/util.go#L69-L79
- :pencil: こちらの問題はv1.20.1で[修正された](https://github.com/kubernetes/kubernetes/pull/97018)ようです
- :pencil: Summary APIは以下のようにkubectlでもアクセスできます

```sh
$ kubectl get --raw /api/v1/nodes/${NODE_NAME}/proxy/stats/summary
```

## Urgent Upgrade Notes

- exec probeのタイムアウトが機能していないバグがkubeletで修正されました。これはデフォルトのタイムアウト（指定されていない場合）が1秒であり、exec probeによっては小さすぎる場合があるため、予期せぬ動作をする可能性があります。この動作に依存しているポッドが、プローブのタイムアウトを正しく処理するように更新されていることを確認してください。詳細については、ドキュメントの[configure probe](https://docs.k8s.io/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/#configure-probes)セクションを参照してください。
  - この振る舞いの変更はいくつかのクラスタで予期しない可能性があり、FeatureGatesの`ExecProbeTimeout`でふるまいを制御可能です。このFeatureGateによる制御は今後のリリースで削除され、exec probeのタイムアウトは常に機能するようになります。([#94115](https://github.com/kubernetes/kubernetes/pull/94115), [@andrewsykim](https://github.com/andrewsykim)) [SIG Node and Testing]
  - :pencil: 以下のようなYAMLで挙動が確認できます。
     - v1.19環境などでは`Liveness probe errored: rpc error: code = DeadlineExceeded desc = failed to exec in container: timeout 1s exceeded: context deadline exceeded`とeventに表示されますが、PodはReadyでRunningのままです。
     - v1.20では`Liveness probe failed`となり、コンテナがリスタートされます(以下のYAMLの例の場合最終的にCrashLoopBackOffの状態になります)

```yaml
apiVersion: v1
kind: Pod
metadata:
  name: exec-test
spec:
  containers:
  - name: exec
    image: alpine
    command:
    - /bin/sh
    - -c
    - sleep 36000
    livenessProbe:
      exec:
        command:
        - tail
        - -f
        - /dev/null
      failureThreshold: 1
```

- FeatureGateの`RuntimeClass`はGAへ昇格しました。`node.k8s.io`APIグループはv1beta1からv1へ昇進しました。v1beta1は非推奨になり、将来のリリースで削除予定であり、v1を使うようにしてください。([#95718](https://github.com/kubernetes/kubernetes/pull/95718), [@SergeyKanzhelev](https://github.com/SergeyKanzhelev)) [SIG Apps, Auth, Node, Scheduling and Testing]

- API priorityとfairnessがbetaとなりました。APFを有効にしたv1.19のサーバはv1.20以上のサーバと共にマルチサーバークラスタで動作させるべきではありません。([#96527](https://github.com/kubernetes/kubernetes/pull/96527), [@adtac](https://github.com/adtac)) [SIG API Machinery and Testing]

- CSIドライバの場合、kubeletはCSIスペックに従ってNodePublishVolumeのtarget_pathを作成しなくなりました。またKubeletは、stagingとtarget のパスがマウントされているか、もしくは破損しているかをチェックしなくなりました。CSI Driverは、べき等である必要があり必要なマウントの検証を行う必要があります。([#88759](https://github.com/kubernetes/kubernetes/pull/88759), [@andyzhangx](https://github.com/andyzhangx)) [SIG Storage]

- Kubeadm: [http://git.k8s.io/enhancements/keps/sig-cluster-lifecycle/kubeadm/2067-rename-master-label-taint/README.md](http://git.k8s.io/enhancements/keps/sig-cluster-lifecycle/kubeadm/2067-rename-master-label-taint/README.md)([#95382](http://git.k8s.io/enhancements/keps/sig-cluster-lifecycle/kubeadm/2067-rename-master-label-taint/README.md), [@neolit123](https://github.com/neolit123)) [SIG Cluster Lifecycle]
  - コントロールプレーンのノードに付与される`node-role.kubernetes.io/master`ラベルは非推奨とされ、GAの非推奨期間後に将来のリリースで削除されます
  - `node-role.kubernetes.io/control-plane`という新しいラベルが導入され、`node-role.kubernetes.io/master`ラベルが削除されるまで、`node-role.kubernetes.io/master`と並行して付与されます
  - `kubeadm upgrade apply`でアップグレード時に`node-role.kubernetes.io/master`ラベルしかない既存のノードに`node-role.kubernetes.io/control-plane`ラベルを追加するようになりました
  - kubeadmの上に構築したツールは、`node-role.kubernetes.io/control-plane`ラベルを使用するようにしてください
  - control-planeノードに適用されていた`node-role.kubernetes.io/master:NoSchedule`というTaintは現在非推奨となっており、GAの非推奨期間後に将来のリリースで削除される予定です
  - 将来新たに追加される`node-role.kubernetes.io/control-plane:NoSchedule`というTaintに対するTolerationをkubeadmで管理されているCoreDNS/kube-dnsマニフェストへ追加しました。このTaintはまだcontrol-planeへ適用されていません。
    - 必要に応じてこのTaintに対応するようにしてください

- kubeadm: serviceSubnetとpodSubnetのvalidationを改善しました。ServiceSubnetは、実装の詳細のためにサイズが制限されており、マスクは20ビット以上を割り当てることができません。PodSubnetはkube-controller-managerの対応するクラスタ`--node-cidr-mask-size`と照合してvalidationしますが、値が互換性がない場合は失敗します。以前のIPv6では、podSubnetのマスクが/112よりも小さい場合、kubeadmはノードマスクを8の倍数になるように計算し、利用可能なビットを分割してノードに使用される数を最大化していました。([#95723](https://github.com/kubernetes/kubernetes/pull/95723), [@aojea](https://github.com/aojea)) [SIG Cluster Lifecycle]

- 非推奨のフラグ`--experimental-kustomize`はkubeadmコマンドから削除されました。代わりにv1.19で導入された`--experimental-patches`を利用してください。`--exprimental-patches`の`--help`の説明にあるマイグレーションの情報を参照してください。([#94871](https://github.com/kubernetes/kubernetes/pull/94871), [@neolit123](https://github.com/neolit123))

- Windows hyper-v コンテナのfeaturegateはv1.20で非推奨となり、1.21で削除されます。([#95505](https://github.com/kubernetes/kubernetes/pull/95505), [@wawa0210](https://github.com/wawa0210)) [SIG Node and Windows]

- v1.10で非推奨となったAPIサーバでinsecureポートを公開する機能が削除されました。insecureアドレスの--addressフラグと、--insecure-bind-addressもAPIサーバでは利用できなくなります。フラグ自体の削除はv1.24予定です。また、--portと--insecure-portフラグは0のみ設定可能で、こちらもv1.24で削除されます。([#95856](https://github.com/kubernetes/kubernetes/pull/95856), [@knight42](https://github.com/knight42), [SIG API Machinery, Node, Testing])

- デュアルスタックの Service が alpha で追加されました。これは alpha API への破壊的な変更になります。デュアルスタックの API では Service の単一の `ipFamily` から `ipFamilyPolicy` (`SingleStack`, `PreferDualStack`, `RequireDualStack`)、`ipFamilies` (割り当てるファミリのリスト), `clusterIPs` の 3 フィールドに書くようになりました。デフォルティングによって処理されるため、殆どの利用者は何もする必要はありません。利用者がデュアルスタックを要求しない限り、Service はシングルスタックになります。この機能は `IPv6DualStack` のフィーチャーゲートによって設定できます。 ([#91824](https://github.com/kubernetes/kubernetes/pull/91824), [@khenidak](https://github.com/khenidak)) [SIG API Machinery, Apps, CLI, Network, Node, Scheduling and Testing]

- TokenRequestとTokenRequestProjectionがGAになりました。この機能では、Podのライフタイムに沿ったSecretから参照できないservice account tokenを生成できます。詳細は、こちらを参照してください。また、TokenRequestとTokenRequestProjectionのfeature gatesはv1.21に削除されます。この変更に伴い、APIサーバの以下のフラグが必須値となります。
  - `--service-account-issuer`: クラスタのライフタイムに渡ってService Account Tokenの発行者を識別するための識別子。
  - `--service-account-key-file`: トークンの検証に使用される1つ以上の公開鍵を含む1つ以上のファイルを設定します。
  - `--service-account-signing-key-file`: Service Account Tokenの署名に利用する、秘密鍵を含んだファイルを設定します。kube-controller-managerの--service-account-private-key-fileと同じファイルを設定できます。([#95896](https://github.com/kubernetes/kubernetes/pull/95896), [@zshihang](https://github.com/zshihang)) [SIG API Machinery, Auth, Cluster Lifecycle]
  - :pencil: TokenRequestとTokenRequestProjectionについては @hiyosi さんの以下の記事が参考になります
     - [TokenRequestProjectionについて調べてみた](https://qiita.com/hiyosi/items/feec917d502af8ad8863)
     - [BoundServiceAccountVolumeを有効にしてみる](https://qiita.com/hiyosi/items/35c22507b2a85892c707)

- kubeadm: `kubeadm alpha kubeconfig user`コマンドは`--config`フラグを受け付け、以下のフラグを削除します
  - apiserver-advertise-address / apiserver-bind-port: InitConfigurationのlocalAPIEndpointまたはClusterConfigurationのcontrolPlaneEndpointを利用してください
  - cluster-name: ClusterConfigurationのclusterNameを使用してください
  - cert-dir: ClusterConfigurationのcertificatesDirをしようしてください([#94879](https://github.com/kubernetes/kubernetes/pull/94879), [@knight42](https://github.com/knight42)) [SIG Cluster Lifecycle]

- GCコントローラが不正なownerReferenceを受け取ったときの非決定論的な挙動を解決しました。今後はchildとownerオブジェクトのネームスペースが一致しない場合、OwnerRefInvalidNamespaceをreasonに持つEventへ記録します。[kubectl-check-ownerrefefrences](https://github.com/kubernetes-sigs/kubectl-check-ownerreferences)ツールを利用すると、アップグレード前にも不正なownerReferenceが存在しないかチェックできます。
  - ネームスペーススコープのオブジェクトのownerReferenceが、同じネームスペースに存在しない場合オブジェクトのuidを参照していた場合、ownerが存在しないものとしてそのchildオブジェクトは削除されます。
  - クラスタスコープのオブジェクトのownerRefefrenceが、名前空間スコープのオブジェクトuidを参照していた場合、ownerが解決できないとしてそのchildオブジェクトはGCによって無視されます。([#92743](https://github.com/kubernetes/kubernetes/pull/92743), [@liggitt](https://github.com/liggitt)) [SIG API Machinery, Apps and Testing]