Kubernetes 的 Changed Block Tracking(CBT,变更块跟踪)已经从 Alpha 进入 Beta。2026 年 3 月发布的 external-snapshot-metadata v1.0.0 带来了一个看似简单、但升级时不能忽略的变化:SnapshotMetadataService CRD 从 v1alpha1 切换为 v1beta1,并且旧版本不再继续提供服务。
CBT 面向块存储卷,主要用于让备份系统只读取快照之间发生变化的块,从而减少备份所需的 I/O、网络流量和存储空间。当前功能不覆盖文件卷,也不覆盖网络文件共享的 changed-list 跟踪。
Beta 版本到底改了什么
CBT 仍然由三个核心部分组成:
- CSI SnapshotMetadata gRPC 服务:由 CSI 驱动提供元数据能力。
SnapshotMetadataServiceCRD:在 Kubernetes 中声明某个驱动的元数据服务。external-snapshot-metadatasidecar:连接 Kubernetes、CSI 驱动和客户端之间的元数据流程。
Beta 的核心变化集中在 CRD API 版本:
apiVersion: cbt.storage.k8s.io/v1beta1
kind: SnapshotMetadataService
metadata:
name: example-csi-driver
namespace: kube-system
spec:
driver: example.csi.driver
endpoint: unix:///run/csi/snapshot-metadata.sock
CRD 的 schema 本身没有变化,但 v1alpha1 被移除,不会和 v1beta1 并行提供,也不存在自动转换。因此,升级不能只替换 sidecar 镜像;集群中的 CRD、资源清单以及读取该 CRD 的客户端或控制器都需要同步检查。
从 Alpha 升级到 Beta 的操作清单
最低兼容条件如下:
- Kubernetes
1.33或更高版本。 - CSI specification
1.10或更高版本。 registry.k8s.io/sig-storage/csi-snapshot-metadata:v1.0.0。
建议在测试集群中按下面的顺序执行。将 CRD 文件路径替换为你下载的 v1.0.0 发布包中的实际文件名:
set -euo pipefail
# 1. 确认 Kubernetes 版本
kubectl version
# 2. 重新安装 v1.0.0 提供的 v1beta1 CRD
kubectl apply -f snapshotmetadataservices.cbt.storage.k8s.io-v1beta1.yaml
# 3. 确认 apiserver 当前提供的版本
kubectl get crd snapshotmetadataservices.cbt.storage.k8s.io \
-o jsonpath='{.spec.versions[*].name}{"\n"}'
# 4. 查看现有资源,确认清单已切换到 v1beta1
kubectl get snapshotmetadataservices.cbt.storage.k8s.io -A -o yaml
然后更新所有 SnapshotMetadataService 清单:
apiVersion: cbt.storage.k8s.io/v1beta1
kind: SnapshotMetadataService
metadata:
name: my-csi-driver
namespace: kube-system
spec:
driver: csi.example.com
endpoint: unix:///run/csi/snapshot-metadata.sock
这里的 spec 字段应以你使用的 CRD 定义和 CSI 驱动实现为准。Beta 的关键要求是 API 版本必须改为 cbt.storage.k8s.io/v1beta1,而不是假设旧的 v1alpha1 会被 Kubernetes 自动转换。
如果你的备份控制器直接使用 Kubernetes API 查询这个 CRD,也要检查代码中的 GVK、客户端类型和 RBAC 配置。升级前可以搜索仓库:
grep -R "cbt.storage.k8s.io/v1alpha1\|SnapshotMetadataService" \
./manifests ./charts ./cmd ./pkg
如何验证端到端流程
使用 CBT 前,CSI 驱动需要同时支持卷快照,并携带 external-snapshot-metadata sidecar。部署完成后,备份客户端可以调用两个主要接口:
GetMetadataAllocated:获取已分配或需要关注的块元数据。GetMetadataDelta:获取两个快照或时间点之间发生变化的块。
可以使用 snapshot-metadata-lister 示例客户端,也可以实现自己的客户端。实际验证时,建议覆盖以下路径:
- 创建一个块卷并写入测试数据。
- 创建第一个卷快照,记录快照标识。
- 修改一部分块,再创建第二个快照。
- 调用
GetMetadataDelta,确认结果只包含预期变化范围。 - 删除或轮转快照,验证客户端如何处理失效的快照引用和迭代器错误。
CBT 的价值在于增量备份效率,而不是替代快照本身。备份系统仍然需要设计快照生命周期、元数据持久化、重试和故障恢复策略。
Beta 阶段适合谁来试
对 CSI 驱动维护者来说,Beta 是评估接入的合适阶段:API 已经从 Alpha 晋升,但生态仍在扩大,生产环境反馈仍然重要。需要重点观察驱动对块设备快照、元数据服务、sidecar 生命周期以及并发请求的支持情况。
对备份软件开发者来说,除了基本的 gRPC 调用,还应关注 streaming client 和 iterator 的行为,例如:
- 大卷场景下结果是否需要分批读取。
- 客户端中断后能否安全重试。
- 快照不存在或已被清理时如何报告错误。
- 备份任务是否会因为元数据服务暂时不可用而错误地退化为全量备份。
升级前的快速检查表
- [ ] Kubernetes 版本至少为
1.33。 - [ ] CSI specification 至少为
1.10。 - [ ] CSI 驱动支持块卷快照和 SnapshotMetadata 服务。
- [ ] sidecar 使用
v1.0.0镜像。 - [ ] 已重新应用
v1beta1CRD 定义。 - [ ] 所有
SnapshotMetadataService资源改用cbt.storage.k8s.io/v1beta1。 - [ ] 控制器、客户端和 RBAC 不再依赖
v1alpha1。 - [ ] 已验证
GetMetadataAllocated和GetMetadataDelta的错误、重试和大结果集行为。
Beta 并不意味着所有 CSI 驱动都已经支持 CBT。更稳妥的落地方式是先在 hostpath 驱动或测试环境中跑通完整流程,再为真实存储后端加入能力探测、监控和全量备份兜底。这样既能获得增量备份收益,也不会把备份可靠性押在一个尚未经过自身生产流量验证的新路径上。