Kubernetes PVC 扩容全流程实战:从原理到操作详解

在 Kubernetes 集群中,当 PVC 存储空间不足时,如何进行安全扩容?本文将深入剖析 PVC 扩容的完整流程,并以 QingCloud CSI 为例,带你掌握 offline 扩容的每一个细节。

PVC 扩容流程概览

在开始扩容操作前,我们需要了解 PVC 扩容的三个关键约束条件:

  1. CSI 驱动程序支持 - 驱动必须支持扩容操作
  2. 存储类配置 - StorageClass 必须允许扩容
  3. 扩容模式 - 区分 online 和 offline 扩容模式

一、确认 CSI 驱动支持情况

1.1 检查驱动支持的扩容模式

首先需要确认你使用的 CSI 驱动是否支持卷扩容,以及支持哪种扩容模式:

  • Online 扩容:Volume 可以在已挂载到 Pod 时进行扩容,无需停止服务
  • Offline 扩容:Volume 必须先卸载(即停止相关 Pod)才能扩容

以 QingCloud CSI 为例,它仅支持 Offline 扩容,这意味着扩容过程中需要暂时停止使用该 PVC 的 Pod。

1.2 查阅官方文档

不同 CSI 驱动的支持情况各异,务必查阅对应云厂商或存储提供商的文档:

csharp 复制代码
# 查看当前集群中安装的 CSI 驱动
kubectl get csidrivers.storage.k8s.io

# 获取 CSI 驱动的详细信息
kubectl describe csidriver <driver-name>

二、确认 StorageClass 配置

2.1 检查 allowVolumeExpansion 参数

StorageClass 必须显式允许卷扩展才能进行扩容操作:

csharp 复制代码
# 查看 StorageClass 配置
kubectl get sc qingcloud-sc -o yaml

关键配置字段:

yaml 复制代码
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: qingcloud-sc
# 必须为 true 才能允许扩容
allowVolumeExpansion: true
provisioner: csi-qingcloud

注意 :如果 allowVolumeExpansionfalse或未设置,PVC 将无法扩容。

2.2 创建时配置允许扩容

如果是创建新的 StorageClass,确保包含此参数:

yaml 复制代码
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: expandable-sc
provisioner: csi-driver.example.com
allowVolumeExpansion: true
parameters:
  type: fast

三、Offline 扩容实战步骤

3.1 准备工作负载停用

对于使用 Deployment 或 StatefulSet 的工作负载,需要先缩减副本数为 0:

ini 复制代码
# 对于 Deployment
kubectl -n <namespace> scale deployment <deployment-name> --replicas=0

# 对于 StatefulSet
kubectl -n <namespace> scale statefulset <statefulset-name> --replicas=0

重要提示

  • 确保业务可以容忍短暂停服
  • 在生产环境中,建议在业务低峰期操作
  • 对于有状态应用,确保数据已持久化

3.2 修改 PVC 容量

通过编辑 PVC 配置文件来调整存储容量:

csharp 复制代码
# 编辑 PVC
kubectl edit pvc <pvc-name> -n <namespace>

修改 spec.resources.requests.storage字段:

yaml 复制代码
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: data-pvc
  namespace: app-ns
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      # 从 10Gi 扩容到 100Gi
      storage: 100Gi
  storageClassName: qingcloud-sc
  volumeMode: Filesystem

注意事项

  • 只能扩容,不能缩容
  • 确保新容量在存储后端的配额限制内
  • 修改后保存退出即可

3.3 监控物理扩容进度

PVC 的物理容量扩容是一个异步过程,可以通过以下命令监控:

arduino 复制代码
# 实时监控 PVC 状态
kubectl get pvc <pvc-name> -n <namespace> -w

# 或查看详细状态
kubectl get pvc <pvc-name> -n <namespace> -o yaml

扩容过程中的 PVC 状态:

yaml 复制代码
status:
  accessModes:
  - ReadWriteOnce
  capacity:
    storage: 10Gi   # 初始容量
  conditions:
  - lastProbeTime: null
    lastTransitionTime: "2023-10-05T09:28:03Z"
    # 关键状态:等待文件系统扩容
    message: Waiting for user to (re-)start a pod to finish file system resize of
      volume on node.
    status: "True"
    type: FileSystemResizePending
  phase: Bound

状态解读

  • FileSystemResizePending:物理扩容已完成,等待文件系统扩容
  • 此时 PVC 显示的容量仍为旧值,这是正常现象

3.4 恢复工作负载

当 PVC 状态出现 FileSystemResizePending时,可以恢复工作负载:

ini 复制代码
# 恢复 Deployment
kubectl -n <namespace> scale deployment <deployment-name> --replicas=3

# 恢复 StatefulSet
kubectl -n <namespace> scale statefulset <statefulset-name> --replicas=3

Pod 启动时,Kubernetes 会自动完成文件系统的扩容。

3.5 确认扩容完成

验证扩容是否完全成功:

csharp 复制代码
# 检查 PVC 最终状态
kubectl get pvc <pvc-name> -n <namespace> -o yaml

成功状态示例:

yaml 复制代码
spec:
  resources:
    requests:
      storage: 100Gi  # 请求的容量
  storageClassName: qingcloud-sc
status:
  capacity:
    storage: 100Gi    # 实际容量,应该与请求的一致
  phase: Bound

查看扩容事件日志:

xml 复制代码
kubectl describe pvc <pvc-name> -n <namespace>

成功事件示例:

