JavaLYG

Kubernetes 1.37 存储版本迁移:CRD 升级后的三层验收与失败排查

Kubernetes 1.37 有个很容易被升级日志盖住的变化:Storage Version Migration(SVM)已经进入 GA,storagemigration.k8s.io/v1 API 和控制器默认启用。它解决的不是“API 能不能访问”,而是 CRD 切换存储版本后,etcd 里遗留的旧对象是否已经被转换并重写。本文用一套可复核的流程,把 CRD 升级从“看起来成功”变成有证据的验收。

Kubernetes 1.37 存储版本迁移验收链

一、先分清三个版本

API 版本决定客户端请求路径;served: true 表示 API Server 仍提供该版本;storage: true 表示新写入对象优先以哪个版本保存。比如 CRD 同时提供 v1alpha1、v1 和 v1,只有一个版本应该是 storage。把 storage 改成新版本,只影响新写入,历史对象不会凭空改写。

二、1.37 到底改变了什么

Kubernetes 官方 1.37 发布说明和 8 月 31 日的专题文章确认:SVM 已 GA,内置 API 与控制器在 v1.37 集群默认启用。它提供稳定的迁移机制,但不会替运维决定迁移哪个 Resource,也不会替你验证 conversion webhook、备份和业务字段。

三、升级前留证

kubectl version
kubectl get crd crontabs.example.com -o yaml
kubectl get crd crontabs.example.com -o jsonpath='{.spec.versions[?(@.storage==true)].name}'
echo
kubectl api-resources | grep -i crontab
kubectl get crontabs.example.com -A -o yaml

示例中的域名和资源名是占位符。生产环境还应保存 CRD YAML、资源数量和一份可恢复备份。升级前先读一条真实对象,用来区分“迁移失败”和“原本就读不通”。

四、正确的切换顺序

先部署并验证 conversion webhook,再保证旧、新版本都能读取、创建、更新和列表;然后把目标版本设为 storage: true,最后创建 SVM。重点检查 spec.versions 中只有一个 storage=true,以及 status.storedVersions 当前包含哪些历史版本。

五、创建迁移对象

cat > migrate-crd.yaml <<'EOF'
apiVersion: storagemigration.k8s.io/v1
kind: StorageVersionMigration
metadata:
  name: crontabs-migration
spec:
  resource:
    group: example.com
    resource: crontabs
EOF
kubectl apply -f migrate-crd.yaml
kubectl get storageversionmigration.storagemigration.k8s.io crontabs-migration -o yaml

groupresource 必须以 API Discovery 的结果为准,不要把 CRD 的复数名称、Kind 和 group 写混。若目标集群不是 1.37,先查该集群实际提供的 API 版本。

六、三层验收,不只看 Succeeded

第一层看迁移对象的 status.conditions,确认 Succeeded=True

kubectl wait --for=condition=Succeeded storageversionmigration.storagemigration.k8s.io/crontabs-migration --timeout=10m
kubectl get storageversionmigration.storagemigration.k8s.io crontabs-migration -o yaml

第二层看 CRD 的存储版本:

kubectl get crd crontabs.example.com -o jsonpath='{.status.storedVersions}'
echo

待淘汰的旧版本应从列表中消失。第三层做抽样读写:分别用旧、新 API 读取对象,更新一个无业务影响的字段,再列表并比较关键字段。转换 webhook 自定义字段时,尤其要检查默认值、枚举和嵌套数组是否丢失。

七、卡住时按证据排查

Kubernetes 存储迁移失败排查清单

现象先查常见方向
API 不存在kubectl api-resources集群版本或 Discovery 不匹配
一直 Runningconditions、事件、控制器日志资源读取失败或控制器异常
成功但仍有旧版本CRD storedVersionsgroup/resource 或 webhook 不正确
对象读取报错API Server 与 webhook 日志证书、网络或双向转换问题

八、回滚边界

失败时先暂停后续 CRD 清理,修复 webhook 或 schema,再按状态重试。不要无备份地把 storage 改回旧版本,更不要手工编辑 etcd。真正的回滚必须确认新字段可以安全转换回旧版本,并保留变更、备份和抽样读写证据。

九、上线清单

  • Discovery、集群版本和 SVM API 已确认。
  • CRD 只有一个 storage 版本,目标版本正确。
  • Webhook 的读、写、列表和双向转换已验证。
  • SVM 为 Succeeded=True,完整 status 已归档。
  • storedVersions 不再包含待淘汰版本。
  • 抽样对象字段完整,业务控制器无新增错误。
  • 备份、回滚边界和变更记录齐全。

🔕 评论已关闭