Kubernetes 1.30: SIG Storageの変更内容

# はじめに

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

## アップグレード前に絶対に確認が必要な変更点 (Urgent Upgrade Notes)

SIG Storageに関連するものはなし

## Changes by Kind
### 非推奨 (Deprecation)

SIG Storageに関連するものはなし

### APIの変更 (API Change)

- volumeBindingプラグインに対するprescoreの拡張ポイントを実装しました。Scoreで何もしない場合はskipします。(#115768, @AxeZhan)
- readOnlyのボリュームにて、Kernelのバージョンが5.12以上再帰的な読み取り専用(read-only)マウントをサポートします。(#123180, @AkihiroSuda)
- cri-api: KEP-3857: 再帰的な読み取り専用(RRO)マウントを実装しました。(#123272, @AkihiroSuda)
- kube-controller-managerに対してdisable-force-detach のCLIオプションを追加しました。デフォルトではfalseに設定されています。有効にすると、最大アンマウント時間およびノードの状態に基づいてボリュームを強制的にデタッチすることを防ぎます。有効化した場合、非グレースフルなノードシャットダウン機能を使用してノードの障害からの復旧が必要です。さらに、Podをデータの破損のリスクを伴って強制終了させる必要がある場合は、適切なVolumeAttachmentオブジェクトを削除する必要があります。(#120344, @rohitssingh)

:memo:disable-force-detachオプションについての詳細は以下をご参照ください。
<details> <summary>詳細</summary>
これまで、ノードのシャットダウンにてアンマウントが正しく行われず、ストレージ側からみたらクライアントとのセッションが残りっぱなし(デタッチ失敗)となるケースにおいて、6分待ち強制デタッチを行っていました。
https://github.com/kubernetes/kubernetes/blob/v1.30.0/pkg/controller/volume/attachdetach/attach_detach_controller.go#L96

この6分の間は、主にブロックストレージなどReadWriteMany(複数ノードからのRead/Write)を許可していないVolumeの場合、再びマウントしようと試みても、Multi Attach Errorとなります。
この6分を待たずにデタッチを強制的に行うためには、非グレースフルなノードシャットダウン機能が提供されていました。
非グレースフルなノードシャットダウン機能ではユーザが対象のノードにtaintを付与した場合に強制的にデタッチなどを行います。
非グレースフルなノードシャットダウン機能の詳細は[「Kubernetes: Non Graceful Node Shutdownの動作検証」](https://qiita.com/ysakashita/items/1a7fdf1688819a0a4580)の記事をご参照ください。

今回追加されたオプションは、この6分後の強制デタッチを行わないようにするオプションです。
利用環境によっては、6分後に強制デタッチをされてしまうことで、他のノードから対象のVolumeが意図せずマウントされてしまいデータの上書きなどによるデータ破壊が起こるリスクがあります。
このようなケースでは有効なオプションとなります。
一方で、本オプションを有効(デフォルトは無効)にすると、ノードの自動復旧など行うことを想定するケースでは自動復旧を妨げる要因となってしまいます。

利用される環境やユースケースにて、本オプションを有効化した方が良いかどうかを見定めた上で利用されることをお勧めします。
</details>

### 機能 (Feature)

- VolumeManagerReconstruction がGAになりました (#123442, @jsafrane)

:memo: 本機能はユーザが直接操作するようなものではありませんが、kubeletの起動中にVolumeがどのようにマウントされているかの情報をkubeletに伝えるための機能になります。これにより、より適切にVolumeのマウント/アンマウント/アタッチ/デタッチを制御することが可能となります。

- volume_manager_selinux_* メトリックスにaccess_modeラベルを追加しました。(#123667, @jsafrane)
- SELinuxの再ラベリングを高速化するために、新しいfeature gate(アルファ)である`SELinuxMount`が導入されました。(#123157, @jsafrane)
- スケジューラーは、PVCが見つからないためにnodevolumelimitsによって失敗したPodを、新しいPVCが追加されたときのみ再試行するようになりました。(#121952, @sanposhiho)

### ドキュメンテーション (Documentation)

SIG Storageに関連するものはなし

### 失敗するテスト (Failing Test)

SIG Storageに関連するものはなし

### バグまたはリグレッション (Bug or Regression)

- バージョン1.29.0以降に導入された、in-treeのvSphereボリュームをCSIドライバに移行する際のリグレッションを修正しました。(#122341, @jsafrane)
- readonlyボリュームを使用してPodが作成される場合、ボリュームの容量が要求されたストレージと同じかそれ以上であればFileSystemResizeFailedの誤った警告イベントを削除しました。(#122508, @carlory)
- ノード再起動時に、Rawブロックボリュームを使用するPodの削除を可能にしました。(#122211, @gnufied)
- kubeletが再構築に失敗したすべてのボリュームをクリーンアップしようとするとき、GenerateUnmapVolumeFuncがglobalUnmapPathを欠いているため、PodがTerminatingの状態で停止してしまう問題を修正しました。(#123032, @carlory)
- ノードの拡張を必要としないボリュームを拡張しようとしたときのエラーを修正しました。(#123055, @gnufied)
- 静的にプロビジョニングされたPVが、そのボリュームソースがCSIタイプであるか又は移行済みのアノテーションを持っている場合、削除されたとき、PersistentVolume controllerはそのフェーズをFailed状態に変更しないようになります。これによりexternal provisionerは次のreconcile loopでfinalizerを削除することができます。ただし、以前に存在したPVがFailed状態である場合、このパッチは効果がありません。ユーザーは手動でfinalizerを削除する必要があります。(#122030, @carlory)
- PersistentVolume controllerはstorageClassNameが空のPersistentVolumeClaims(PVC) にデフォルトのStorageClassを自動的に割り当てなくなりました。(#122704, @carlory)
- ValidateVolumeAttributesClassUpdateは新しいVolumeAttributesClassオブジェクトも検証します。(#122449, @carlory)

### その他 (Cleanup or Flake)

- Cleanup: getStorageAccountNameの警告メッセージを削除しました。(#121983, @andyzhangx)
- reclaim policyが`Recycle`のときのPVに対する警告を追加しました。(#122339, @carlory)
- azureFile向けのin-treeのストレージプラグインは非推奨となり、削除されました。(#122576, @carlory)
- Azure向けのin-treeのクラウドプロバイダは削除されました。代わりにhttps://github.com/kubernetes/cloud-provider-azure からexternal cloud providerとCSIドライバを使用してください。(#122857, @nilo19)
- vSphere向けのin-treeのcloud providerは非推奨とされ削除されました。ユーザーは、https://github.com/kubernetes/cloud-provider-vsphere で利用可能なexternal cloud providerとCSIドライバを利用することが推奨されます。(#122937, @dims)

# CHANGELOG外の変更点

本内容は、[CHANGELOG](https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.30.md#changelog-since-v1290)には記載がない変更点です。
[Kubernetes v1.30: Uwubernetes](https://kubernetes.io/blog/2024/04/17/kubernetes-v1-30-release/)にて「Prevent unauthorized volume mode conversion during volume restore」が紹介されているため記載します。

- [external-provisioner v4.0.0](https://github.com/kubernetes-csi/external-provisioner/releases/tag/v4.0.0): `prevent-volume-mode-conversion`の機能フラグをデフォルトで有効化しました
  - VolumeSnapshotからPVCを作成する場合、AllowVolumeModeChangeアノテーションがtrueに設定されていない限り、ボリュームモードの変更は拒否されます。VolumeSnapshotからPVCを作成する際にボリュームモード変更に依存するアプリケーションは、それに応じて更新する必要があります。(#1126、@akalenyu)
- [external-snapshotter v7.0.0](https://github.com/kubernetes-csi/external-snapshotter/releases/tag/v7.0.0)
  - external-provisioner v4.0.0の`prevent-volume-mode-conversion`と同じコメントのため割愛します。 (#916, @akalenyu)

:memo: external-provisioner, external-snapshotterにてサポートされたPrevent unauthorized volume mode conversionの機能の詳細については、 [「Kubernetes: Prevent unauthorized volume mode conversion during volume restoreの動作検証」](https://qiita.com/ysakashita/items/0bb38c39d70acd211da7) にて記事を公開したため、ご興味のある方はご参照ください。

# 所感

Kubernets v1.30では、PVC/PVのユースケースに大きく影響するような機能の追加はありませんでした。
その代わり、ノードがグレースフルにシャットダウンできなかった時などに強制デタッチとなる挙動を抑止するdisable-force-detachオプションの追加や、VolumeSnapshotからのリストア時に異なるVolumeModeでリストアをしないように抑止するPrevent unauthorized volume mode conversionなどが追加されました。
これらの機能は、障害発生時など通常ではなかなか遭遇しないケースで活躍する機能になります。
特に、ストレージの場合、障害時の対応を間違えるとデータ欠損やデータ消失といった企業生命を脅かしかねない事故につながります。
そのため、紹介したような機能らを理解し、これらの機能が必要な環境であると感じる場合には設定した方が安全なKubernetes環境になります。
ただし、環境によっては、逆に自動復旧などを妨げてしまうことになりかねないため、闇雲に設定するのではなく正しく内容を理解した上で設定判断を行うと良いでしょう。