1.PersistentVolume(PV)是集群中已由管理员配置的一段网络存储。集群中的资源就像一个节点是一个集群资源,可以从远程的NFS或分布式对象存储系统中创建得来(pv存储空间大小、访问方式)
2.Pv是诸如卷之类的卷插件,但是只有独立于使用Pv的任何单个pod的生命周期。
3.该API对象捕获存储的实现细节,即NFS,isCSI或云提供商特定的存储系统
4.PV就是从存储设备中的空间创建出一个存储资源
1.PersistentVolumeClaim (Pvc)是用户存储的请求。Pvc的使用逻辑:在podt中定义一个存储卷(该存储卷类型为pvc),定义的时候直按指定大小,pvc必须与对应的pv建立关系,pvc会根据定义去pv申请,而pv是由存储空间创建出来的。pr和pvc是kubernetes抽象出来的一种存储资源
2.虽然PersistentVolumeClaims允许用户使用抽象存储资源,但是常见的需求是,用户需要根据不同的需求去创建v,用于不同的场景。而此时需要集群管理员提供不同需求的Pv,而不仅仅是Pv的大小和访问模式,但又不需要用户了解这些卷的实现细节
3.对于这样的需求,此时可以采用storageclass资源
PVv是集群中的资源。Pvc是对这些资源的请求,也是对资源的索引检查。PV和Pvc之间的相互作用遵循这个生命周期:Provisioning(配置)---> Binding(绑定)--->Using(使用)--->Releasing(释放)--->Recycling(回收)
1.这里有两种PV的提供方式:静态或者动态 2.静态-->直接固定存储空间: 集群管理员创建一些PV。它们携带可供集群用户使用的真实存储的详细信息。它们存在于Ktbernetes API中,可用于消费 3.动态-->通过存储类进行动态创建存储空间: 当管理员创建的静态PV都不匹配用户的 PvC时,集群可能会尝试动态地为 Pvc配置卷。此配置基于StorageClasses: PvC必须请求存储类,并且管理员必须已创建并配置该类才能进行动态配置。要求该类的声明有效地为自己禁用动态配置
1.mkdir -p /data/v{1..5} chmod 777 -R /data/* 2.vim /etc/exports /data/v1 192.168.10.0/24(rw,no_root_squash,sync) /data/v2 192.168.10.0/24(rw,no_root_squash,sync) /data/v3 192.168.10.0/24(rw,no_root_squash,sync) /data/v4 192.168.10.0/24(rw,no_root_squash,sync) /data/v5 192.168.10.0/24(rw,no_root_squash,sync) 3.systemctl start rpcbind systemctl start nfs 4.showmount -e 5.hostnamectl set-hostname nfs01 su 6.echo '11111' > /data/v1/index.html echo '22222' > /data/v2/index.html echo '33333' > /data/v3/index.html echo '44444' > /data/v4/index.html echo '55555' > /data/v5/index.html
//这里定义5个Pv,并且定义挂载的路径以及访问模式,还有pv划分的大小 vim pv-demo.yaml ========================================================== apiVersion: v1 kind: PersistentVolume metadata: name: pv001 labels: name: pv001 spec: nfs: path: /data/v1 server: nfs01 accessModes: ["ReadWriteMany","ReadWriteOnce"] capacity: storage: 1Gi --- apiVersion: v1 kind: PersistentVolume metadata: name: pv002 labels: name: pv002 spec: nfs: path: /data/v2 server: nfs01 accessModes: ["ReadWriteOnce"] capacity: storage: 2Gi --- apiVersion: v1 kind: PersistentVolume metadata: name: pv003 labels: name: pv003 spec: nfs: path: /data/v3 server: nfs01 accessModes: ["ReadWriteMany","ReadWriteOnce"] capacity: storage: 2Gi --- apiVersion: v1 kind: PersistentVolume metadata: name: pv004 labels: name: pv004 spec: nfs: path: /data/v4 server: nfs01 accessModes: ["ReadWriteMany","ReadWriteOnce"] capacity: storage: 4Gi --- apiVersion: v1 kind: PersistentVolume metadata: name: pv005 labels: name: pv005 spec: nfs: path: /data/v5 server: nfs01 accessModes: ["ReadWriteMany","ReadWriteOnce"] capacity: storage: 5Gi ========================================================== kubectl apply -f pv-demo.yaml kubectl get pv
//这里定义了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
1.我们通过相同的存储卷,只修改pod的名称 cp pvc-demo.yaml 1.yaml cp pvc-demo.yaml 2.yaml 2.修改pod的名称后,apply执行创建 kubectl apply -f 1.yaml kubectl apply -f 2.yaml 3.查看ip kubectl get pod -o wide 4.curl进行测试,查看是否共享存储卷,多路读写
在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则需要借助第三方接口完成这样的请求
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