Kubernetes存储体系通过PV(Persistent Volume)和PVC(Persistent Volume Claim)实现存储资源的抽象与分配。静态供给需要管理员预先创建PV,无法满足大规模动态扩容需求。StorageClass结合CSI(Container Storage Interface)驱动实现动态供给,Pod创建PVC时自动分配底层存储卷,是Kubernetes容器编排中的标准存储方案。
PV/PVC/StorageClass三层架构解析
PV是集群级别的存储资源,由管理员创建或通过StorageClass动态供给。PVC是用户对存储的申请,声明所需容量和访问模式。StorageClass是动态供给的模板,定义Provisioner(存储驱动)和参数。
# StorageClass定义(以NFS CSI为例)
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: nfs-storage
provisioner: nfs.csi.k8s.io
parameters:
server: 192.168.1.100
share: /data/nfs
mountPermissions: "0755"
reclaimPolicy: Delete # PVC删除后PV处理方式:Delete/Retain
allowVolumeExpansion: true # 是否允许在线扩容
volumeBindingMode: WaitForFirstConsumer # 延迟绑定直到Pod调度
mountOptions:
- hard
- nfsvers=4.1
- timeo=600
# PVC声明
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: app-data-pvc
namespace: production
spec:
accessModes:
- ReadWriteMany # RWO单节点读写,RWX多节点读写,ROX多节点只读
storageClassName: nfs-storage
resources:
requests:
storage: 50Gi
# Pod挂载PVC
apiVersion: v1
kind: Pod
metadata:
name: web-app
spec:
containers:
- name: nginx
image: nginx:1.25
volumeMounts:
- name: data
mountPath: /usr/share/nginx/html
volumes:
- name: data
persistentVolumeClaim:
claimName: app-data-pvc
常见CSI驱动与StorageClass配置
Ceph RBD块存储
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: ceph-rbd
provisioner: rbd.csi.ceph.com
parameters:
clusterID: <ceph-cluster-id>
pool: kube-rbd-pool
imageFormat: "2"
imageFeatures: layering
csi.storage.k8s.io/provisioner-secret-name: ceph-secret
csi.storage.k8s.io/provisioner-secret-namespace: kube-system
csi.storage.k8s.io/controller-expand-secret-name: ceph-secret
csi.storage.k8s.io/controller-expand-secret-namespace: kube-system
csi.storage.k8s.io/node-stage-secret-name: ceph-secret
csi.storage.k8s.io/node-stage-secret-namespace: kube-system
csi.storage.k8s.io/fstype: ext4
reclaimPolicy: Retain
allowVolumeExpansion: true
volumeBindingMode: WaitForFirstConsumer
本地存储Local Volume
# Local Persistent Volume适合对延迟敏感的数据库场景
# 需要预先在节点上创建目录
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: local-storage
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: local-pv-node01
spec:
capacity:
storage: 100Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
storageClassName: local-storage
local:
path: /mnt/disks/ssd1
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- node01
存储卷扩容与快照管理
# 在线扩容PVC
# 前提:StorageClass的allowVolumeExpansion必须为true
kubectl patch pvc app-data-pvc -n production \
--patch '{"spec":{"resources":{"requests":{"storage":"100Gi"}}}}'
# 查看扩容状态
kubectl get pvc app-data-pvc -n production -o wide
# 状态会从resizing变为可用
# Volume Snapshot配置
# 1. 创建VolumeSnapshotClass
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshotClass
metadata:
name: ceph-snapshot
driver: rbd.csi.ceph.com
deletionPolicy: Delete
parameters:
clusterID: <ceph-cluster-id>
csi.storage.k8s.io/snapshotter-secret-name: ceph-secret
csi.storage.k8s.io/snapshotter-secret-namespace: kube-system
# 2. 创建快照
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshot
metadata:
name: app-data-snapshot
spec:
volumeSnapshotClassName: ceph-snapshot
source:
persistentVolumeClaimName: app-data-pvc
# 3. 从快照恢复
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: app-data-restored
spec:
accessModes:
- ReadWriteOnce
storageClassName: ceph-rbd
resources:
requests:
storage: 50Gi
dataSource:
name: app-data-snapshot
kind: VolumeSnapshot
apiGroup: snapshot.storage.k8s.io
StatefulSet与存储卷的最佳实践
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mysql-cluster
spec:
serviceName: mysql-headless
replicas: 3
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql:8.0
ports:
- containerPort: 3306
volumeMounts:
- name: data
mountPath: /var/lib/mysql
- name: config
mountPath: /etc/mysql/conf.d
volumes:
- name: config
configMap:
name: mysql-config
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: ["ReadWriteOnce"]
storageClassName: ceph-rbd
resources:
requests:
storage: 200Gi
StatefulSet通过volumeClaimTemplates为每个Pod自动创建独立PVC。Pod mysql-cluster-0对应PVC data-mysql-cluster-0,命名规则固定,确保数据与Pod绑定。
存储故障排查与性能监控
# 查看PV和PVC状态
kubectl get pv
kubectl get pvc -A
kubectl describe pvc <pvc-name> -n <namespace>
# 查看CSI驱动日志
kubectl logs -n kube-system <csi-controller-pod>
kubectl logs -n kube-system <csi-node-pod>
# 检查节点存储挂载
# 登录到运行Pod的节点
lsblk
df -h
mount | grep /var/lib/kubelet
# 查看CSI驱动注册状态
kubectl get csidriver
kubectl get csinode
# 存储性能基准测试(在Pod内执行)
apiVersion: v1
kind: Pod
metadata:
name: fio-benchmark
spec:
containers:
- name: fio
image: danielguerra/fio
command: ["fio"]
args:
- "--name=seq-write"
- "--filename=/data/testfile"
- "--rw=write"
- "--bs=4k"
- "--size=1G"
- "--numjobs=1"
- "--time_based"
- "--runtime=60"
volumeMounts:
- name: data
mountPath: /data
volumes:
- name: data
persistentVolumeClaim:
claimName: benchmark-pvc
存储性能核心指标:IOPS(每秒IO次数)、吞吐量(MB/s)、延迟(ms)。SSD后端存储随机读写IOPS通常在5000-50000,NVMe可达10万以上。NFS等网络存储延迟受网络带宽和RTT影响,生产环境数据库不建议使用NFS作为主存储。
多存储后端选型对比
Ceph RBD:块存储,适合数据库等需要低延迟和高IOPS的场景。支持快照、克隆、在线扩容。运维复杂度高,需要独立的Ceph集群。
CephFS:文件存储,支持ReadWriteMany多节点同时读写。适合共享文件、CI/CD构建产物等场景。性能低于RBD。
NFS:网络文件系统,部署简单。适合开发测试环境或静态资源存储。单点故障风险高,网络延迟影响性能。
Local PV:节点本地存储,延迟最低。适合有状态服务如数据库。数据与节点绑定,节点故障会导致数据不可用,需配合高可用方案。
云盘CSI:公有云块存储(如阿里云云盘、AWS EBS),与云平台深度集成。按需付费,弹性扩容方便。跨可用区复制依赖云平台能力。
选型原则:数据库类有状态服务优先选择RBD或云盘CSI,Web应用静态资源选择NFS或CephFS,高性能计算选择Local PV配合数据复制方案。
原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/kubernetes-cun-chu-juan-shi-zhan-pvpvc-dong-tai-gong-ji-yu/