乐趣区

关于kubernetes:11kubernetes笔记-Volume存储卷二-PVPVC存储

前言

Volume 提供了十分好的数据长久化计划,不过在可管理性上还有有余。拿后面示例能够看出,要应用 Volume,Pod 必须当时晓得如下信息:

  1. 以后 Volume 来自来哪里及具体位置 Local、网络。
  2. 存储卷的类型, 并晓得每种类型卷的配置应用办法, 通过 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 删除需谨慎
退出移动版