volumeClaimTemplates 是什么
volumeClaimTemplates 是 StatefulSet 里的 PVC 模板:控制器按模板与副本序号为每个 Pod 生成一份独立 PVC,命名规则为 <模板名>-<StatefulSet 名>-<序号>。Pod 被删除、重建或被调度到别的节点后,仍会挂回属于自己序号的那份数据,因此它是数据库、消息队列、ZooKeeper 这类有状态服务在 Kubernetes 上的标准存储做法,与 Deployment 里所有副本共用一个卷的模式有本质区别。
基本信息
| 所属对象 | StatefulSet.spec.volumeClaimTemplates |
|---|---|
| 生成对象 | 每个副本一份独立 PVC |
| 命名规则 | <模板名>-<statefulset 名>-<序号> |
| 模板变更 | 不追溯已有副本,只影响之后新建的 |
| 删除行为 | 缩容或删除 StatefulSet 默认保留 PVC |
典型使用场景
- 数据库主从:data-mysql-0、data-mysql-1 各自独立数据目录,重启后数据不串位
- 消息队列与搜索引擎:每个副本绑定自己的索引目录,避免多写共享卷损坏数据
- 需要稳定网络标识的服务:配合 headless Service,Pod 名与卷一一对应,扩容缩容行为可预测
- 单副本有状态应用的存储声明:用 StatefulSet + volumeClaimTemplates 拿到比 Deployment 更明确的卷归属
- 按副本差异化存储:不同序号可挂不同 StorageClass 的卷(较新版本支持在模板中按序号覆盖)
声明模板
声明模板
volumeClaimTemplates:
- metadata:
name: data # 生成 data-db-0、data-db-1 ...
spec:
accessModes: ['ReadWriteOnce'] # 云盘类卷为单节点语义
storageClassName: fast-ssd # 显式指定,避免落到默认类
resources:
requests:
storage: 50Gi查看与核对
查看与核对
kubectl get pvc -l app=db # 按标签看每个副本的 PVC
kubectl get pvc data-db-0 -o jsonpath='{.spec.storageClassName} {.status.phase}'
kubectl get pod db-0 -o jsonpath='{.spec.volumes[*].persistentVolumeClaim.claimName}' # 确认挂的是自己那份
kubectl describe pvc data-db-1 | sed -n '/Events:/,$p' # 未绑定/扩容失败都会在这里留原文PVC 逐列读法
| 列 | 含义 | 正常/异常 |
|---|---|---|
| NAME | 模板名-StatefulSet名-序号 | 序号应与 Pod 名对应,缺号说明对应副本被删过 |
| STATUS | Bound 已绑定,Pending 未就绪 | 长期 Pending 看 StorageClass 与拓扑条件 |
| VOLUME | 绑定的 PV 名 | 为空说明还没绑定成功 |
| CAPACITY | 已分配容量 | 改大 requests 后此处不更新说明扩容未完成 |
| STORAGECLASS | 实际使用的存储类 | 与模板声明不一致说明落了默认类 |
模板只在新副本创建时被读取:给已有副本扩容要单独改对应 PVC 的 requests.storage,且 StorageClass 需开启 allowVolumeExpansion。缩容不会自动删除 PVC,这是防误删数据的设计,要清理必须显式删除 pvc。