vbnet 复制代码
Events:
  Type     Reason                      Age                From                            Message
  ----     ------                      ----               ----                            -------
  Normal   ExternalExpanding           29m                volume_expand                   Ignoring the PVC: didn't find a plugin capable of expanding the volume; waiting for an external controller to process this PVC.
  Warning  VolumeResizeFailed          28m (x12 over 28m) external-resizer csi-qingcloud  resize volume pvc-e78f36e1-bb9c-40a6-903e-ba32014afb15 failed: rpc error: code = FailedPrecondition desc = volume vol-ey3xpxcj currently published on a node but plugin only support OFFLINE expansion
  Normal   Resizing                    28m (x13 over 28m) external-resizer csi-qingcloud  External resizer is resizing volume pvc-e78f36e1-bb9c-40a6-903e-ba32014afb15
  Normal   FileSystemResizeSuccessful  26m                kubelet                         MountVolume.NodeExpandVolume succeeded for volume "pvc-e78f36e1-bb9c-40a6-903e-ba32014afb15"

关键成功标志

  1. FileSystemResizeSuccessful事件
  2. spec.resources.requests.storage等于 status.capacity.storage
  3. PVC 状态为 Bound且无错误条件

四、扩容失败处理

4.1 常见错误及解决

错误1:PVC 处于挂起状态

ini 复制代码
Warning  VolumeResizeFailed  external-resizer csi-qingcloud  
resize volume failed: rpc error: code = FailedPrecondition 
desc = volume currently published on a node but plugin only support OFFLINE expansion

解决方法

  • 确认所有使用该 PVC 的 Pod 已停止
  • 检查是否有节点异常导致 PVC 仍被挂载

错误2:存储配额不足

ini 复制代码
Warning  VolumeResizeFailed  external-resizer csi-qingcloud  
resize volume failed: rpc error: code = ResourceExhausted 
desc = quota exceeded

解决方法

  • 联系云平台管理员增加存储配额
  • 或选择较小的扩容容量

4.2 恢复 PVC 到之前状态

如果扩容失败,可以尝试将 PVC 恢复到之前的状态:

perl 复制代码
# 1. 回滚 PVC 配置
kubectl edit pvc <pvc-name> -n <namespace>
# 将 storage 改回原来的大小

# 2. 如果 PVC 处于异常状态,删除并重建
# 注意:确保有数据备份!
kubectl delete pvc <pvc-name> -n <namespace>
# 使用备份数据恢复

五、最佳实践与建议

5.1 事前准备

  1. 备份数据:在扩容前,确保有完整的数据备份
  2. 通知相关人员:提前通知业务方和维护窗口
  3. 测试环境验证:先在测试环境演练完整流程

5.2 监控与告警

yaml 复制代码
# 设置 PVC 使用率监控
# PVC 使用率超过 80% 时发出告警
- alert: PVCUsageHigh
  expr: (kubelet_volume_stats_used_bytes / kubelet_volume_stats_capacity_bytes) * 100 > 80
  for: 5m
  labels:
    severity: warning
  annotations:
    summary: "PVC {{ $labels.persistentvolumeclaim }} usage high"

5.3 自动化扩容方案

对于需要频繁扩容的场景,可以考虑:

  1. 使用动态扩容工具:如 kubernetes-autoscaler
  2. 编写自动化脚本:将扩容流程脚本化
  3. 集成到 CI/CD:在发布流程中自动检查存储容量

六、不同存储方案对比

存储方案 扩容模式 是否需要停服 文件系统支持
QingCloud CSI Offline ext4, xfs
AWS EBS CSI Online 大部分文件系统
Azure Disk CSI Online 大部分文件系统
Ceph RBD Online 大部分文件系统

总结

PVC 扩容是 Kubernetes 运维中的常见操作,理解其工作原理和注意事项至关重要。通过本文的步骤指南,你可以:

  1. 安全地完成 offline 扩容操作
  2. 理解扩容过程中的各个状态
  3. 能够诊断和解决扩容中的问题
  4. 建立完善的存储容量管理策略

记住,任何生产环境操作前都要先备份数据,并在非业务高峰期进行。随着 Kubernetes 和 CSI 驱动的发展,未来会有更多存储方案支持 online 扩容,进一步降低业务影响。


实战小贴士:对于关键业务,建议实现存储容量的自动化监控和预警,提前规划扩容,避免存储空间用尽导致的业务中断。

相关推荐
AllFiles15 小时前
Linux 网络故障排查:如何诊断与解决 ARP 缓存溢出问题
linux·后端
盒子691015 小时前
【golang】替换 ioutil.ReadAll 为 io.ReadAll 性能会下降吗
开发语言·后端·golang
Aeside115 小时前
揭秘 Nginx 百万并发基石:Reactor 架构与 Epoll 底层原理
后端·设计模式
追梦者12315 小时前
springboot整合minio
java·spring boot·后端
程序员Agions16 小时前
程序员邪修手册:那些不能写进文档的骚操作
前端·后端·代码规范
肌肉娃子16 小时前
20260109.反思一个历史的编程的结构问题-更新频率不一致的数据不要放在同一个表
后端
凌览16 小时前
2026年1月编程语言排行榜|C#拿下年度语言,Python稳居第一
前端·后端·程序员
码事漫谈16 小时前
【深度解析】为什么C++有了malloc,还需要new?
后端
晴虹16 小时前
lecen:一个更好的开源可视化系统搭建项目--组件和功能按钮的权限控制--全低代码|所见即所得|利用可视化设计器构建你的应用系统-做一
前端·后端·低代码