PV和PVC
在 Kubernetes 中,有状态应用(stateful application)非常普遍和重要,而PV和PVC是实现有状态应用的核心基础。
volume和volumeMount
容器中的文件在磁盘上是临时存放的,也有很多场景下应用程序都需要对某些数据进行持久存储,避免在容器奔溃时造成数据丢失。
Volume 是 Kubernetes 中定义的存储资源,作用是将外部存储或节点上的存储空间与 Pod 关联,用于在容器之间共享数据或提供持久化存储。
Volume的类型有很多种,例如还有跟云厂商关联的awsElasticBlockStore、azureDisk、azureFile等,具体可以参考官方文档。
主要的常用volume类型包括:
kubernetes的一个重要的基本理念是:向app developers隐藏真实的基础设施,使他们不需要关心基础设施的具体状况信息,并使应用程序可以在不同的云服务商之前进行迁移、切换。因此,kubernetes提出了PV和PVC的概念,使开发人员可以在创建pod需要使用持久化存储时,就像请求 CPU \ Mem 等资源一样来向kubernetes集群请求持久存储。
PV和PVC
基本概念
前面提到的emptyDir和hostPath都不是持久化存储,会随着Pod/Node的销毁和重建而丢失。而PV和PVC都是kubernetes中定义的API资源,提供一种能持久化存储的能力。
PV是集群中的一块存储,可以由集群的administrators事先手动创建外部存储后关联PV,就是所谓的静态供应(static provisioning)。
这个方法很大的一个问题在于,当kubernetes集群规模很大时,需要管理员手工去创建成千上万的PV来对应存储资源,这是很繁琐的。
因此,kubernetes中PV的创建一般会使用动态供应(dynamic provisioning)。
PV属于集群资源,它们的生命周期跟使用它们的pod时相互独立。
PVC表达的是用户对存储的请求,也是kubernetes中独立存在的API资源。Pod 会耗用节点资源,而 PVC 申领会耗用 PV 资源。Pod 可以请求特定数量的资源(CPU 和内存);同样PVC也可以请求特定的大小和访问模式。
当用户创建一个PVC,kubernetes中的volume controller会监测到PVC的对象,寻到集群中与之匹配的PV资源,将二者进行绑定。如果没有匹配的PV资源,PVC则会处理未绑定的状态一直持续等待,直到集群中出现满足条件的PV资源后进行绑定。PVC和PV之间的绑定是一种一对一的映射。
而另一个很重要的概念,也是kubernetes的API资源,就是storageClass。storageClass可以说是PV的创建模板。
这样,kubernetes就可以根据PVC指定的storageClass,调用指定的存储插件,创建所需的PV。
Pod、PVC、PV、StorageClass的关系图可以解释如下:
Pod中使用持久存储
例如,在AWS上的kubernetes集群,使用PVC声明需要EBS并挂载到Pod中:
- 需要在集群中预先部署aws-ebs-csi-driver (EKS的话,有提供AWS managed Add-on直接支持)
- 创建对应的storageClass, 确保Provisioner backend pods也正常运行
- 创建PVC, 在workload中使用PVC作为volume, 并使用volumeMount在pod中声明
- aws-ebs-csi-driver创建对应的外部存储EBS和PV,挂载到workload的pod中
PVC / PV / SC 等资源
在集群中需要有对应的storageClass
1
2
3
4
5
6
7
8
9
10apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: ebs-sc
provisioner: ebs.csi.aws.com # Specify related provisioner
parameters:
type: gp3 # The type of EBS volume (gp3 for general-purpose SSD)
fsType: ext4 # File system type
reclaimPolicy: Delete # Automatically delete EBS volume when PVC is deleted
volumeBindingMode: WaitForFirstConsumer # Volume is provisioned only when a pod uses the PVC创建PVC
1
2
3
4
5
6
7
8
9
10
11apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: my-ebs-pvc
spec:
accessModes:
- ReadWriteOnce # EBS volumes can only be attached to one node at a time
resources:
requests:
storage: 5Gi # Request 5Gi of storage
storageClassName: ebs-sc # Use the ebs-sc StorageClass
集群中的Volume Controller发现这个PVC后,就会主动在集群中寻找合适的PV,来和PVC绑定。只有和PV绑定了的PVC,才能被pod正常挂载使用。
Volume Controller寻找PV的条件主要是:
- PVC和PV的spec字段中指定的规格,例如存储(storage)的大小;
- PVC和PV的storageClassName必须一样。
如果集群中不存在合适的PV,Provisioner就会尝试根据配置动态创建外部存储,和在集群上创建对应的PV。
- 创建使用PVC的workload
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24apiVersion: apps/v1
kind: Deployment
metadata:
name: ebs-pvc-app
spec:
replicas: 1
selector:
matchLabels:
app: ebs-pvc-app
template:
metadata:
labels:
app: ebs-pvc-app
spec:
containers:
- name: app
image: nginx
volumeMounts:
- mountPath: /usr/share/nginx/html # Mount PVC at this path
name: storage
volumes:
- name: storage
persistentVolumeClaim:
claimName: my-ebs-pvc # Use the PVC created earlier
对于EBS这样的块存储,分为“两阶段处理”。
(1)Attach:为宿主机挂载远程存储;(如果是NFS的话,其实没有这个过程,因为不需要“挂载存储设备到宿主机”)
(2)Mount:将远程存储格式化挂载到宿主机的指定目录,对应容器中的Volume。
参考资料
- 标题: PV和PVC
- 作者: xawei
- 创建于 : 2021-01-10 11:10:00
- 更新于 : 2025-01-21 04:57:44
- 链接: https://xawei.xyz/2021/01/10/pv-pvc-basic-use/
- 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。