k8s 持久化存储 PV 和 PVC 的简单使用
概述
Kubernetes 对于有状态的容器应用或者对数据需要持久化的应用,可以通过 hostPath 或者 emptyDir 的方式来持久化我们的数据,但是我们需要更加可靠的存储来保存应用的持久化数据。不过存储资源和 CPU 资源以及内存资源有很大不同,为了屏蔽底层的技术实现细节,让用户更加方便的使用,Kubernetes 便引入了 PV 和 PVC 两个重要的资源对象来实现对存储的管理。
概念
PV (PersistentVolume) 是对底层网络共享存储的抽象,将共享存储定义为一种 “资源”。PV 一般由K8S的管理员所创建和配置,它和具体的底层的共享存储技术的实现方式有关,比如 Ceph、GlusterFS、NFS 等,都是通过插件机制完成与共享存储的对接。
PVC (PersistentVolumeClaim) 是用户对存储资源的一个 “申请”。就像 Pod消费 Node 资源一样,PVC 能够消费 PV 的资源。Pod 可以请求节点的CPU和内存,而 PVC 可以请求特定的存储空间和访问模式。对于用户来说,不需要关心底层的存储实现细节,只需要直接使用 PVC 即可。
实战:基于NFS共享存储创建PV和PVC
示例:基于NFS存储来创建PV和PVC
本次共享存储资源选择本地自建的NFS,关于搭建NFS的教程参考之前写的博文:centos7搭建NFS服务
试验环境如下,注意所有k8s节点都要安装nfs,yum install -y nfs-tools:
| 主机名hostname | IP地址 | 说明 |
|---|---|---|
| master | 192.168.18.10 | k8s主节点 |
| node1 | 192.168.18.11 | k8s的node1节点 |
| node2 | 192.168.18.12 | k8snode2节点 |
| db | 192.168.18.7 | NFS服务器,共享目录/data/nfs/test-pv |
PV
PV 作为存储资源,主要包括存储能力、访问模式、存储类型、回收策略、后端存储类型等关键信息的设置。PV 是没有名称空间的隔离性的。下面来创建一个PV 资源对象:
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv001
spec:
capacity:
storage: 5Gi
accessModes:
- ReadWriteMany
persistentVolumeReclaimPolicy: Recycle
storageClassName: nfs-slow
nfs:
path: /data/nfs/test-pv
server: 192.168.18.7
上面yaml文件表明:创建了一个名字是pv001的PV,使用NFS类型的后端存储,声明5G的存储空间,访问模式是 ReadWriteMany ,回收策略为 Recyle。有了yaml文件后,直接创建即可。
# 创建pv
[root@master k8s-yaml]# kubectl create -f pv.yaml
# 查看pv
[root@master k8s-yaml]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pv001 5Gi RWX Recycle Available nfs-slow 5s
PV的常用配置参数
1. 存储能力(Capacity)
一个 PV 对象一般都要指定一个存储能力,通过 PV 的 capacity 属性来设置的,比如这里的 storage: 5Gi,目前只支持对存储空间的设置,未来可能加入IOIPS、吞吐量等指标的设置。
2. 访问模式(Access Modes)
对 PV 进行访问模式的设置,用于描述用户的应用对存储资源的访问权限。分为三种:
ReadWriteOnce:读写权限,并且只能被单个 Node 挂载;ReadOnlyMany:只读权限,允许被多个 Node 挂载;ReadWriteMany:读写权限,允许被多个 Node 挂载
一些 PV 可能支持多种访问模式,但是在挂载的时候只能使用一种访问模式,多种访问模式是不会生效的。
3. 存储类别(Class)
PV 可以设定其存储的类别,通过 storageClassName 参数指定一个 StorageClass 资源对象的名称。具有特定类别的 PV 只能与请求了该类别的 PVC 进行绑定。未设定类别的 PV 则只能与不请求任何类别的 PVC 进行绑定。
4. 回收策略
回收策略是通过 persistentVolumeReclaimPolicy 参数进行设置,可选性如下:
Retain:保留,需要手动清理数据Recycle:回收,清楚PV中的数据,相当于rm -rf /thevolume/*命令Delete:删除,与 PV 相连的后端存储完成volume的删除操作,删除 PVC 后,PV也会被删掉。这一类的PV,需要支持删除功能,是动态存储的默认方式。
PV 的生命周期
一个 PV 在生命周期可能处于下面四个阶段之一:
Available:可用状态,还没有于某个PVC进行绑定Bound:已跟某个PVC绑定Released:绑定的PVC已经删除,资源已经释放,但是没有被集群回收Failed:自动资源回收失败
上面创建了PV之后,由于还没有任何PVC跟PV绑定,所以PV的状态还是 Available。
PVC
PVC 作为用户对存储资源的需求申请,主要包括存储空间请求、访问模式、PV选择条件和存储类别的信息的设置。如下,新建一个PVC,跟上面创建的PV进行绑定。
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: myclaim
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 3Gi
storageClassName: nfs-slow
该PVC申请了与存储类别名称为 nfs-slow 的 PV 进行绑定,请求3G的存储容量,访问模式是 ReadWriteMany,创建该PVC:
[root@master k8s-yaml]# kubectl create -f pvc.yaml
# 查看default名称空间下的PVC
[root@master k8s-yaml]# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
myclaim Bound pv001 5Gi RWX nfs-slow 6s
# 注意,PVC有名称空间的隔离性
[root@master k8s-yaml]# kubectl get pvc -n kube-system
No resources found in kube-system namespace.
# 查看PV状态
[root@master k8s-yaml]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pv001 5Gi RWX Recycle Bound default/myclaim nfs-slow 3h29m
可以看到,在PVC与PV进行绑定之后,PV的状态变成了 Bound。但是从上面也看出,我的 PVC 里面声明的容量是3G,而PV里面声明的容量是5G,结果创建出来的PVC容量却是5G,说明,PV的容量是多少,PVC的容量就是多少。
如果PVC里面设置的容量超过PV里面定义的容量,那么PVC是创建不成功的,会一直处于Pending状态。
使用PVC
上面创建了PV和PVC,接下来就可以使用它们了,使用下面nginx-pvc.yaml 进行测试:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-pvc
spec:
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.18.0
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
volumeMounts:
- mountPath: /usr/share/nginx/html
name: my-pvc-volume
volumes:
- name: my-pvc-volume
persistentVolumeClaim:
claimName: myclaim
然后在nfs的共享目录里面创建个html文件:
[root@db ]# cd /data/nfs/test-pv/
[root@db test-pv]# echo "hello k8s pvc" > index.html
创建Deployment
[root@master k8s-yaml]# kubectl create -f nginx-pvc.yaml
查看Pod:
[root@master k8s-yaml]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-pvc-78c9859d7-94lxn 1/1 Running 0 38s 10.244.166.165 node1 <none> <none>
访问Pod:
[root@master k8s-yaml]# curl 10.244.166.165
hello k8s pvc
可以看到,Pod内部的容器已经成功挂载nfs的后端存储。
参考资料
-
《Kubernetes 权威指南:从 Docker 到 Kubernetes 实践全接触 (第四版) 》

浙公网安备 33010602011771号