Kubernetes v1.37 で Storage Version Migration が GA、既定で有効
Kubernetes v1.37 では StorageVersionMigration オブジェクトを作るだけで既存リソースの再書き込みが走る。旧 API 版の削除前や鍵ローテーション後の再書き込みを自前で回しているチーム向け。
Kubernetes v1.37 では StorageVersionMigration オブジェクトを作るだけで既存リソースの再書き込みが走る。旧 API 版の削除前や鍵ローテーション後の再書き込みを自前で回しているチーム向け。
Kubernetes v1.37 で、ストレージバージョン移行(Storage Version Migration、SVM)が GA になった。storagemigration.k8s.io/v1 の StorageVersionMigration API と、それを処理するコントロールプレーン側のコントローラが、v1.37 のすべてのクラスタで既定で有効になっている。出典は Kubernetes 公式ブログに2026年8月31日付で載った Michael Aspinwall(Google)の告知だ。
既定で有効といっても、クラスタを上げた瞬間に保存済みのリソースが書き換わるわけではない。移行が始まるのは StorageVersionMigration オブジェクトを作ったときだ。告知が使いどころとして挙げるのは、CRD から古い API バージョンを落とす場面と、保存時暗号化の鍵をローテーションする場面だ。この作業を kubectl get と kubectl replace を回すスクリプトや out-of-tree の kube-storage-version-migrator でこなしてきたチームは、v1.37 のクラスタなら同じことを標準 API でできる。
Kubernetes は API リソースを、そのリソースに定められたストレージバージョンの表現で保存する。告知の説明では、保存済みのリソースを最新のストレージバージョンに揃えるには、リソースそのものを書き換える(mutation)しかない。ストレージバージョンを変えたいときに面倒が起きるのはここに原因がある。
典型例が CRD のバージョン整理だ。v1alpha1 を落として v1beta1 と v1 だけにしたいとき、v1 を新しいストレージバージョンに指定しただけでは足りない。以後の書き込みは v1 で保存されるが、既存のリソースは v1alpha1 や v1beta1 のまま残りうる。ストレージ上のすべてのリソースが書き直されるまで、CRD の .status.storedVersions から v1alpha1 を外すことも、serving を止めることも安全にはできない。
もう一つが保存時暗号化と鍵ローテーションだ。暗号化を設定しても、鍵を替えても、既存のリソースは API サーバー経由で書き直されるまで平文のまま、あるいは古い鍵で暗号化されたまま残る。
これまで管理者と CRD 作者は、手書きの kubectl get / kubectl replace スクリプトか、out-of-tree の kube-storage-version-migrator を入れて強制的に書き直してきた。告知はこのやり方を「面倒で、間違いやすく、監視しにくい(訳)」と評している。
やることは宣言的な StorageVersionMigration オブジェクトを一つ作るだけだ。コントロールプレーンに組み込まれた StorageVersionMigrator コントローラがこのオブジェクトを監視し、対象 API の既定のストレージバージョンへ既存リソースを移行する。
告知の例は、crontabs.example.com という CRD のストレージバージョンを v1 に更新した後で、古いバージョンのまま保存されているリソースを移行するものだ。
apiVersion: storagemigration.k8s.io/v1
kind: StorageVersionMigration
metadata:
name: crontabs-migration
spec:
resource:
group: example.com
resource: crontabs
kubectl apply -f crontabs-migration.yaml
例で spec.resource に書いているのは group と resource だけで、移行元や移行先のバージョンは書いていない。移行先はその API の既定のストレージバージョンに決まる。
進捗はコントローラが StorageVersionMigration オブジェクトの status に書き込む。
kubectl get storageversionmigration.storagemigration.k8s.io/crontabs-migration -o yaml
成功すると Succeeded 条件が True になる。告知に載っている成功時の status は次の形だ。
status:
conditions:
- type: Running
status: "False"
lastUpdateTime: "2026-08-02T10:05:00Z"
reason: StorageVersionMigrationInProgress
- type: Succeeded
status: "True"
lastUpdateTime: "2026-08-02T10:05:00Z"
reason: StorageVersionMigrationSucceeded
Succeeded が True なら、そのリソースのすべてのインスタンスが現在のストレージバージョンで保存されていると見なせる。CRD の場合はここで .status.storedVersions を見る。移行後は優先バージョンだけが残っているはずで、古いバージョンが残っていれば移行中に CRD が更新されたことを意味する。その場合は移行をやり直してから、古いストレージバージョンの廃止に進む。
.status.storedVersions をコントローラが更新するのか、管理者が手で更新するのかは、告知には書かれていない。「更新されていなければ移行中に CRD が変更された」という書き方は自動更新を示唆するが、明記ではない。どちらであっても、移行後に storedVersions を自分で確かめる手順は省かないほうがいい。
StorageVersionMigration は標準の宣言的 API なので、CRD 作者は CRD の更新と同じマニフェストに移行を入れられる。告知の例では、v1 に storage: true を付けた CustomResourceDefinition と、上と同じ StorageVersionMigration を --- で並べている。
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: crontabs.example.com
spec:
group: example.com
# Updated versions list where v1 has storage: true
...
---
apiVersion: storagemigration.k8s.io/v1
kind: StorageVersionMigration
metadata:
name: crontabs-migration
spec:
resource:
group: example.com
resource: crontabs
Operator を配布している側から見ると、「CRD を更新したら利用者側で migrator を回してもらう」という手順書の一項目をマニフェストに畳み込める。前節のとおり、移行中に CRD が更新されると古いバージョンが storedVersions に残る。同梱したからといって、移行後の確認まで省けるわけではない。
v1.37 のクラスタには、同じ目的の API とコントローラが既定で入っている。out-of-tree の kube-storage-version-migrator を運用している場合、v1.37 に上げたクラスタではこの組み込み版が使える。ただし out-of-tree 版の今後の扱いや、両方を同時に動かした場合の挙動は告知には書かれていない。フィーチャーゲートの名前や無効化の可否も書かれていないので、有効・無効を明示的に切り替えたい場合は別途の確認が要る。
CRD の旧バージョンを落とす作業に組み込み版を使うなら、順番はこうなる。
versions で v1 に storage: true を付けて適用するspec.resource に group と resource を書いた StorageVersionMigration を作るSucceeded 条件が True になるのを待つ.status.storedVersions が優先バージョンだけになっていることを確かめる。古いバージョンが残っていれば手順2からやり直す鍵ローテーション後の再書き込みも同じ API で起こせると告知は位置づけているが、載っているマニフェスト例は CRD のものだけだ。コアグループのリソースを対象にするときの spec.resource の書き方は、この告知だけでは分からない。まずは検証クラスタで CRD 一つを対象に、Succeeded と storedVersions の動きを見てから本番に持ち込むのが無難だ。SIG API Machinery は採用後のフィードバックを Slack の #sig-api-machinery チャンネルで受け付けている。