前言
Volume 提供了十分好的数据长久化计划,不过在可管理性上还有有余。拿后面示例能够看出,要应用Volume,Pod 必须当时晓得如下信息:
- 以后 Volume 来自来哪里及具体位置 Local、网络。
- 存储卷的类型,并晓得每种类型卷的配置应用办法,通过 kubectl explain pods.spec.volumes 能够看到kubernetes反对卷的类型十分的多
Pod通常是由利用的开发人员保护,而 Volume 则通常是由存储系统的管理员保护。开发人员要取得下面的信息:要么询问管理员 要么本人就是管理员。
这样就带来一个治理上的问题:利用开发人员和系统管理员的职责耦合在一起了。如果零碎规模较小或者对于开发环境这样的状况还能够承受。但当集群规模变大,特地是对于生成环境,思考到效率和安全性,这就成了必须要解决的问题。
Kubernetes 给出的解决方案是 PersistentVolume 和 PersistentVolumeClaim。
PersistentVolume (PV) 是内部存储系统中的一块存储空间,由管理员创立和保护。与 Volume 一样,PV 具备持久性,生命周期独立于 Pod。
PersistentVolumeClaim (PVC) 是对 PV 的申请 (Claim)。PVC 通常由普通用户创立和保护。须要为 Pod 调配存储资源时,用户能够创立一个 PVC,指明存储资源的容量大小和拜访模式(比方只读)等信息,Kubernetes 会查找并提供满足条件的 PV。
有了 PersistentVolumeClaim,用户只须要通知 Kubernetes 须要什么样的存储资源,而不用关怀真正的空间从哪里调配,如何拜访等底层细节信息。这些 Storage Provider 的底层信息交给管理员来解决,只有管理员才应该关怀创立 PersistentVolume 的细节信息。
PVC和PV简介
- 是由管理员设置的存储,它是群集的一部分。就像节点是集群中的资源一样,PV 也是集群中的资源。 PV 是Volume 之类的卷插件,但具备独立于应用 PV 的 Pod 的生命周期。此 API 对象蕴含存储实现的细节,即NFS、iSCSI 或特定于云供应商的存储系统
- PV、PVC:将存储生产,存储创立的职能拆散开来,
- PV: Persistent Volume,长久卷,可被PVC绑定;而PV肯定要与某个真正的存储空间(个别是网络存储服务上的存储空间)对应起来,能力真正存储数据。由集群管理员负责管理。集群级别资源;将真正的存储设备上的一段存储空间形象成的k8s的对象
- PVC: Persistent Volume Claim 长久卷申请,简称PVC;k8s上规范的资源类型之一;名称空间级别;由用户定义出存储生产需要,而后依据需要条件与现有各PV进行匹配检测,找出一个最佳的应用。
Pod应用这类存储的步骤:
- Admin: 创立好PV;
- User: 按需创立PVC,而后创立Pod,在Pod调用persistentVolumeClaim 类型的存储卷插件调用同一个名称空间的PVC资源;
PV字段介绍:
除了存储卷插件之外,PersistentVolume资源标准Spec字段次要反对嵌套以下几个通用字段,它们用于定义PV的容量、拜访模式和回收策略等属性
- capacity <map[string]string>: 指定PV的容量;目前 Capacity仅反对存储容量设定,未来还应该能够指定IOPS和吞吐量(throughput) 。
- accessModes <[]string>: 指定以后PV反对拜访模式;存储系统反对存取能力大体可分为ReadWriteOnce(单路读写)、ReadOnlyWlany(多路只读)和ReadwriteMany(多路读写)三种类型,某个特定的存储系统可能会反对其中的局部或全副的能力。
- persistentVolumeReclaimPolicy <string> ∶PV空间被开释时的解决机制;可用类型仅为Retain(默认)、Recycle(已废除)或Delete(k8s主动发明默认抉择)。目前,仅nfs和hostPath反对Recycle策略,也仅有局部存储系统反对Delete策略。
- volumenode <string>:该PV的卷模型,用于指定此存储卷被格式化为文件系统应用还是间接应用裸格局的块设施;默认值为Filesystem,仅块设施接口的存储系统反对该性能。
- storageClassName <string>:以后PV所属的StorageClass资源的名称,指定的存储类须要当时存在;默认为空值,即不属于任何存储类。
- mountOptions <string>:挂载选项组成的列表,例如ro、soft和hard等。
- nodeAffinity <Object>:节点亲和性,用于限度可能拜访该PV的节点,进而会影响到应用与该PV关联的PVC的Pod的调度后果。
PVC字段介绍:
定义PVC时,用户可通过拜访模式(accessModes)、数据期(dataSource)、存储资源空间需要和限度(resources)、存储类、标签选择器、卷模型和卷名称等匹配规范来筛选集群上的PV资源,其中,resources和accessModes是最重的筛选规范。PVC的Spec字段的可嵌套字段有如下几个。
- accessModes <[]string>: PVC的拜访模式;它同样反对RWO、RWX和ROX三种模式;
- dataSrouces <Object>: 用于从指定的数据源复原该PVC卷,它目前反对的数据源包含一个当初卷快照对象(snapshot.storage.k8s.io/VolumeSnapshot)、一个既有PVC对象(PersistentVolumeClaim)或一个既有的用于数据转存的自定义资源对象(resource/object) ;
- resources <Object>: 申明应用的存储空间的最小值和最大值;目前,PVC的资源限定仅反对空间大小一个维度;
- selector <Object>: 筛选PV时额定应用的标签选择器(matchLabels)或匹配条件表达式, (matchExpressions) ;
- storageClassName <string>:该PVC资源附属的存储类资源名称;指定了存储类资源的PVC仅能在同一个存储类下筛选PV资源,否则,就只能从所有不具备存储类的PI中进行筛选;
- volumeMode <string>∶卷模型,用于指定此卷可被用作文件系统还是裸格局的块设施;默认值为Filesystem;
- volumeName <string>: 间接指定要绑定的PV咨源的名称
资源标准:
spec: volumes : - name <string> #存储卷名称标识,仅可应用DNS标签格局的字符,在以后Pod中必须唯 vOL_TYPE <0bject> #存储卷插件及具体的指标存储供给方的相干配置 containers: - name: ... image: ... volumeMounts: - name <string> #要挂载的存储卷的名称,必须匹配存储卷列表中某项的定义 mountPath <string> #容器文件系统上的挂载点门路 readOnly <boolean> #是否挂载为只读模式,默认为“否” subPath <string> #挂载存储卷上的一个子目录至指定的挂载点 subPathExpr <string> #挂载由指定的模式匹配到的存储卷的文件或目录至挂载点
示例1: NFS网络存储、PV、PVC、POD创立与援用
- 1、创立NFS服务共享目录
[root@nfs ~]# mkdir /data/redis00{1,2,3,4,5}[root@nfs ~]# chmod -R 1010 /data/[root@nfs ~]# cat /etc/exports/data/redis 192.168.4.0/24(rw)/data/redis001 192.168.4.0/24(rw)/data/redis002 192.168.4.0/24(rw)/data/redis003 192.168.4.0/24(rw)/data/redis004 192.168.4.0/24(rw)/data/redis005 192.168.4.0/24(rw)[root@nfs ~]# systemctl restart nfs[root@k8s-node1 ~]# showmount -e 192.168.4.100Export list for 192.168.4.100:/data/redis005 192.168.4.0/24/data/redis004 192.168.4.0/24/data/redis003 192.168.4.0/24/data/redis002 192.168.4.0/24/data/redis001 192.168.4.0/24/data/redis 192.168.4.0/24
2、创立3种不同类型的PV 别离为
- 5G多路读写
- 10G多路读
- 1G单路读写
[root@k8s-master storage]# cat pv-nfs-demo001.yaml apiVersion: v1kind: PersistentVolumemetadata: name: pv-nfs-demo001spec: capacity: storage: 5Gi #容量 volumeMode: Filesystem #文件系统 accessModes: - ReadWriteMany #多路读写 persistentVolumeReclaimPolicy: Retain #回收策略 mountOptions: - hard - nfsvers=4.1 nfs : path: "/data/redis001" server: 192.168.4.100 #nfs存储地址与门路[root@k8s-master storage]# cat pv-nfs-demo002.yaml apiVersion: v1kind: PersistentVolumemetadata: name: pv-nfs-demo002spec: capacity: storage: 10Gi #容量 volumeMode: Filesystem accessModes: - ReadWriteMany #多路读 persistentVolumeReclaimPolicy: Retain mountOptions: - hard - nfsvers=4.1 nfs : path: "/data/redis002" server: 192.168.4.100 #nfs存储地址与门路 [root@k8s-master storage]# cat pv-nfs-demo003.yaml apiVersion: v1kind: PersistentVolumemetadata: name: pv-nfs-demo003spec: capacity: storage: 1Gi volumeMode: Filesystem accessModes: - ReadWriteOnce #单路读写 persistentVolumeReclaimPolicy: Retain mountOptions: - hard - nfsvers=4.1 nfs : path: "/data/redis002" server: 192.168.4.100 [root@k8s-master storage]# kubectl apply -f pv-nfs-demo001.yaml -f pv-nfs-demo002.yaml -f pv-nfs-demo003.yaml #创立3个不同属性的PV卷persistentvolume/pv-nfs-demo001 createdpersistentvolume/pv-nfs-demo002 createdpersistentvolume/pv-nfs-demo003 created[root@k8s-master storage]# kubectl get pvNAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGEpv-nfs-demo001 5Gi(容量) RWX(多路读写) Retain(回收策略) Available 33spv-nfs-demo002 10Gi RWX Retain Available 33spv-nfs-demo003 1Gi RWO(单路读写) Retain Available
3、创立2个不同属性PVC需要
- 3G-10G多路读写
- 2G-5G单路读写
[root@k8s-master storage]# cat pvc-demo-0001.yaml apiVersion: v1kind: PersistentVolumeClaimmetadata: name: pvc-demo-0001 namespace: defaultspec: accessModes: ["ReadWriteMany"] #多路读写 volumeMode: Filesystem resources: requests: storage: 3Gi #最小容量 limits: storage: 10Gi #最大容量 [root@k8s-master storage]# cat pvc-demo-0002.yaml apiVersion: v1kind: PersistentVolumeClaimmetadata: name: pvc-demo-0002spec: accessModes: ["ReadWriteOnce"] #单路读写 volumeMode: Filesystem resources: requests: storage: 2Gi #要求最小容量 2G-5G之间 limits: storage: 5Gi #要求最大容量 selector: #应用标签匹配 matchLabels: usedof : "redisdata"
- PVC依据须要会主动与PV匹配并绑定
[root@k8s-master storage]# kubectl get pvcNAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGEpvc-demo-0001 Bound pv-nfs-demo001 5Gi RWX 13hpvc-demo-0002 Pending 2m40s #没有匹配卷 挂起[root@k8s-master storage]# kubectl describe pvc pvc-demo-0002 Name: pvc-demo-0002Namespace: defaultStorageClass: Status: PendingVolume: Labels: <none>Annotations: <none>Finalizers: [kubernetes.io/pvc-protection]Capacity: Access Modes: VolumeMode: FilesystemMounted By: <none>Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal FailedBinding 7s (x3 over 34s) persistentvolume-controller no persistent volumes available for this claim and no storage class is set #没有匹配标签的PV挂起[root@k8s-master storage]# kubectl get pvNAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGEpv-nfs-demo001 5Gi RWX Retain Bound default/pvc-demo-0001 13h pv-nfs-demo002 10Gi RWX Retain Available 13hpv-nfs-demo003 1Gi RWO Retain Available 13h
- 4、Pod的创立绑定PVC
[root@k8s-master storage]# cat volumes-pvc-demo.yaml apiVersion: v1kind: Podmetadata: name: volumes-pvc-demo namespace: defaultspec: containers: - name: redis image: redis:alpine imagePullPolicy: IfNotPresent securityContext: runAsUser: 1010 ports: - containerPort: 6379 name: redisport volumeMounts: - mountPath: /data name: redis-rbd-vol volumes: - name: redis-rbd-vol persistentVolumeClaim: claimName: pvc-demo-0001 #挂载PVC 指定名称 [root@k8s-master storage]# kubectl apply -f volumes-pvc-demo.yaml pod/volumes-pvc-demo created[root@k8s-master storage]# kubectl get podNAME READY STATUS RESTARTS AGEcentos-deployment-66d8cd5f8b-fkhft 1/1 Running 0 27hmy-grafana-7d788c5479-8bx6k 1/1 Running 0 4h24mvolumes-nfs-demo 1/1 Running 0 4h25mvolumes-pvc-demo 1/1 Running 0 4s[root@k8s-master ~]# kubectl get pvc #能够看到PVC绑定已胜利NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGEpvc-demo-0001 Bound pv-nfs-demo001 5Gi RWX 52m[root@k8s-master ~]# kubectl get podNAME READY STATUS RESTARTS AGEcentos-deployment-66d8cd5f8b-fkhft 1/1 Running 0 27hmy-grafana-7d788c5479-8bx6k 1/1 Running 0 5h19mvolumes-hostpath-demo 1/1 Running 0 48mvolumes-nfs-demo 1/1 Running 0 5h20mvolumes-pvc-demo 1/1 Running 0 4m[root@k8s-master ~]# kubectl exec volumes-pvc-demo -it -- /bin/sh #挂载PVC写入数据/data $ redis-cli127.0.0.1:6379> set mykey2 "taobao"OK127.0.0.1:6379> get mykey2"taobao"127.0.0.1:6379> BGSAVEBackground saving started127.0.0.1:6379> exit/data $ lsdump.rdb/data $ [root@nfs redis001]# ls /data/redis001/ #nfs服务器上查看数据dump.rdb
示例2: 通过PVC实现共享数据
这里只是演示不同的Pod能够挂载同一个PVC共享数据,但对于一些有状态的服务,数据的实时读写和服务、存储类型都有关系
[root@k8s-master storage]# cat volumes-pvc2.demo.yaml #新建redis 2apiVersion: v1kind: Podmetadata: name: volumes-pvc2-demo namespace: defaultspec: containers: - name: redis image: redis:alpine imagePullPolicy: IfNotPresent securityContext: runAsUser: 1010 ports: - containerPort: 6379 name: redisport volumeMounts: - mountPath: /data name: redis-rbd-vol volumes: - name: redis-rbd-vol persistentVolumeClaim: claimName: pvc-demo-0001 #应用雷同的PVC[root@k8s-master storage]# kubectl exec volumes-pvc2-demo -it -- /bin/sh #在别一个Pod上查看数据 /data $ redis-cli127.0.0.1:6379> get mykey"baidu.com"127.0.0.1:6379> exit/data $ exit
示例3: 删除Pod、PVC、PV后复原数据
- 所有数据的复原都须要回收策略为Retain的状况下
- 删除Pod及PVC
[root@k8s-master storage]# kubectl delete pod volumes-pvc-demopod "volumes-pvc-demo" deleted[root@k8s-master storage]# kubectl delete pod volumes-pvc2-demo #删除之前两个Podpod "volumes-pvc2-demo" deleted[root@k8s-master storage]# kubectl get pvc #删除Pod不影响PVC及数据NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGEpvc-demo-0001 Bound pv-nfs-demo001 5Gi RWX 14hpvc-demo-0002 Pending 33m[root@k8s-master storage]# kubectl delete pvc pvc-demo-0001 #删除PVCpersistentvolumeclaim "pvc-demo-0001" deleted[root@k8s-master storage]# kubectl get pv #因为回收策略为Retain 所以PV不会主动删除 变为Released状态NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGEpv-nfs-demo001 5Gi RWX Retain Released default/pvc-demo-0001 14hpv-nfs-demo002 10Gi RWX Retain Available 14hpv-nfs-demo003 1Gi RWO Retain Available 14h[root@k8s-master storage]# kubectl apply -f pvc-demo-0001.yaml #最次创立PVC看是否能绑定原来的PVpersistentvolumeclaim/pvc-demo-0001 created[root@k8s-master storage]# kubectl get pv #绑定到的新的PV 原来的PV还是为Released状态NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGEpv-nfs-demo001 5Gi RWX Retain Released default/pvc-demo-0001 14hpv-nfs-demo002 10Gi RWX Retain Bound default/pvc-demo-0001 14hpv-nfs-demo003 1Gi RWO Retain Available 14h[root@k8s-master storage]# kubectl delete -f pvc-demo-0001.yaml #删除Podpersistentvolumeclaim "pvc-demo-0001" deleted[root@k8s-master storage]# kubectl get pv #当初两个PV都为ReleasedNAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGEpv-nfs-demo001 5Gi RWX Retain Released default/pvc-demo-0001 14hpv-nfs-demo002 10Gi RWX Retain Released default/pvc-demo-0001 14hpv-nfs-demo003 1Gi RWO Retain Available 14h
- 批改PVC 让PVC复原为Available状态 从新绑定
[root@k8s-master storage]# kubectl edit pv pv-nfs-demo001 #批改PV 让状态变为Available 能够从新绑定...spec: accessModes: - ReadWriteMany capacity: storage: 5Gi claimRef: #删除claimRef:字段所有内容 apiVersion: v1 kind: PersistentVolumeClaim name: pvc-demo-0001 namespace: default resourceVersion: "6371169" uid: f8a9ba0b-e15e-44ea-bccf-6b40f0d46390 mountOptions: - hard - nfsvers=4.1 nfs: path: /data/redis001 server: 192.168.4.100 persistentVolumeReclaimPolicy: Retain volumeMode: Filesystemstatus: phase: Released...[root@k8s-master storage]# kubectl edit pv pv-nfs-demo002 #pv-nfs-demo002也做雷同操作persistentvolume/pv-nfs-demo002 edited[root@k8s-master storage]# kubectl get pv #复原Available状态NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGEpv-nfs-demo001 5Gi RWX Retain Available 14hpv-nfs-demo002 10Gi RWX Retain Available 14hpv-nfs-demo003 1Gi RWO Retain Available 14h[root@k8s-master storage]# kubectl apply -f pvc-demo-0001.yaml #新建PVCpersistentvolumeclaim/pvc-demo-0001 created[root@k8s-master storage]# kubectl get pv #查看PV 绑定到原来的PV胜利NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGEpv-nfs-demo001 5Gi RWX Retain Bound default/pvc-demo-0001 14hpv-nfs-demo002 10Gi RWX Retain Available 14hpv-nfs-demo003 1Gi RWO Retain Available 14h[root@k8s-master storage]# kubectl apply -f volumes-pvc-demo.yaml #从新创立Podpod/volumes-pvc-demo created[root@k8s-master storage]# kubectl get podNAME READY STATUS RESTARTS AGEcentos-deployment-66d8cd5f8b-fkhft 1/1 Running 0 41hmy-grafana-7d788c5479-8bx6k 1/1 Running 0 19hvolumes-hostpath-demo 1/1 Running 0 14hvolumes-nfs-demo 1/1 Running 0 19hvolumes-pvc-demo 1/1 Running 0 3s[root@k8s-master storage]# kubectl exec volumes-pvc-demo -it -- /bin/sh #查看之前数据/data $ lsdump.rdb/data $ redis-cli127.0.0.1:6379> get mykey2"taobao"127.0.0.1:6379> exit/data $ exit[root@k8s-master storage]# [root@k8s-master storage]# kubectl delete pod volumes-pvc-demo #删除Podpod "volumes-pvc-demo" deleted[root@k8s-master storage]# kubectl get pvcNAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGEpvc-demo-0001 Bound pv-nfs-demo001 5Gi RWX 6m34spvc-demo-0002 Pending 79m[root@k8s-master storage]# kubectl delete pvc pvc-demo-0001 #删除PVCpersistentvolumeclaim "pvc-demo-0001" deleted[root@k8s-master storage]# kubectl delete pv pv-nfs-demo001 #删除PVpersistentvolume "pv-nfs-demo001" deleted[root@k8s-master storage]# kubectl get pvNAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGEpv-nfs-demo002 10Gi RWX Retain Available 14hpv-nfs-demo003 1Gi RWO Retain Available 14h[root@nfs ~]# ls /data/redis001/ #NFS服务查看数据文件 仍然存在dump.rdb
PVC、PV总结:
- 删除Pod、PVC 在回收策略为Retain状况下,数据不会失落
- PV的删除数据是否会失落与存储类型无关,上述测试的NFS不会失落不代表所有的PV删除都不会失落,PV删除需谨慎