Kubernetes PV与PVC
2020-03-25 by dongnan
开始之前
在前面的三篇文章中,至此我们已经准备好了K8S集群环境。
接下来我们将以在K8S集群运行一个真实的项目为目标,依次介绍项目所使用的K8S资源对象。
这个项目是一个典型的Web系统,使用 Java Spring Boot框架开发,需要使用 MySql、Redis数据库、NFS共享存储(多个Pod容器间共享文件)。
由于K8S环境部署在阿里云上,所以这里使用了阿里云提供的 RDS-Mysql 、RDS-Redis 数据库服务、NAS(NFS)
网络附加存储等中间件产品,对于K8S集群来说,我们需要将这些服务映射为K8S的资源对象。
项目使用的K8S的资源对象包括:
- PV&PVC,用于Pod数据卷(NFS)。
- Pod (volumeMounts、readinessProbe),挂载数据卷、健康检查。
- Secret,存储机密数据。
- Service,服务-外部域名(ExternalName)。
- NetworkPolicy,网络策略。
- LimitRange,限制资源。
- Ingress
环境
测试的k8s集群由一个Master管理节点、两个Worker计算节点组成,详细请参考这里。
借用一张图说明 Pod(容器组)、挂载点、数据卷、存储卷(PV)、和存储卷声明(PVC)它们之间的关系:

目标
本文介绍如何使用 Kubernetes 提供的 PV与PVC "挂载" NFS网络存储。
举个栗子
yaml文档
# PV
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: yii-server-pv
labels:
pv: yii-server-pv
spec:
capacity:
storage: 30Gi
accessModes:
- ReadWriteMany
mountOptions:
- vers=4
- minorversion=0
- noresvport
nfs:
server: 90xxxxx8a5-vxxx2.cn-zhxxxxxxu.nas.aliyuncs.com
path: /yii
# PVC
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
namespace: yii-prod
name: yii-server-pvc
spec:
accessModes:
- ReadWriteMany
storageClassName: ""
resources:
requests:
storage: 30Gi
selector:
matchLabels:
pv: yii-server-pv
创建PV与PVC
kubectl apply -f yii-pv-pvc.yaml
验证PV与PVC
PV不属于任何命名空间
kubectl get pv yii-server-pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
yii-server-pv 30Gi RWX Retain Bound yii-prod/yii-server-pvc 152d
注意,存储卷 yii-server-pv 已经被 yii-prod 命名空间的 yii-server-pvc 存储声明绑定了。
PVC则属于某个命名空间
kubectl -n yii-prod get pvc yii-server-pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
yii-server-pvc Bound yii-server-pv 30Gi RWX 152d
其实这个PVC也被某个Pod容器挂载使用了,下一篇文章介绍如在Pod中使用PVC存储资源 。
kubectl -n yii-prod describe pvc yii-server-pvc
Name: yii-server-pvc
Namespace: yii-prod
StorageClass:
Status: Bound
Volume: yii-server-pv
Labels: <none>
Annotations: kubectl.kubernetes.io/last-applied-configuration:
#...省略
Finalizers: [kubernetes.io/pvc-protection]
Capacity: 30Gi
Access Modes: RWX
VolumeMode: Filesystem
Mounted By: yii-server-78dxxx94d-gxxxr # 注意这里
Events: <none>
PV
PV 存储卷(PersistentVolume) 是抽象出来的存储资源,由管理员创建和配置或者由 StorageClass 自动创建并管理。
配置参数包括: 存储能力、存储类型、访问模式、回收策略、后端存储类型等。
选项参数
metadata.labels: 存储卷的标签,将被PVC绑定的依据。
- 这里
pv作为键,yunyi-server-pv作为值。
spec.capacity.storage: 存储大小。
spec.accessModes: 访问模式:
ReadWriteMany: 允许多个节点挂载进行读写。ReadWriteOnce: 仅允许单个节点挂载进行读写。ReadOnlyMany: 允许多个节点挂载且只读。
spec.persistentVolumeReclaimPolicy: 回收策略:
Retain: 保留,删除PVC后PV保留数据。Recycle: 回收空间,删除PVC后简单的清除文件。Delete: 删除,删除PVC后与PV相连接的后端存储会删除数据。
spec.storageClassName: 存储类别,指定一个StorageClass资源对象的名称,具有特定类别的PV只能与请求了该类别的PVC进行绑定。
- 这里使用的是静态方式绑定
PVC与PV,所以这里没有设置存储类SC。
spec.mountOptions: 挂载参数,当PV挂载到一个节点时,可能需要设置额外的挂载参数,就是通过 mountOptions 字段设置。
- 这里使用的是
NFS存储类型,所以这里设置NFS相关的参数。
spec.volumeMode: 存储卷模式,值有 Filesystem 文件系统(默认值),Block 块设备。
- 这里没有指定参数,所以使用的默认值
Filesystem。
生命周期
PV有4个生命周期阶段
Available: 可用状态,无PVC绑定。Bound: 绑定状态,已经和某个PVC绑定。Released: 释放状态,绑定的PVC已删除,资源释放但没有被集群回收。Failed: 失败状态,自动资源回收失败。
PVC
PVC 存储卷声明(PersistentVolumeClaim),PVC作为用户对存储资源的需求申请用于消费PV资源,主要包括了存储空间大小、访问模式、PV的选择条件、存储类别等信息的设置。
选项参数
- metadata.namespace: 与
PV不同,PVC属于某个命名空间。 - metadata.name: 存储卷声明的名称,将被
Pod挂载并使用。 - spec.resources.requests.storage: 申请的存储空间大小。
- spec.accessModes: 访问模式,与PV的三种模式相同。
- spec.storageClassName: 存储类别,指定一个
StorageClass资源对象的名称,""存储类设置为空,表示该PVC不需要特定的SC存储类,K8S将选择没有设置SC的PV与之绑定。 - spec.selector.matchLabels:
PV的选择条件,可以通过标签匹配进行PV绑定。
生命周期
PVC也有4个生命周期阶段。
Available: 可用状态,无PV绑定。Bound: 绑定状态,已经和某个PV绑定。Released: 释放状态,绑定的PV已删除,资源释放但没有被集群回收。Failed: 失败状态,自动资源回收失败。
小结
PV是集群中的存储资源,通常由集群管理员创建和管理。StorageClass用于对PV进行分类(可以根据PVC的请求动态创建PV)。PVC是使用该资源的请求,通常由应用程序提出请求,并指定对应的需求的空间大小。PVC可以做为数据卷的一种,被挂载到Pod容器组中使用。