1.pv是什么
PV 全称叫做 Persistent Volume,持久化存储卷。它是用来描述或者说用来定义一个存储卷的,这个通常都是由运维工程师来定义。
2.pvc是什么
PVC 的全称是 Persistent Volume Claim,是持久化存储的请求。它是用来描述希望使用什么样的或者说是满足什么条件的 PV 存储。
2.1 pvc的使用逻辑
在 Pod 中定义一个存储卷(该存储卷类型为 PVC),定义的时候直接指定大小,PVC 必须与对应的 PV 建立关系,PVC 会根据配置的定义去 PV 申请,而 PV 是由存储空间创建出来的。PV 和 PVC 是 Kubernetes 抽象出来的一种存储资源。
上面介绍的PV和PVC模式是需要运维人员先创建好PV,然后开发人员定义好PVC进行一对一的Bond,但是如果PVC请求成千上万,那么就需要创建成千上万的PV,对于运维人员来说维护成本很高,Kubernetes提供一种自动创建PV的机制,叫StorageClass,它的作用就是创建PV的模板。
创建 StorageClass 需要定义 PV 的属性,比如存储类型、大小等;另外创建这种 PV 需要用到的存储插件,比如 Ceph 等。 有了这两部分信息,Kubernetes 就能够根据用户提交的 PVC,找到对应的 StorageClass,然后 Kubernetes 就会调用 StorageClass 声明的存储插件,自动创建需要的 PV 并进行绑定。
PV和PVC之间的相互作用遵循这个生命周期
Provisioning(配置)---> Binding(绑定)---> Using(使用)---> Releasing(释放) ---> Recycling(回收)
Provisioning,即 PV 的创建,可以直接创建 PV(静态方式),也可以使用 StorageClass 动态创建
- Binding,将 PV 分配给 PVC
- Using,Pod 通过 PVC 使用该 Volume,并可以通过准入控制StorageProtection(1.9及以前版本为PVCProtection) 阻止删除正在使用的 PVC
- Releasing,Pod 释放 Volume 并删除 PVC
- Reclaiming,回收 PV,可以保留 PV 以便下次使用,也可以直接从云存储中删除
根据这 5 个阶段,PV 的状态有以下 4 种:
- Available(可用):表示可用状态,还未被任何 PVC 绑定
- Bound(已绑定):表示 PV 已经绑定到 PVC
- Released(已释放):表示 PVC 被删掉,但是资源尚未被集群回收
- Failed(失败):表示该 PV 的自动回收失败
一个PV从创建到销毁的具体流程如下:
- 一个PV创建完后状态会变成Available,等待被PVC绑定。
- 一旦被PVC邦定,PV的状态会变成Bound,就可以被定义了相应PVC的Pod使用。
- Pod使用完后会释放PV,PV的状态变成Released。
- 变成Released的PV会根据定义的回收策略做相应的回收工作。有三种回收策略,Retain、Delete和Recycle。Retain就是保留现场,K8S集群什么也不做,等待用户手动去处理PV里的数据,处理完后,再手动删除PV。Delete策略,K8S会自动删除该PV及里面的数据。Recycle方式,K8S会将PV里的数据删除,然后把PV的状态变成Available,又可以被新的PVC绑定使用。
3.如何创建pv
3.1 创建静态pv
1.先创建我们的nfs,在nfs服务器里中/opt下创建文件夹用来挂载
2.我们到我们的master下创建pv.yaml文件
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv001
spec:
capacity:
storage: 1Gi
#volumeMode: Filesystem
accessModes:
- ReadWriteOnce
- ReadWriteMany
#persistentVolumeReclaimPolicy: Recycle
#storageClassName: slow
nfs:
path: /opt/k8s/v1
server: 192.168.223.105
3.生成pv
4.创建我们的pvc
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mypvc
spec:
accessModes:
- ReadWriteMany
#volumeMode: Filesystem
resources:
requests:
storage: 2Gi
5.现在我们创建一个pod并把我们的pvc进行挂载
apiVersion: v1
kind: Pod
metadata:
name: pod-demo1
namespace: default
spec:
containers:
- name: nginx-1
image: nginx
volumeMounts:
- name: html
mountPath: /usr/share/nginx/html/
volumes:
- name: html
persistentVolumeClaim:
claimName: mypvc
6.之后我们进入到这个容器中测试数据是否共享
kubectl exec -it pod-demo1 bash
3.2 创建动态pv
搭建 StorageClass + nfs-client-provisioner ,实现 NFS 的动态 PV 创建
Kubernetes 本身支持的动态 PV 创建不包括 NFS,所以需要使用外部存储卷插件分配PV。
- 我们先在我们的apiserver下添加配置文件
vim /etc/kubernetes/manifests/kube-apiserver.yaml
spec:
containers:
- command:
- kube-apiserver
- --feature-gates=RemoveSelfLink=false #添加这一行
- --advertise-address=192.168.223.105
2.刷新apiserver服务
3.先将我们的nfs插件包进行上传
cd /opt/k8s
mkdir sc
cd sc
unzip nfs-client.zip
4.用安装包里面的配置文件创建用户,并给予权限
kubectl apply -f nfs-client-rbac.yaml
kubectl get sa
kubectl get secrets
5.我们在nfs服务器创建一个文件用来共享
6.然后我们去master节点上面修改配置文件
vim nfs-client-provisioner.yaml
7.创建pod
8.创建nfs-client-storageclass
9.创建pvc
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mypvc-nfs
spec:
accessModes:
- ReadWriteMany
#volumeMode: Filesystem
resources:
requests:
storage: 2Gi
storageClassName: nfs-client-storageclass
10.我们创建一个pod的
apiVersion: v1
kind: Pod
metadata:
name: pod-demo1
namespace: default
spec:
containers:
- name: nginx-1
image: nginx
volumeMounts:
- name: html
mountPath: /usr/share/nginx/html/
volumes:
- name: html
persistentVolumeClaim:
claimName: mypvc-nfs
11.进入pod中写一个文件进行测试来查看一下是否能正常共享