赞
踩
PVC和PV
PersistentVolume (PV)是集群中已由管理员配置的一段网络存储。集群中的资源就像一个节点是一个集群资源。PV是诸如卷之类的卷插件,但是具有独立于使用Pv的任何单个pod的生命周期。该API对象捕获存储的实现细节,即NFS, iscs1或云提供商特定的存储系统。
PersistentVolumeClaim (PVC)是用户存储的请求。PVC的使用逻辑:在pod中定义一个存储卷(该存储卷类型为PVC) ,定义的时候直接指定大小, pvc必须与对应的pv建立关系, pvc会根据定义去pv申请, 而pv是由存储空间创建出来的。pv和pvc是kubernetes抽象出来的一种存储资源。
虽然PersistentvolumeClaims允许用户使用抽象存储资源,但是常见的需求是,用户需要根据不同的需求去创建PV,用于不同的场景。而此时需要集群管理员提供不同需求的PV,而不仅仅是PV的大小和访问模式,但又不需要用户了解这些卷的实现细节**。对于这样的需求,此时可以采用storageclass资源。**
PV是集群中的资源。PVc是对这些资源的请求,也是对资源的索引检查。
PV和pvc之间的相互作用遵循这个生命周期
PV的提供方式有两种,分别是静态和动态
PV 就是从存储设备的空间创建出一个存储资源(逻辑上存在)
静态:由k8s管理员创建的,供k8s集群(pod)使用的存储资源,可以从远程的NFS,或者分布式对象存储系统中创建得来(pv存储空间大小,访问方式)
动态storageClass(存储类资源):用于动态的自动创建pvc申请的pv资源供pod使用
pod 使用pvc ----请求------> PV资源 ------> 存储设备中
kubectl explain pv #查看pv的定义方式
FIELDS:
apiVersion
kind
metadata
spec
[root@master ~]# kubectl explain pv.spec
spec:
nfs (定义存储类型)
path (定义挂载卷路径)
server (定义服务器名称)
accessModes (定义访问模型,有以下三种访问模型,以列表的方式存在,也就是说可以定义多个访问模式)
ReadwriteOnce (RWO) 单节点读写
ReadonlyMany (ROX) 多节点只读
ReadwriteMany (RWX) 多节点读写
capacity (定义PV空间的大小)
storage (指定大小)
kubectl explain pvc #查看pvc的定义方式
KIND: PersistentVolumeClaim
VERSION: v1
FIELDS:
apiVersion: <string>
kind <string>
metadata <Object>
spec <Object>
kubectl explain pvc.spec #查看pvc的规格
spec:
accessModes (定义访问模式,必须是pv的访问模式的子集)
resources (定义申请资源的大小)
requests:
storage:
[root@nfs ~]# yum -y install nfs-utils rpcbind
[root@nfs ~]# mkdir -p /data/volumes/v{1..5}
[root@nfs ~]# ls -R /data/
[root@nfs ~]# chmod -R 777 /data/*
#配置nfs共享的目录
[root@nfs ~]# for i in {1..5}
do
echo "/data/volumes/v$1 192.168.23.0/24(rw,no_root_squash,sync)" >> /etc/exports
done
#写入网页内容
[root@nfs ~]# for i in {1..5}
do
echo "this is pv00$i" > /data/volumes/v$i/index.html
done
[root@nfs ~]# systemctl start rpcbind
[root@nfs ~]# systemctl start nfs
[root@nfs ~]# exportfs -arv
[root@nfs ~]# showmount -e
定义5个 pv,并且定义挂载的路径及访问模式,pv划分大小
[root@master ~]# vim pv-demo.yaml apiVersion: v1 kind: PersistentVolume metadata: name: pv001 labels: name: pv001 spec: nfs: path: /data/volumes/v1 server: stor01 accessModes: - ReadWriteMany - ReadWriteOnce capacity: storage: 1Gi --- apiVersion: v1 kind: PersistentVolume metadata: name: pv002 labels: name: pv002 spec: nfs: path: /data/volumes/v2 server: stor01 accessModes: - ReadWriteOnce capacity: storage: 2Gi --- apiVersion: v1 kind: PersistentVolume metadata: name: pv003 labels: name: pv003 spec: nfs: path: /data/volumes/v3 server: stor01 accessModes: - ReadWriteMany - ReadWriteOnce capacity: storage: 2Gi --- apiVersion: v1 kind: PersistentVolume metadata: name: pv004 labels: name: pv004 spec: nfs: path: /data/volumes/v4 server: stor01 accessModes: - ReadWriteMany - ReadWriteOnce capacity: storage: 4Gi --- apiVersion: v1 kind: PersistentVolume metadata: name: pv005 labels: name: pv005 spec: nfs: path: /data/volumes/v5 server: stor01 accessModes: - ReadWriteMany - ReadWriteOnce capacity: storage: 5Gi
[root@master ~]# kubectl apply -f pv-demo.yaml
[root@master ~]# kubectl get pv
pvc请求的 访问模式accessMode 及 storage大小(capacity 栏)都完全符合
[root@master ~]# vim pod-vol-pvc.yaml apiVersion: v1 kind: PersistentVolumeClaim metadata: name: mypvc namespace: default spec: accessModes: - ReadWriteMany resources: requests: storage: 2Gi --- apiVersion: v1 kind: Pod metadata: name: pod-vo1-pvc namespace: default spec: containers: - name: myapp image: ikubernetes/myapp:v1 volumeMounts: - name: html mountPath: /usr/share/nginx/html volumes: - name: html persistentVolumeClaim: claimName: mypvc
[root@master ~]# kubectl apply -f pod-vol-pvc.yaml
persistentvolumeclaim/mypvc created
pod/pod-vo1-pvc created
[root@master ~]# kubectl get pods,pv -o wide
[root@master ~]# curl 10.244.1.151
this is pv003
在访问模式符合 的情况下,大小不符合,则会再所以大于请求大小的pv中,选择大小最接近的
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: mypvc-test02 namespace: default spec: accessModes: - ReadWriteMany resources: requests: storage: 2Gi --- apiVersion: v1 kind: Pod metadata: name: pod-vo2-pvc namespace: default spec: containers: - name: myapp image: ikubernetes/myapp:v1 volumeMounts: - name: html mountPath: /usr/share/nginx/html volumes: - name: html persistentVolumeClaim: claimName: mypvc-test02
[root@master ~]# kubectl apply -f pod-vol-pvc.yaml
persistentvolumeclaim/mypvc-test02 created
pod/pod-vo2-pvc created
[root@master ~]# kubectl get pods,pv,pvc -o wide
[root@master ~]# curl 10.244.2.117
this is pv004
在访问模式不符合,或者大小没有满足的(都效于),则pod和pvc都处于pending状态
[root@master ~]# vim pod-vol-pvc.yaml apiVersion: v1 kind: PersistentVolumeClaim metadata: name: mypvc-test03 namespace: default spec: accessModes: - ReadWriteMany resources: requests: storage: 7Gi --- apiVersion: v1 kind: Pod metadata: name: pod-vo3-pvc namespace: default spec: containers: - name: myapp image: ikubernetes/myapp:v1 volumeMounts: - name: html mountPath: /usr/share/nginx/html volumes: - name: html persistentVolumeClaim: claimName: mypvc-test03
[root@master ~]# kubectl apply -f pod-vol-pvc.yaml
persistentvolumeclaim/mypvc-test03 created
pod/pod-vo3-pvc created
[root@master ~]# kubectl get pods,pv,pvc -o wide
[root@master ~]# kubectl get pods,pv,pvc -o wide
[root@master ~]# kubectl describe pod pod-vo3-pvc
使用多主机读写 RWX (ReadWriteMany) 模式,将新创建的pod 加入到已有的pvc 中
[root@master ~]# vim pod-vol-pvc.yaml apiVersion: v1 kind: Pod metadata: name: pod-vo4-pvc namespace: default spec: containers: - name: myapp image: ikubernetes/myapp:v1 volumeMounts: - name: html mountPath: /usr/share/nginx/html volumes: - name: html persistentVolumeClaim: claimName: mypvc-test02
[root@master ~]# kubectl apply -f pod-vol-pvc.yaml
pod/pod-vo4-pvc created
[root@master ~]# kubectl get pods,pv,pvc -o wide
[root@master ~]# curl 10.244.1.152
this is pv004
当pvc请求的 类型accessModes 和存储storage大小没有完全符合的pv时
会在 accessModes类型相同的情况下
在 类型accessModes都没有符合的情况下,或者storage存储大小都小于请求的时候
多节点读写:
在创建pod时,pod.spec.volumes.claimName 的值使用已有的pvc 名,可以是pod使用已有的pvc,从而使用pv
[root@master ~]# kubectl describe persistentvolumeclaims mypvc-test02 .... Mounted By: pod-vo2-pvc pod-vo4-pvc ..... #先删除使用这个pvc的所有pod [root@master ~]# kubectl delete pod pod-vo{2,4}-pvc pod "pod-vo2-pvc" deleted pod "pod-vo4-pvc" deleted #再删除pvc [root@master ~]# kubectl delete persistentvolumeclaims mypvc-test02 persistentvolumeclaim "mypvc-test02" deleted #查看发现pvc确实被删除了,但是,相应的pv处于Released状态,此时pv无法被新pvc绑定 [root@master ~]# kubectl get pods,pv,pvc -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES persistentvolume/pv004 4Gi RWO,RWX Retain Released default/mypvc-test02 73m Filesystem
使用 edit 在线对pv 资源进行编辑,删除claiRef段落。保存后,通过命令查看,其状态就自动变为了Available,PV即可重新使用
[root@master ~]# kubectl edit persistentvolume pv004
...
#删除
claimRef:
apiVersion: v1
kind: PersistentVolumeClaim
name: mypvc-test02
namespace: default
resourceVersion: "242922"
uid: 95ef0c00-754e-4a8e-81c3-f8ee4d5f9824
.....
[root@master ~]# kubectl get pods,pv,pvc -o wide
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE VOLUMEMODE
persistentvolume/pv004 4Gi RWO,RWX Retain Available 81m Filesystem
<b
在pv和pvc使用过程中存在的问题,在pvc申请存储空间时,未必就有现成的pv符合pvc申请的需求,上面nfs在做pvc可以成功的因素是因为我们做了指定的需求处理。
那么当PVC申请的存储空间不一定有满足PVC要求的PV时,又该如何处理呢? ? ?为此, Kubernetes为管理员提供了描述存储"Class(类) "的方法(StorageClass) 。
举个例子,在存储系统中划分一个1TB的存储空间提供给Kubernetes使用,当用户需要一个10G的PVC时,会立即通过restful发送请求,从而让存储空间创建一个10G的image,之后在我们的集群中定义成10G的PV供给给当前的PVc作为挂载使用。在此之前我们的存储系统必须支持restful接口,比如ceph分布式存储,而glusterfs则需要借助第三方接口完成这样的请求。
kubectl explain storageclass #storageclass也是k8s上的资源KIND: storageclass
VERSION: storage.k8s.io/v1
FIELDS:
allowVolumeExpansion <boolean>
allowedTopologies <[]object>
apiversion <string>
kind <string>
metadata <object>
mountOptions <[string> #挂载选项
parameters <map [string]string> #参数,取决于分配器,可以接受不同的参数。例如,参数type的值io1和参数iopsPerGB特定于EBS PV。当参数被省略时,会使用默认值。
provisioner <string>-required- #存储分配器,用来决定使用哪个卷插件分配pv。该字段必须指
reclaimPolicy <string> #回收策略,可以是Delete或者Retain。如果storageclass对象被创建时没有指定reclaimPolicy它将默认为Delete
volumeBindingMode <string> #卷的绑定模式
storageclass中包含provisioner、 parameters和reclaimPolicy字段,当class需要动态分配persistentvolume时会使用到。由于storageclass需要一个独立的存储系统,此处就不再演示。
从其他资料查看定义storageclass的方式如下:
kind: storageclass
apiversion: storage.k8s.io/vl
metadata:
name: standard
provisioner: kubernetes.io/aws-ebs
parameters:
type: gp2
reclaimPolicy: Retain
mountOptions:
- debug
rs <map [string]string> #参数,取决于分配器,可以接受不同的参数。例如,参数type的值io1和参数iopsPerGB特定于EBS PV。当参数被省略时,会使用默认值。
provisioner -required- #存储分配器,用来决定使用哪个卷插件分配pv。该字段必须指
reclaimPolicy #回收策略,可以是Delete或者Retain。如果storageclass对象被创建时没有指定reclaimPolicy它将默认为Delete
volumeBindingMode #卷的绑定模式
</font> <font size=2> ```bash storageclass中包含provisioner、 parameters和reclaimPolicy字段,当class需要动态分配persistentvolume时会使用到。由于storageclass需要一个独立的存储系统,此处就不再演示。 从其他资料查看定义storageclass的方式如下: kind: storageclass apiversion: storage.k8s.io/vl metadata: name: standard provisioner: kubernetes.io/aws-ebs parameters: type: gp2 reclaimPolicy: Retain mountOptions: - debug
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。