Kubernetes 1.17: SIG-Storageの変更内容

# はじめに
本ドキュメントでは、Kubernetes 1.17.0の[CHANGELOG](https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG-1.17.md#changes)をベースにSIG-Storageに関する機能について紹介します。
:memo: がついた文章は、CHANGELOGの公式内容ではなく筆者の補足です。

# 新着情報 (What's New)

- Volume SnapshotがBetaに昇格 :tada:
  KubernetesのVolume Snapshotが Kubernetes v1.17でベータになりました。この機能は、Kubernetes v1.12でアルファとして登場し、Kubernetes v1.13で重大な変更が加えられセカンドアルファとして提供されてきました。

- CSIMigrationがBetaに昇格 :tada:
  Kubernetesのin-treeのstorage pluginからContainer Storage Interface(CSI)へのマイグレーションがKubernetes v1.17でベータになりました。このCSIMigrationは Kubernetes v1.14でアルファとして登場しました。

:memo: in-treeのstorage pluginはKubernetes v1.21で全て削除される予定です。これに向けCSIへのマイグレーションは Kubernetes v1.19/v1.20のGAを目指し急ピッチでプロジェクトが進められています([参考: KubeCon NA 2019/Intro+Deep Dive+ Kubernetes Storage SIG](https://kccncna19.sched.com/event/UakS/intro-deep-dive-kubernetes-storage-sig-saad-ali-google?iframe=no&w=100%&sidebar=yes&bg=no))。
in-treeのstorage pluginを利用中の方は、CSIへのマイグレーションを検討されると良いでしょう。また、新しい機能は、ほぼCSIしか対応されなくなってきています。

# 既知の問題点 (Known Issues)

- 特権があるコンテナの場合、volumeDevicesマッピングは無視されます。
  
# アップグレード前に絶対に確認が必要な変更点 (Urgent Upgrade Notes)

- このリリースでは、ブロックボリュームで使われているパスが変更されているため、Kubernetesクラスタをアップグレードする前に全てのNodeをDrainしてください。なお、オンラインのNodeのアップグレードは許可されていません。([#74026](https://github.com/kubernetes/kubernetes/pull/74026), @mkimuram)

# 非推奨or廃止される機能 (Deprecations and Removals)

- GCERegionalPersistentDisk, EnableAggregatedDiscoveryTimeout, PersistentLocalVolumesのfeature gatesはDeprecatedとなり、無条件で有効になりました。([#82472](https://github.com/kubernetes/kubernetes/pull/82472), @draveness)
- 組み込みのsystem:csi-external-provisionerと system:csi-external-attacherのcluster rolesはKubernetes 1.17で削除されました。 ([#84282](https://github.com/kubernetes/kubernetes/pull/84282), @tedyu)
- in-treeのGCE PD plugin `kubernetes.io/gce-pd` が deprecatedになり1.21で削除される予定です。GCP上に自分でKubernetesをデプロイしたユーザは、CSIMigration + CSIMigrationGCE機能を有効にし、GCE PD CSI Driver (https://github.com/kubernetes-sigs/gcp-compute-persistent-disk-csi-driver) をインストールして、既存のPodとPVCの中断を回避してください。そして、ユーザは新規ボリュームのため、GCE PD CSI Driverを直接使い始めてください。([#85231](https://github.com/kubernetes/kubernetes/pull/85231), @davidz627)
- in-treeのAWS EBS plugin `kubernetes.io/aws-ebs`がdeprecatedになり1.21で削除される予定です。AWS上に自分でKubernetesをデプロイしたユーザは、CSIMigration + CSIMigrationAWS機能を有効にし、AWS EBS CSI Driver (https://github.com/kubernetes-sigs/aws-ebs-csi-driver)をインストールして、既存のPodとPVCの中断を回避してください。そして、ユーザは新規ボリュームのため、AWS EBS CSI Driverを直接使い始めてください。([#85237](https://github.com/kubernetes/kubernetes/pull/85237), @leakingtapan)
- CSINodeInfoのfeature gateはdeprecatedになり、将来のリリースで削除される予定です。 これに関連し storage.k8s.io/v1beta1 CSINodeオブジェクトはdeprecatedになり、将来のリリースで削除される予定です。([#83474](https://github.com/kubernetes/kubernetes/pull/83474), @msau42)

:memo: CSI Topology 機能がGAとなりCSINodeオブジェクトが `k8s.io/v1`に変更となったためです。

- 使われていなかったアルファ機能のMountContainersが削除されました。([#84365](https://github.com/kubernetes/kubernetes/pull/84365), @codenrhoden)
-  https://v1-13.docs.kubernetes.io/docs/setup/release/notes のdeprecationのアナウンスに従って、廃止予定のディレクトリ`{kubelet_root_dir}/plugins`の監視とCSI V0サポートについて削除しました。([#84533](https://github.com/kubernetes/kubernetes/pull/84533), @davidz627)

# メトリクスの変更 (Metrics Changes)

## 追加されたメトリクス (Added metrics )

SIG-Storage関連はなし

##  非推奨/変更されたメトリクス (Deprecated/changed metrics)

- kubeletからの以下のメトリクスがALPHA stabilityレベルとしてマークされます：  
`kubelet_container_log_filesystem_used_bytes` `kubelet_volume_stats_capacity_bytes` `kubelet_volume_stats_available_bytes` `kubelet_volume_stats_used_bytes` `kubelet_volume_stats_inodes` `kubelet_volume_stats_inodes_free` `kubelet_volume_stats_inodes_used` `plugin_manager_total_plugins` `volume_manager_total_volumes`   
([#84907](https://github.com/kubernetes/kubernetes/pull/84907), @RainbowMango)
- kube-controller-managerからの以下のメトリクスがALPHA stabilityレベルとしてマークされます:  
`storage_count_attachable_volumes_in_use` `attachdetach_controller_total_volumes` `pv_collector_bound_pv_count` `pv_collector_unbound_pv_count` `pv_collector_bound_pvc_count` `pv_collector_unbound_pvc_count`  ([#84896](https://github.com/kubernetes/kubernetes/pull/84896), @RainbowMango)

# 注目機能 (Notable Features)

## Stable

- CSI Topology 機能がGAになりました。 ([#83474](https://github.com/kubernetes/kubernetes/pull/83474), @msau42) 
- VolumeSubpathEnvExpansion機能がGAになりました。これに伴い、VolumeSubpathEnvExpansionのfeature gateは無条件で有効となり、v1.19で削除される予定です。([#82578](https://github.com/kubernetes/kubernetes/pull/82578), @kevtaylor)
- Node-specific volume limitsがGAになりました。 ([#83568](https://github.com/kubernetes/kubernetes/pull/83568), @bertinatto)

## Beta

- Kubernetes Volume Snapshot機能がベータになりました。このリリースからVolumeSnapshotDataSourceのfeature gateがデフォルトでオンになっています。これにより、ボリュームのスナップショット(CSIドライバがサポートしている場合)を取得できます。そして、このスナップショットを使って、スナップショットから事前にデータを復元した新しいボリュームをプロビジョニングできます。
- Feature gates CSIMigrationがベータ(デフォルトでオン)となり、CSIMigrationGCEもベータ(GCE PD CSI Driverのインストールが必要なため、デフォルトではオフ)になりました。([#85231](https://github.com/kubernetes/kubernetes/pull/85231), @davidz627)
- Promote CSIMigrationAWS to Beta (off by default since it requires installation of the AWS EBS CSI Driver) (#85237, @leakingtapan)
- CSIMigrationAWSがベータに昇格しました(AWS EBS CSI Driverのインストールが必要なため、デフォルトではオフ)。 ([#85237](https://github.com/kubernetes/kubernetes/pull/85237), @leakingtapan)

## CLIの改善 (CLI Improvements)

SIG-Storage関連はなし

## APIの変更点 (API Changes)

SIG-Storage関連はなし

# その他注目すべき変更 (Other notable changes)

## Storage

- CSI versionが1.2.0になりました。([#84832](https://github.com/kubernetes/kubernetes/pull/84832), [@gnufied](https://github.com/gnufied))
- CSI Migration: 同じ内部仕様名をもつ全てのinline volumeが同じパスにステージングされる問題を修正します。移行後のinline volumeは、ボリューム毎にユニークなパスへステージングされるようになりました。 ([#84754](https://github.com/kubernetes/kubernetes/pull/84754), [@davidz627](https://github.com/davidz627))
- CSI Migration: GCE PDのAccess modeは、inline volumeのread onlyのステータスを反映するようになりました。これにより、read onlyの複数のPDのマルチアタッチが可能となります。 ([#84809](https://github.com/kubernetes/kubernetes/pull/84809), [@davidz627](https://github.com/davidz627))
- CSIのdetachのタイムアウトを10秒から2分に増やしました。([#84321](https://github.com/kubernetes/kubernetes/pull/84321), [@cduchesne](https://github.com/cduchesne))
- Ceph RDB volume プラグインは認証用のkeyring(`/etc/ceph/ceph.client.lvs01cinder.keyring`, `/etc/ceph/ceph.keyring`, `/etc/ceph/keyring`, `/etc/ceph/keyring.bin`)を使用しなくなりました。CephのユーザのcredentialsはPersistentVolumeと関連するSecretにて提供される必要があります。 ([#75588](https://github.com/kubernetes/kubernetes/pull/75588), [@smileusd](https://github.com/smileusd))
- GlusterFSにおいて、IPの文字列が有効なIPアドレス(version4 or 6)であるかを検証します。 ([#83104](https://github.com/kubernetes/kubernetes/pull/83104), [@zouyee](https://github.com/zouyee))
- Topologyラベルとして `PersistentVolumes`のラベル付けを行うPersistentVolumeLabel admission pluginは、動的にプロビジョニングされたPVの既存ラベルを上書きしなくなりました。`PersistentVolume`に正しいラベルをつけた動的プロビジョニングを信頼し、潜在的に高価なCloud APIの呼び出しを節約します。ユーザが手動で作成した `PersistentVolumes`は、以前と同じ方法のadmission pluginにてラベル付けされます。([#82830](https://github.com/kubernetes/kubernetes/pull/82830), [@jsafrane](https://github.com/jsafrane))
- マイグレーションが有効の場合、既存のPVはvolume topologyを使うように変換されます。([#83394](https://github.com/kubernetes/kubernetes/pull/83394), [@bertinatto](https://github.com/bertinatto))
- local: ブロックリソースのlocal filesystem volumeの再構築をサポートしました。 ([#84218](https://github.com/kubernetes/kubernetes/pull/84218), [@cofyc](https://github.com/cofyc))
- BlockVolume 機能がオフの時、PersistentVolumes/PersistentVolumeClaimsのbindingのブロックを修正しました。([#84049](https://github.com/kubernetes/kubernetes/pull/84049), [@jsafrane](https://github.com/jsafrane))
- PVCでマイナスのストレージサイズによる紛らわしいエラーを報告するようになりました。 ([#82759](https://github.com/kubernetes/kubernetes/pull/82759), [@sttts](https://github.com/sttts))
- AWSでのAttachエラーの"requested device X but found Y"を修正しました。([#85675](https://github.com/kubernetes/kubernetes/pull/85675), [@jsafrane](https://github.com/jsafrane))
- ボリュームのattaching/detaching時のAWS APIのDescribeVolumesの呼び出し頻度を減らしました。 ([#84181](https://github.com/kubernetes/kubernetes/pull/84181), [@jsafrane](https://github.com/jsafrane))
- detach直後のAWSのVolumeのattachを修正しました。([#83567](https://github.com/kubernetes/kubernetes/pull/83567), [@jsafrane](https://github.com/jsafrane))
- OpenStack使用時に発生する可能性のあったfd(ファイルディスクリプタ)リークとディレクトリのクローズ処理を修正しました。 ([#82873](https://github.com/kubernetes/kubernetes/pull/82873), [@odinuge](https://github.com/odinuge))
- local: local volume blockモードの再構築をサポートしました。  ([#84173](https://github.com/kubernetes/kubernetes/pull/84173), [@cofyc](https://github.com/cofyc))
- kubeletの再起動後のraw ブロックデバイスのクリーンアップが修正されました。([#83451](https://github.com/kubernetes/kubernetes/pull/83451), [@jsafrane](https://github.com/jsafrane))
- Windows SercerのGCE-PDドライバでドライバーがアンマウントされている最中のデータキャッシュのフラッシュ処理が追加されました。([#83591](https://github.com/kubernetes/kubernetes/pull/83591), [@jingxu97](https://github.com/jingxu97))

# 所感

　Kubernetes v1.17ではストレージ関連が目立ちました。大きくは以下の3つです。

- Volume Snapshotのベータ昇格
- CSIMigrationのベータ昇格
- TopologyのGA昇格

Volume SnapshotとTopologyは新しい機能として徐々に昇格し洗練されたものにブラッシュアップされている印象です。これらはバックアップやDR(ディザスタリカバリ)などを意識したボリュームの配置など便利になっていく機能です。
　一方、CSIMigrationはストレージ関連の機能が増えるわけではありません。CSIMigrationは、これまで開発されていたin-treeと呼ばれるKubernetesのソースコードに埋め込まれたストレージ関連の処理を、外部インターフェース/プラグインとして登場したCSIへ移行するための支援機能です。
上述しましたが、SIG-Storageではin-treeのストレージ関連の処理はKubernetes v1.21で全て削除される予定です。ユーザは利用しているインフラに対応したCSIMigrationを使い、早々に移行を検討した方が良いかと思います。今回のKubernetes v1.17ではGCP,AWSのマイグレーションがベータになりました。今後徐々に対応が増えていく(はず)ので、チェックしておくと良いかと思います。また、これから新しくKubernetesへストレージの導入を行おうとしている方は、移行の手間を省ける＆新しい機能のサポートの2点を考え、CSIに対応したものを選ぶのがベターチョイスではないでしょうか。

## おまけ: local volumeの再構築(reconstruction)とは

local volumeの再構築(reconstruction)がKubernetes v1.17で変更されました。
少々わかりにくので説明を追加します。(気にする人は少ないかもしれませんが...)

local volumeのPVの定義で動作が変わります。

- .spec.pathがディレクトリで.spec.volumeMode == "Filesystem"の場合
  - 再構築はサポートされません(必要なし)。local voumeはディレクトリであり、コンテナに直接bind-mountedされるため、クリーンアップするマウントポイントやデバイスへのシンボリックリンクはありません。
- .spec.pathがブロックデバイスで、spec.volumeMode == "Filesystem"の場合
  - ブロックデバイスはglobal mount path(`/var/lib/kubelet/plugins/kubernetes.io/local-volume/mounts/spec.Name()`)にマウントされ、クリーンアップする必要があります。->再構築をサポート
- .spec.pathがブロックデバイスで、spec.volumeMode == "Block"の場合
  - Node map pathがシンボリックリンク(`/var/lib/kubelet/plugins/kubernetes.io~local-volume/volumeDevices/spec.Name()/{podUid}`がデバイス(例: `/dev/sdb`)へのシンボリックリンク)になり、クリーンアップが必要となります。->再構築をサポート
  - さらに、Pod map pathもシンボリックリンク(`/var/lib/kubelet/pods/{podUid}/volumeDevices/kubernetes.io~local-volume/spec.Name()`がデバイス(例: `/dev/sdb`)へのシンボリックリンク)になり、クリーンアップが必要となります。->再構築をサポート