Kubernetes 1.33: SIG Storageの変更内容

Kubernetes 1.33.0がリリースされました🎉

それでは、[Kubernetes 1.33.0のCHANGELOG](https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.33.md#v1320)をベースにSIG Storageに関する変更について紹介します。

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

過去 3 リリースの変更内容:
- [Kubernetes 1.32: SIG Storageの変更内容](https://qiita.com/everpeace/items/3a4ef4004b96f62fdc23)
- [Kubernetes 1.31: SIG Storageの変更内容](https://qiita.com/ysakashita/items/e5121b77bea1fbd170f5)
- [Kubernetes 1.30: SIG Storageの変更内容](https://qiita.com/ysakashita/items/07fab50bff17c10fa07d)

# :pencil: 所感

SIG Storageは、v1.33では、多くの機能がGAへ昇格し、大分安定してきている印象を受けます。

v1.33の注目機能(Alpha)としては下記です(詳細は本文の :pencil: を参照ください)。
- `StorageCapacityScoring`: Dynamic provisioningなvolumeを持つPodをスケジュールする際に空き容量を考慮してノードのスコアリングできる機能
- `MutableCSINodeAllocatableCount`: `CSINode.Spec.Drivers[*].Allocatable.Count`がmutableにできる機能

Feature昇格は下記の通りです:
- Beta昇格
  - `SELinuxChangePolicy`, `SELinuxMount(disabled by default)`
- GA昇格
  - `AnyVolumeDataSource`
  - `CSIMigrationPortworx`
  - `HonorPVReclaimPolicy`
- GA後のfeature gate削除
  - `PersistentVolumeLastPhaseTransitionTime`

# :warning: Urgent Upgrade Notes（必ず一読してからアップグレードしなければならない事項）

- [Action Required] `IsLikelyNotMountPoint` を呼んでいるCSI driverは `false`が返ってきても、そのパスがマウントポイントだと想定するべきではありません。 渡されたファイルがイレギュラーなファイルで実際はマウントポイントでない場合には許容されてしまうので、CSI Driverは返り値を適切に利用する必要があります([#129370](https://github.com/kubernetes/kubernetes/pull/129370), [@andyzhangx](https://github.com/andyzhangx))
:::note info
:pencil: Windowsでのみインパクトのある修正です。go 1.23で入ったWindowsにおけるマウントポイントのパース処理の変更による影響です。
:::

# :wastebasket: Deprecation (非推奨になったAPI)
- `StorageCapacityScoring` feature gateが追加され、ストレージの空き容量でノードをスコアするようになりました。これはAlphaステージであり、デフォルトでdisabledです。これに伴って`VolumeCapacityPriority` Alpha feature gateはこのfeature gateで置き換えられます。デフォルトの挙動も変更になります。`VolumeCapacityPriority`は空き容量が少ないノードを優先していましたが、`StorageCapacityScoring`は空き容量が多いノードを優先します。詳しくは[KEP-4049](https://github.com/kubernetes/enhancements/blob/master/keps/sig-storage/4049-storage-capacity-scoring-of-nodes-for-dynamic-provisioning/README.md)を参照してください([#128184](https://github.com/kubernetes/kubernetes/pull/128184), [@cupnes](https://github.com/cupnes))
:::note info
:pencil: 古いAlpha feature gateが置き換えられているのでDeprecationのセクションに記載されていますが、`StorageCapacityScoring`は新機能です。

[Kubernetes Blog - Kubernetes v1.33: Storage Capacity Scoring of Nodes for Dynamic Provisioning (alpha)](https://kubernetes.io/blog/2025/04/30/kubernetes-v1-33-storage-capacity-scoring-feature/)

:eyes: ブログタイトルにもあるようにこのスコアリングはDynamic Provisioningのボリュームのみを持つPodのスケジューリング時に機能します。

また、デフォルトで空き容量が多いノードを優先する仕様にしているのは、スケジュール後にPVを拡張するユースケースを重視しているからのようです。リソース/費用効率からビンパッキングしたいこともあるため、
スコアロジックは`VolumeBinding`プラグインの設定(`.args`)に`.shape`というフィールド([`RequestedToCapacityRatio`プラグインで使える](https://kubernetes.io/docs/concepts/scheduling-eviction/resource-bin-packing/)ものと同じ)が追加されており、このフィールドで変更できます。

```yaml
apiVersion: kubescheduler.config.k8s.io/v1
kind: KubeSchedulerConfiguration
profiles:
  ...
  pluginConfig:
  - name: VolumeBinding
    args:
      ...
      # スプレッド:
      # (StorageCapacityScoring feature gateのdefault)
      # utilizationが低い=空き容量が多い方を優先
      shape:
      - utilization: 0
        score: 10
      - utilization: 100
        score: 0
      
      # ビンパッキング: 
      # utilizationが高い=空き容量が少ない方を優先
      shape:
      - utilization: 0
        score: 0
      - utilization: 100
        score: 10
```
:::


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

- 新しいAlpha feature gate `MutableCSINodeAllocatableCount`が導入されました。このfeature gateが有効になると、`CSINode.Spec.Drivers[*].Allocatable.Count`フィールドがmutableになります。また、新しいフィールド`NodeAllocatableUpdatePeriodSeconds`が`CSIDriver`オブジェクトで利用可能になります。このフィールドはnodeによって報告されたvolume capacityを定期的に更新させることで、stateful podが、kube-schedulerが古い情報を参照してしまうことでスタックすることを防ぎます([#130007](https://github.com/kubernetes/kubernetes/pull/130007), [@torredil](https://github.com/torredil))

:::note info
:pencil: 
[KEP-4876: Mutable CSINode Allocatable Property](https://github.com/kubernetes/enhancements/issues/4876)
 [Kubernetes Blog - Kubernetes v1.33: Mutable CSI Node Allocatable Count](https://kubernetes.io/blog/2025/05/02/kubernetes-1-33-mutable-csi-node-allocatable-count/)

クラウドなどではVMにアタッチできるボリューム数上限があり、CSI以外のボリューム操作や、複数CSIドライバが稼働している場合には、ドライバ毎のアタッチ上限は動的に変化します。

また、誤ったAllocatable.CountでスケジュールされてしまったPodは、ContainerCreatingでスタックしてしまうため、効率的なStatefulワークロードのスケジューリングにおいては重要な機能と言えます。
:::
- `AnyVolumeDataSource` feature gateをGAに昇格させました。([#129770](https://github.com/kubernetes/kubernetes/pull/129770), [@sunnylovestiramisu](https://github.com/sunnylovestiramisu))
- `ClusterTrustBundle` APIは`v1beta1`に移行します。`ClusterTrustBundleProjection` featureをkubeletで対応するためには、`ClusterTrustBundle` APIの`v1beta1`バージョンが利用可能な状態で、かつ、`ClusterTrustBundleProjection` feature gateが有効でなくてはなりません。kubelet起動後にこのAPIが有効になった場合は、機能を有効にするためにkubeletをリスタートしてください。([#128499](https://github.com/kubernetes/kubernetes/pull/128499), [@stlaz](https://github.com/stlaz))
:::note info
:pencil: 
[KEP-3257: ClusterTrustBundles (previously Trust Anchor Sets)](https://github.com/kubernetes/enhancements/issues/3257)
[Kubernetes Documentation / Concepts / Storage / Projected Volumes / clusterTrustBundle projected volumes](https://kubernetes.io/docs/concepts/storage/projected-volumes/#clustertrustbundle)
:::

# :sparkle: Features (機能追加)
- volume group snapshotのe2eテストを追加しました([#128972](https://github.com/kubernetes/kubernetes/pull/128972), [@manishym](https://github.com/manishym))
- kube-controller-managerがコンテナで実行されている際の`SELinuxWarningController`のデフォルト値を修正しました([#130037](https://github.com/kubernetes/kubernetes/pull/130037), [@jsafrane](https://github.com/jsafrane))
  - :pencil: [KEP-1710: Speed up recursive SELinux label change](https://github.com/kubernetes/enhancements/issues/1710)
- kube-apiserver: `StorageObjectInUseProtection` アドミッションプラグインは、`VolumeAttributeClass`が有効かつ`storage.k8s.io/v1beta1`も有効な場合、`kubernetes.io/vac-protection`ファイナライザを`VolumeAttributesClass`作成時に追加するようになりました([#130553](https://github.com/kubernetes/kubernetes/pull/130553), [@Phaow](https://github.com/Phaow))
- `CSIMigrationPortworx` feature gateをGAに昇格させました。アプリケーションがPortworxボリュームを利用している場合、1.31以降にアップグレードする**前に**、対応するPortworx CSIドライバがインストールされてていることを確認してください。このfeature gateが有効な場合、すべてのin-tree `portworxVolume`はpxd.portworx.com CSIドライバにリダイレクトされるためです([#129297](https://github.com/kubernetes/kubernetes/pull/129297), [@gohilankit](https://github.com/gohilankit))
- `HonorPVReclaimPolicy` feature gateをGAに昇格させました([#129583](https://github.com/kubernetes/kubernetes/pull/129583), [@carlory](https://github.com/carlory))
- `SELinuxChangePolicy`,`SELinuxMount`がBetaに昇格しました。`SELinuxMount`はデフォルトoffのままです。([#130544](https://github.com/kubernetes/kubernetes/pull/130544), [@jsafrane](https://github.com/jsafrane))
  - :pencil: [KEP-1710: Speed up recursive SELinux label change](https://github.com/kubernetes/enhancements/issues/1710)
- `StorageCapacityScoring` feature gateが追加され、ストレージの空き容量でノードをスコアするようになりました。これはAlphaステージであり、デフォルトでdisabledです。これに伴って`VolumeCapacityPriority` Alpha feature gateはこのfeature gateで置き換えられます。デフォルトの挙動も変更になります。`VolumeCapacityPriority`は空き容量が少ないノードを優先していましたが、`StorageCapacityScoring`は空き容量が多いノードを優先します。詳しくは[KEP-4049](https://github.com/kubernetes/enhancements/blob/master/keps/sig-storage/4049-storage-capacity-scoring-of-nodes-for-dynamic-provisioning/README.md)を参照してください([#128184](https://github.com/kubernetes/kubernetes/pull/128184), [@cupnes](https://github.com/cupnes))


# 📃 Documentation (ドキュメント)
:pencil: SIG Storage関連のものはありません

# :bug: Bug or Regression (バグ修正)
- ボリュームのpermission/ownershipの変更進捗を追加しました([#130398](https://github.com/kubernetes/kubernetes/pull/130398), [@gnufied](https://github.com/gnufied))
:::note info
:pencil: ボリュームのpermisison/ownershipの大規模な変更を抑制するために`fsGroupChangePolicy: onRootMismatch`(ルートでだけチェック)がありますが、`fsGroupChangePolicy: Always`な場合に、下記のように進捗イベントが発砲されるようになります。
```
  Warning  VolumePermissionChangeInProgress  2m50s  kubelet                  Setting volume ownership for /var/lib/kubelet/
pods/29928e79-9a46-4ab9-8aab-c612e82ec0d9/volumes/kubernetes.io~csi/biginode/mount is taking longer than 
expected, consider using OnRootMismatch - https://kubernetes.io/docs/tasks/configure-pod-container/security-context/
#configure-volume-permission-and-ownership-change-policy-for-pods

  Warning  VolumePermissionChangeInProgress  110s   kubelet                  Setting volume ownership for /var/lib/kubelet/
pods/29928e79-9a46-4ab9-8aab-c612e82ec0d9/volumes/kubernetes.io~csi/biginode/mount, processed 2654670 files.

  Warning  VolumePermissionChangeInProgress  50s    kubelet                  Setting volume ownership for /var/lib/kubelet/
pods/29928e79-9a46-4ab9-8aab-c612e82ec0d9/volumes/kubernetes.io~csi/biginode/mount, processed 5121525 files.
```
:::
- Fix: go1.23におけるWindowsでのmount pointパース処理の変更を適用しました([#129368](https://github.com/kubernetes/kubernetes/pull/129368), [@andyzhangx](https://github.com/andyzhangx))
- マルチパスに関するストレージバグを修正しました。iSCSIやFibre Channelデバイスがmultipathでアタッチされている場合、デバイスパーティションを正しく解決します([#128086](https://github.com/kubernetes/kubernetes/pull/128086), [@RomanBednar](https://github.com/RomanBednar))    
- `volume_linux_test.go`における`TestSetVolumeOwnershipOwner`の`fsGroup=3000`の場合とsymlinkケースの場合のテスト失敗を修正しました。このテストは所有権の不完全な検証によるもので、所有権変更処理の調整、rootで動作する時の挙動の修正を行うことで解決しました([#130616](https://github.com/kubernetes/kubernetes/pull/130616), [@gnufied](https://github.com/gnufied))
- 参照しているPVCがユーザによって削除されている最中にkubeletが再起動すると実行中のpodのvolumeをunmountする問題を修正しました([#130335](https://github.com/kubernetes/kubernetes/pull/130335), [@carlory](https://github.com/carlory))
- クラスタでPortworx security feature(Kubernetesの機能ではなくPortworxの機能)が有効な場合に、Portworxボリュームのin-tree CSI migrationを修正しました。in-tree Storage Classで参照されているSecretの認証データがCSIリクエストに渡されるべきですが、この修正前は行われていませんでした。([#129630](https://github.com/kubernetes/kubernetes/pull/129630), [@gohilankit](https://github.com/gohilankit))
- Nominated nodeが変化した時の処理を正しく扱うようにスケジューリングの挙動を見直しました。Nominated node名が消されたり別のノードにnominateされたりした際にpodの再スケジューリングをトリガします([#129058](https://github.com/kubernetes/kubernetes/pull/129058), [@dom4ha](https://github.com/dom4ha))

# :microscope: Others (その他修正)
- Podがlabel/selectorとマッチしないボリュームをアタッチしようとする時のエラーメッセージを、"x node(s) had volume node affinity conflict"から"x node(s) didn't match PersistentVolume's node affinity"に変更しました([#129887](https://github.com/kubernetes/kubernetes/pull/129887), [@rhrmo](https://github.com/rhrmo))
- GA feature gate `PersistentVolumeLastPhaseTransitionTime`を削除しました([#129295](https://github.com/kubernetes/kubernetes/pull/129295), [@carlory](https://github.com/carlory))