在Kubernetes集群中管理存储资源时,PersistentVolume(PV)和PersistentVolumeClaim(PVC)是两个核心抽象层。它们解耦了存储供应方和使用方的关系,让管理员和开发者能够各司其职。
PV相当于集群中的一块"物理存储",由管理员预先配置好。它可以是:
而PVC则是用户对存储资源的"申请单",开发者不需要关心底层具体用什么存储技术,只需要声明需要的存储大小和访问模式。当PVC提交后,Kubernetes会尝试将其与合适的PV绑定。
重要提示:PV的生命周期独立于Pod,即使Pod被删除,PV中的数据仍然会保留,除非显式地回收PV资源。
下面是一个NFS类型PV的完整定义示例:
yaml复制apiVersion: v1
kind: PersistentVolume
metadata:
name: nfs-pv
spec:
capacity:
storage: 10Gi
volumeMode: Filesystem
accessModes:
- ReadWriteMany
persistentVolumeReclaimPolicy: Retain
storageClassName: slow
mountOptions:
- hard
- nfsvers=4.1
nfs:
path: /data/nfs/share
server: 192.168.1.100
关键参数解析:
| 类型 | 典型场景 | 访问模式 | 性能 | 适用环境 |
|---|---|---|---|---|
| hostPath | 开发测试 | RWO | 高 | 单节点 |
| NFS | 共享存储 | RWX | 中 | 自有环境 |
| iSCSI | 块存储 | RWO | 高 | 企业存储 |
| AWS EBS | 云块存储 | RWO | 高 | AWS环境 |
| Azure Disk | 云块存储 | RWO | 高 | Azure环境 |
| CephFS | 分布式文件系统 | RWX | 中高 | 大规模集群 |
yaml复制apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: app-data-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
storageClassName: slow
selector:
matchLabels:
type: nfs
PVC会通过以下条件匹配PV:
当PVC提交后,Kubernetes会执行以下匹配流程:
如果找不到匹配的PV,PVC会保持Pending状态,直到有符合条件的PV出现。
对于生产环境,建议使用StorageClass实现动态PV供应:
yaml复制apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: fast-ssd
provisioner: kubernetes.io/aws-ebs
parameters:
type: gp3
fsType: ext4
iops: "3000"
throughput: "125"
优势:
定期快照:利用CSI snapshot功能定期备份
bash复制kubectl create volumesnapshot mysql-snapshot \
--source=persistentvolumeclaim/mysql-pvc \
--volume-snapshot-class=csi-aws-vsc
跨可用区复制:在云环境中配置跨AZ存储
应用级备份:结合数据库dump等应用层备份方案
IOPS调整:云平台块存储可配置IOPS参数
yaml复制parameters:
iops: "10000"
throughput: "500"
文件系统选择:xfs通常比ext4性能更好
读写分离:将日志等高频写入数据与主数据分离
可能原因及解决方案:
没有可用PV:
容量不足:
accessModes不匹配:
典型错误现象:
code复制Warning FailedMount 3s (x5 over 15s) kubelet MountVolume.SetUp failed for volume "nfs-pv" : mount failed: exit status 32
排查步骤:
可能原因:
解决方案:
通过定义PVC时指定dataSource实现:
yaml复制apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: clone-pvc
namespace: new-ns
spec:
dataSource:
name: original-pvc
kind: PersistentVolumeClaim
apiGroup: ""
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
对于性能敏感型应用,可使用本地PV配合节点亲和性:
yaml复制apiVersion: v1
kind: PersistentVolume
metadata:
name: local-pv
spec:
capacity:
storage: 100Gi
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
storageClassName: local-storage
local:
path: /mnt/ssd
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- node-1
以AWS EBS CSI驱动为例的完整部署流程:
安装CSI驱动
bash复制kubectl apply -k "github.com/kubernetes-sigs/aws-ebs-csi-driver/deploy/kubernetes/overlays/stable/?ref=master"
创建StorageClass
yaml复制apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: ebs-sc
provisioner: ebs.csi.aws.com
volumeBindingMode: WaitForFirstConsumer
parameters:
type: gp3
encrypted: "true"
创建PVC(自动触发PV创建)
yaml复制apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: ebs-claim
spec:
accessModes:
- ReadWriteOnce
storageClassName: ebs-sc
resources:
requests:
storage: 100Gi
在实际生产环境中,我们团队发现为不同业务场景设计专门的StorageClass能显著提高管理效率。例如,为日志类应用创建高吞吐量的sc-logging,为数据库创建低延迟的sc-db,这样开发团队可以根据应用特性选择合适的存储类型,而不需要了解底层实现细节。