前言
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.100
Export 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: v1
kind: PersistentVolume
metadata:
name: pv-nfs-demo001
spec:
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: v1
kind: PersistentVolume
metadata:
name: pv-nfs-demo002
spec:
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: v1
kind: PersistentVolume
metadata:
name: pv-nfs-demo003
spec:
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 created
persistentvolume/pv-nfs-demo002 created
persistentvolume/pv-nfs-demo003 created
[root@k8s-master storage]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pv-nfs-demo001 5Gi(容量) RWX(多路读写) Retain(回收策略) Available 33s
pv-nfs-demo002 10Gi RWX Retain Available 33s
pv-nfs-demo003 1Gi RWO(单路读写) Retain Available
3、创立2个不同属性PVC需要
- 3G-10G多路读写
- 2G-5G单路读写
[root@k8s-master storage]# cat pvc-demo-0001.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-demo-0001
namespace: default
spec:
accessModes: ["ReadWriteMany"] #多路读写
volumeMode: Filesystem
resources:
requests:
storage: 3Gi #最小容量
limits:
storage: 10Gi #最大容量
[root@k8s-master storage]# cat pvc-demo-0002.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-demo-0002
spec:
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 pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
pvc-demo-0001 Bound pv-nfs-demo001 5Gi RWX 13h
pvc-demo-0002 Pending 2m40s #没有匹配卷 挂起
[root@k8s-master storage]# kubectl describe pvc pvc-demo-0002
Name: pvc-demo-0002
Namespace: default
StorageClass:
Status: Pending
Volume:
Labels: <none>
Annotations: <none>
Finalizers: [kubernetes.io/pvc-protection]
Capacity:
Access Modes:
VolumeMode: Filesystem
Mounted 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 pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pv-nfs-demo001 5Gi RWX Retain Bound default/pvc-demo-0001 13h
pv-nfs-demo002 10Gi RWX Retain Available 13h
pv-nfs-demo003 1Gi RWO Retain Available 13h
- 4、Pod的创立绑定PVC
[root@k8s-master storage]# cat volumes-pvc-demo.yaml
apiVersion: v1
kind: Pod
metadata:
name: volumes-pvc-demo
namespace: default
spec:
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 pod
NAME READY STATUS RESTARTS AGE
centos-deployment-66d8cd5f8b-fkhft 1/1 Running 0 27h
my-grafana-7d788c5479-8bx6k 1/1 Running 0 4h24m
volumes-nfs-demo 1/1 Running 0 4h25m
volumes-pvc-demo 1/1 Running 0 4s
[root@k8s-master ~]# kubectl get pvc #能够看到PVC绑定已胜利
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
pvc-demo-0001 Bound pv-nfs-demo001 5Gi RWX 52m
[root@k8s-master ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
centos-deployment-66d8cd5f8b-fkhft 1/1 Running 0 27h
my-grafana-7d788c5479-8bx6k 1/1 Running 0 5h19m
volumes-hostpath-demo 1/1 Running 0 48m
volumes-nfs-demo 1/1 Running 0 5h20m
volumes-pvc-demo 1/1 Running 0 4m
[root@k8s-master ~]# kubectl exec volumes-pvc-demo -it -- /bin/sh #挂载PVC写入数据
/data $ redis-cli
127.0.0.1:6379> set mykey2 "taobao"
OK
127.0.0.1:6379> get mykey2
"taobao"
127.0.0.1:6379> BGSAVE
Background saving started
127.0.0.1:6379> exit
/data $ ls
dump.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 2
apiVersion: v1
kind: Pod
metadata:
name: volumes-pvc2-demo
namespace: default
spec:
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-cli
127.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-demo
pod "volumes-pvc-demo" deleted
[root@k8s-master storage]# kubectl delete pod volumes-pvc2-demo #删除之前两个Pod
pod "volumes-pvc2-demo" deleted
[root@k8s-master storage]# kubectl get pvc #删除Pod不影响PVC及数据
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
pvc-demo-0001 Bound pv-nfs-demo001 5Gi RWX 14h
pvc-demo-0002 Pending 33m
[root@k8s-master storage]# kubectl delete pvc pvc-demo-0001 #删除PVC
persistentvolumeclaim "pvc-demo-0001" deleted
[root@k8s-master storage]# kubectl get pv #因为回收策略为Retain 所以PV不会主动删除 变为Released状态
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pv-nfs-demo001 5Gi RWX Retain Released default/pvc-demo-0001 14h
pv-nfs-demo002 10Gi RWX Retain Available 14h
pv-nfs-demo003 1Gi RWO Retain Available 14h
[root@k8s-master storage]# kubectl apply -f pvc-demo-0001.yaml #最次创立PVC看是否能绑定原来的PV
persistentvolumeclaim/pvc-demo-0001 created
[root@k8s-master storage]# kubectl get pv #绑定到的新的PV 原来的PV还是为Released状态
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pv-nfs-demo001 5Gi RWX Retain Released default/pvc-demo-0001 14h
pv-nfs-demo002 10Gi RWX Retain Bound default/pvc-demo-0001 14h
pv-nfs-demo003 1Gi RWO Retain Available 14h
[root@k8s-master storage]# kubectl delete -f pvc-demo-0001.yaml #删除Pod
persistentvolumeclaim "pvc-demo-0001" deleted
[root@k8s-master storage]# kubectl get pv #当初两个PV都为Released
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pv-nfs-demo001 5Gi RWX Retain Released default/pvc-demo-0001 14h
pv-nfs-demo002 10Gi RWX Retain Released default/pvc-demo-0001 14h
pv-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: Filesystem
status:
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 AGE
pv-nfs-demo001 5Gi RWX Retain Available 14h
pv-nfs-demo002 10Gi RWX Retain Available 14h
pv-nfs-demo003 1Gi RWO Retain Available
14h
[root@k8s-master storage]# kubectl apply -f pvc-demo-0001.yaml #新建PVC
persistentvolumeclaim/pvc-demo-0001 created
[root@k8s-master storage]# kubectl get pv #查看PV 绑定到原来的PV胜利
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pv-nfs-demo001 5Gi RWX Retain Bound default/pvc-demo-0001 14h
pv-nfs-demo002 10Gi RWX Retain Available 14h
pv-nfs-demo003 1Gi RWO Retain Available 14h
[root@k8s-master storage]# kubectl apply -f volumes-pvc-demo.yaml #从新创立Pod
pod/volumes-pvc-demo created
[root@k8s-master storage]# kubectl get pod
NAME READY STATUS RESTARTS AGE
centos-deployment-66d8cd5f8b-fkhft 1/1 Running 0 41h
my-grafana-7d788c5479-8bx6k 1/1 Running 0 19h
volumes-hostpath-demo 1/1 Running 0 14h
volumes-nfs-demo 1/1 Running 0 19h
volumes-pvc-demo 1/1 Running 0 3s
[root@k8s-master storage]# kubectl exec volumes-pvc-demo -it -- /bin/sh #查看之前数据
/data $ ls
dump.rdb
/data $ redis-cli
127.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 #删除Pod
pod "volumes-pvc-demo" deleted
[root@k8s-master storage]# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
pvc-demo-0001 Bound pv-nfs-demo001 5Gi RWX 6m34s
pvc-demo-0002 Pending 79m
[root@k8s-master storage]# kubectl delete pvc pvc-demo-0001 #删除PVC
persistentvolumeclaim "pvc-demo-0001" deleted
[root@k8s-master storage]# kubectl delete pv pv-nfs-demo001 #删除PV
persistentvolume "pv-nfs-demo001" deleted
[root@k8s-master storage]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pv-nfs-demo002 10Gi RWX Retain Available 14h
pv-nfs-demo003 1Gi RWO Retain Available 14h
[root@nfs ~]# ls /data/redis001/ #NFS服务查看数据文件 仍然存在
dump.rdb
PVC、PV总结:
- 删除Pod、PVC 在回收策略为Retain状况下,数据不会失落
- PV的删除数据是否会失落与存储类型无关,上述测试的NFS不会失落不代表所有的PV删除都不会失落,PV删除需谨慎
发表回复