一、PV和PVC
1.1、概念
PersistentVolume(PV)是集群中已由管理员配置的一段网络村吃。集群中的资源就想一个节点是一个集群资源
PV是诸如卷之类卷插件,但是具有独立于使用PV的任何单个pod的生命周期。该API对象补货存储的实现细节,即NFS,iSCSI或云提供商特定的存储系统
PersistentVolumeClaims(PVC)是用户存储的请求。PVC的使用逻辑:在pod中定义一个存储卷(该存储卷类型为pvc),定义的时候直接指定大小,pvc必须与对应的pv建立关系,pvc会根据定义去pv申请,而pv是由存储空间创建出来的。pv和pvc是k8s抽象出来的一种存储资源
虽然PersistentVolumeClaims允许用户使用抽象存储资源,但是常见的需求是,用户需要根据不同的需求去创建pv,用于不同的场景。而此时需要集群管理员提供不同需求的PV,而不仅仅是pv的大小和访问模式,但又不需要用户了解这些卷的实现细节。对于这样的需求,此时可以采用StorageClass资源
pv是集群中的资源。pvc是对这些资源的请求,也是对资源的索引检查。pv和pvc之间的相互作用遵循这个生命周期
Provisioning(配置)--->Binding(绑定)--->Using(使用)--->Releasing(释放)--->Recycling(回收)
1.2、两种PV提供方式
1.2.1、静态
集群管理员创建一些PV。它们携带可供集群用户使用的真实存储的详细信息。它们存在于K8SAPI中,可用于消费
1.2.2、动态
通过存储类进行动态创建存储空间
当管理员创建的静态PV都不匹配用户的PVC时,集群可能会尝试动态的为PVC配置卷。此配置基于Storageclass:PVC
必须请求存储类,并且管理员必须已创建并配置该类才能进行动态配置,要求该类的声明有效的为自己禁用动态配置
1.3、PV定义
kubectl explain pv #查看pv的定义方式
kubectl explain pv.spec #查看pv定义的规格
spec:
nfs(定义存储类型)
path(定义挂载卷路径)
server(定义服务器名称)
accessModes(定义访问模式,以下有三种访问模式,以列表的方式存在,也就是说可以定义多个访问模式)
ReadWriteOnec(RWO) #单节点读写
ReadOnlyMany(ROX) #多节点只读
ReadWriteMany(RWX) #多节点读写
capacity(定义pv空间的大小)
storage(指定大小)
kubectl explain pvc #查看pvc的定义方式
kubectl explain pvc.spec
spec:
accessModes(定义访问模式,必须是pv的访问模式的子集)
resources(定义申请资源的大小)
requests:
storage:
二、基于NFS使用静态pv和pvc
2.1、环境准备
192.168.80.11 master01
192.168.80.12 node01
192.168.80.13 node02
192.168.80.14 nfs
2.2、配置nfs存储
systemctl stop firewalld
setenforce 0
hostnamctl set-hostname nfs
mkdir -p /data/v{1..5}
chmod 777 -R /data/*
vim /etc/exports
/data/v1 192.168.80.0/24(rw,no_root_squash)
/data/v2 192.168.80.0/24(rw,no_root_squash)
/data/v3 192.168.80.0/24(rw,no_root_squash)
/data/v4 192.168.80.0/24(rw,no_root_squash)
/data/v5 192.168.80.0/24(rw,no_root_squash)
systemctl start rpcbind
systemctl start nfs
exportfs -arv #发布共享
showmount -e #查看共享
echo '111111' > /data/v1/index.html
echo '222222' > /data/v2/index.html
echo '333333' > /data/v3/index.html
echo '444444' > /data/v4/index.html
echo '555555' > /data/v5/index.html
2.3、定义PV
//这里定义5个Pv,并且定义挂载的路径以及访问模式,还有pv划分的大小
vim pv-demo.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv1
labels:
name: pv1
spec:
nfs:
path: /data/v1
server: nfs
accessModes: ["ReadWriteMany","ReadWriteOnce"]
capacity:
storage: 1Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv2
labels:
name: pv2
spec:
nfs:
path: /data/v2
server: nfs
accessModes: ["ReadWriteOnce"]
capacity:
storage: 2Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv3
labels:
name: pv3
spec:
nfs:
path: /data/v3
server: nfs
accessModes: ["ReadWriteMany","ReadWriteOnce"]
capacity:
storage: 2Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv4
labels:
name: pv4
spec:
nfs:
path: /data/v4
server: nfs
accessModes: ["ReadWriteMany","ReadWriteOnce"]
capacity:
storage: 4Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv5
labels:
name: pv5
spec:
nfs:
path: /data/v5
server: nfs
accessModes: ["ReadWriteMany","ReadWriteOnce"]
capacity:
storage: 5Gi
kubectl apply -f pv-demo.yaml
kubectl get pv
2.4、定义PVC
#这里定义了pvc的访问模式为多路读写,该访问模式必须在前面pv定义的访问模式之中。定义Pvc申请的大小为2Gi,此时pvc会自动去匹配多路读写且大小为2Gi的Pv,匹配成功获取PVC的状态即为Bound
vim pvc-demo.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mypvc
spec:
accessModes: ["ReadWriteMany"]
resources:
requests:
storage: 2Gi
---
apiVersion: v1
kind: Pod
metadata:
name: pv-pvc
spec:
containers:
- name: myapp
image: nginx
volumeMounts:
- name: html
mountPath: /usr/share/nginx/html
volumes:
- name: html
persistentVolumeClaim:
claimName: mypvc
kubectl apply -f pvc-demo.yaml
kubectl get pv
三、基于动态storageclass创建pv与pvc
3.1 storageclass的用处
在pv和pvc使用过程中存在的问题,在pvc申请存储空间时,未必就有现成的pv符合pvc申请的需求,上面nfs在做pvc可以成功的因素是因为我们做了指定的需求处理。当PvC申请的存储空间不一定有满足PvC要求的Pv时,Kubernetes为管理员提供了描述存储"class(类)"的方法(StorageClass)。举个例子,在存储系统中划分一个1TB的存储空间提供给Kubernetes使用,当用户需要一个10G的PvC时,会立即通过restful发送请求,从而让存储空间创建一个10G的image,之后在我们的集群中定义成10c的Pv供给给当前的Pvc作为挂载使用。在此之前我们的存储系统必须支持restful接口,比如ceph分布式存储,而glusterfs则需要借助第三方接口完成这样的请求
3.2 storageclass的yaml格式
kubectl explain storageclass #storageclass也是k8s上的资源
KIND: Storageclass
VERSION: storage.k8s.io/vl
FIELDS:
allowVolumeExpansion <boolean>
allowedTopologies<[]Object>apiversion<string>
kind <string>
metadata <object>
mountOptions <[]string>挂载选项
parameters <map[string]string#参数,取决于分配器,可以接受不同的参数。例如,参数type的值 io1和参数iopsPerGB特定于EBS PV。当参数被省略时,会使用默认值。
provisioner <string-requred-#存储分配器,用来决定使用哪个卷插件分配 PV。该字段必须指定。
reclaimPolicy <string>#回收策略,可以是 Delete或者 Retain。如果 StorageClass 对象被创建时没有指定 reclaimPolicy,它将默认为 Delete。
volumeBindingMode<string>#卷的绑定模式
StorageClass 中包含 provisioner、parameters和 reclaimPolicy字段,当 class需要动态分配 PersistentVolume时会使用到。由于storageclass需要一个独立的存储系统,此处就不再演示。从其他资料查看定义storageclass的方式如下:
kind: storageClass
apiversion: storage.k8s.io/v1432
metadata :
name : standard
provisioner: kubernetes.iol aws-ebs435 parameters:
type: gp2
reclaimPolicy: Retain
mountoptions:
- debug