• kubernetes的简单化数据存储StorageClass(建立和删除以及初步使用)


    kubernetes的简单化数据存储StorageClass(建立和删除以及初步使用)

    文章目录


    前言

    k8s有着非常多的新概念,而这些概念使得我们学习k8s需要更多的成本,本文主要就k8s的数据持久化存储涉及到的一些新概念:pv,pvc,sc,svc讨论,从而在实际的生产活动中,更好的用好k8s集群。


    一、StorageClass是什么?

    先说结论,StorageClass 为管理员提供了描述存储 "类" 的方法,实现了存储的动态供给,简单来说,StorageClass能够根据pvc来自动创建pv,减轻了集群管理员创建pv的负担。简单的说人话,就是在管理k8s集群的时候,不需要创建pv了,只需要创建一个pvc就可以了。

    那么,这就引出了两个全新的概念,什么是pv?什么是pvc?

    (1)pv

    pv=persistentVolume,是一个缩写,中文意思持久存储,PV是对底层网络共享存储的抽象,将共享存储定义为一种“资源”,比如Node也是容器应用可以消费的资源。PV由管理员创建和配置,与共享存储的具体实现直接相关。

    1. kubernetes支持的PV类型如下:
    2. ◎ AWSElasticBlockStore:AWS公有云提供的ElasticBlockStore。
    3. ◎ AzureFile:Azure公有云提供的File。
    4. ◎ AzureDisk:Azure公有云提供的Disk。
    5. ◎ CephFS:一种开源共享存储系统。
    6. ◎ FC(Fibre Channel):光纤存储设备。
    7. ◎ FlexVolume:一种插件式的存储机制。
    8. ◎ Flocker:一种开源共享存储系统。
    9. ◎ GCEPersistentDisk:GCE公有云提供的PersistentDisk。
    10. ◎ Glusterfs:一种开源共享存储系统。
    11. ◎ HostPath:宿主机目录,仅用于单机测试。
    12. ◎ iSCSI:iSCSI存储设备。
    13. ◎ Local:本地存储设备,目前可以通过指定块(Block)设备提供Local PV,或通过社区开发的sig-storage-local-static-provisioner插件( https://github.com/kubernetes-sigs/sig-storage-local-static-provisioner )来管理Local PV的生命周期。
    14. ◎ NFS:网络文件系统。
    15. ◎ Portworx Volumes:Portworx提供的存储服务。
    16. ◎ Quobyte Volumes:Quobyte提供的存储服务。
    17. ◎ RBD(Ceph Block Device):Ceph块存储。
    18. ◎ ScaleIO Volumes:DellEMC的存储设备。
    19. ◎ StorageOS:StorageOS提供的存储服务。
    20. ◎ VsphereVolume:VMWare提供的存储系统。

    以上可以看到,nfs,iscsi,ceph这些常用的网络存储或者块存储会被看做一个资源,也就是被k8s认为是一个可用资源。

    一个简单的pv创建文件,内容如下:

    1. [root@master mysql]# cat pv_mysql.yaml
    2. kind: PersistentVolume
    3. apiVersion: v1
    4. metadata:
    5. name: nfs-pv-test
    6. namespace: database
    7. spec:
    8. accessModes:
    9. - ReadWriteOnce
    10. capacity:
    11. storage: 1.5Gi
    12. persistentVolumeReclaimPolicy: Retain
    13. storageClassName: nfs
    14. nfs:
    15. path: /data/nfs_sc/nfs-pv-test
    16. server: 192.168.217.16

    上面这个pv创建文件,有比较多的参数,其中需要关注的参数是:

    1, capacity 它的值就是pod允许持久化多少数据,假如这个pv被某个pvc调用,那么,将只能使用1.5G的空间。

    2,存储卷模式(Volume Mode)

    volumeMode=xx,可选项包括Filesystem(文件系统)和Block(块设备),默认值是FileSystem。上面这个文件因为是使用的网络存储nfs,因此,这里省略了,使用的默认filesystem

    3,

    访问模式(Access Modes)

    用于描述应用对存储资源的访问权限。

    ◎ ReadWriteOnce(RWO):读写权限,并且只能被单个Node挂载。

    ◎ ReadOnlyMany(ROX):只读权限,允许被多个Node挂载。

    ◎ ReadWriteMany(RWX):读写权限,允许被多个Node挂载。

    上面的示例使用的readwriteonce ,这个也是比较常用的,另一个常用的就是readwritemany,但,many可能会造成后期的管理上的混乱问题,因此,once是应用最多的,如果不想给自己找麻烦的话,once就够用了,不要使用many。

    4、

    存储类别(Class)

    设定存储的类别,通过storageClassName参数指定给一个StorageClass资源对象的名称,具有特定类别的PV只能与请求了该类别的PVC进行绑定。未绑定类别的PV则只能与不请求任何类别的PVC进行绑定。

    前面已经说过了,如果有设定StorageClass,并且这个StorageClass被设定为默认的话,这个就可以不指定了。如果没有设定默认的StorageClass,那么,这里必须要指定。

    如何选择StorageClass?

    1. [root@master mysql]# k get sc -A
    2. NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
    3. mynfs mynfs Delete Immediate true 4h17m
    4. nfs (default) nfs Delete Immediate true 4h19m
    5. nfs-provisioner choerodon.io/nfs-client-provisioner Delete Immediate false 3d20h
    6. nfs-sc storage.pri/nfs Delete Immediate true 5h5m

    比如我的测试系统,我安装了很多个StorageClass,示例pv文件使用的就是默认nfs(default) 

    5、

    回收策略(Reclaim Policy)

    通过persistentVolumeReclaimPolicy字段设置,

    ◎ Retain 保留:保留数据,需要手工处理。

    ◎ Recycle 回收空间:简单清除文件的操作(例如执行rm -rf /thevolume/* 命令)。

    ◎ Delete 删除:与PV相连的后端存储完成Volume的删除操作

    EBS、GCE PD、Azure Disk、OpenStack Cinder等设备的内部Volume清理)。

    回收策略是根据实际的生产活动来设定的,如果持久化的数据比较重要,那么,retain是一个不错的选择,这里的意思是,如果是retain 即使删除了pv,数据依然保留。本例是使用的retain

    如何查询pv是使用的哪种策略?(总不能什么都看上面的那个示例安装文件吧,万一找不到了呢?)

    1. [root@master mysql]# k get pv -A
    2. NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
    3. mysql-pv-test 1Gi RWO Retain Terminating database/mysql-pvc-test nfs-provisioner 34h
    4. nfs-pv-test 1536Mi RWO Retain Terminating database/nfs-pvc-test nfs 3h56m
    5. pvc-04203f8a-5907-48ce-9fc2-013e94313c3c 8Gi RWO Delete Bound kube-system/redis-data-redis-test-replicas-1 nfs-provisioner 3d11h
    6. pvc-751a32b6-8706-477b-8cad-d71e8e9f3ab8 256Mi RWO Delete Bound kube-system/redis nfs-provisioner 3d11h
    7. pvc-d5ea7d10-2ffa-402e-b3f1-8573a195ad6f 8Gi RWO Delete Bound kube-system/redis-data-redis-test-replicas-0 nfs-provisioner 3d11h
    8. pvc-e1693689-b01b-4855-ab1c-b8f843be4e2e 8Gi RWO Delete Bound kube-system/redis-data-redis-test-replicas-2 nfs-provisioner 3d11h
    9. pvc-f9193155-776c-42f4-a3f5-71e75f16416f 8Gi RWO Delete Bound kube-system/redis-data-redis-test-master-0 nfs-provisioner 3d11

    那,我创建的nfs-pv-test这个pv就是使用的retain策略。

    如何更改策略呢?  重新kubectl  apply -f 示例文件就可以了 ,例如下面这样修改:

    1. [root@master mysql]# cat pv_mysql.yaml
    2. kind: PersistentVolume
    3. apiVersion: v1
    4. metadata:
    5. name: nfs-pv-test1
    6. spec:
    7. accessModes:
    8. - ReadWriteOnce
    9. capacity:
    10. storage: 1.5Gi
    11. persistentVolumeReclaimPolicy: Recycle
    12. storageClassName: nfs
    13. nfs:
    14. path: /data/nfs_sc/nfs-pv-test1
    15. server: 192.168.217.16

     

    1. [root@master mysql]# k apply -f pv_mysql.yaml
    2. The PersistentVolume "nfs-pv-test1" is invalid: spec.persistentVolumeReclaimPolicy: Unsupported value: "recycle": supported values: "Delete", "Recycle", "Retain"
    3. [root@master mysql]# vim pv_mysql.yaml
    4. [root@master mysql]# k apply -f pv_mysql.yaml
    5. persistentvolume/nfs-pv-test1 created

    The PersistentVolume "nfs-pv-test1" is invalid: spec.persistentVolumeReclaimPolicy: Unsupported value: "recycle": supported values: "Delete", "Recycle", "Retain"   这一段表示就三种策略,策略必须指定,没有默认的说法。

    1. [root@master mysql]# k get pv -A
    2. NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
    3. mysql-pv-test 1Gi RWO Retain Terminating database/mysql-pvc-test nfs-provisioner 35h
    4. nfs-pv-test 1536Mi RWO Retain Terminating database/nfs-pvc-test nfs 4h2m
    5. nfs-pv-test1 1536Mi RWO Recycle Available nfs 15s
    6. pvc-04203f8a-5907-48ce-9fc2-013e94313c3c 8Gi RWO Delete Bound kube-system/redis-data-redis-test-replicas-1 nfs-provisioner 3d11h
    7. pvc-751a32b6-8706-477b-8cad-d71e8e9f3ab8 256Mi RWO Delete Bound kube-system/redis nfs-provisioner 3d11h

     这里需要注意一点,pv名称是nfs-pv-test1,回收策略是Recycle,这里需要注意大小写。它和其它的pv 状态不同,其它的要么是bound,要么是Terminating ,而这个是available,因为这个pv还没有绑定到任何pvc。而Terminating 表示这个pv已经结束使命了,因为,我用了默认的StorageClass,pod已经起来了,pv的生命周期也就结束了(没有继续bound 绑定的意义了)。

    另外,如果资源供应使用的是动态模式,即管理员没有预先定义PV,仅通过StorageClass交给系统自动完成PV的动态创建,那么PVC再设定Selector时,系统将无法为其供应任何存储资源。

    在启用动态供应模式的情况下,一旦用户删除了PVC,与之绑定的PV也将根据其默认的回收策略“Delete”被删除。如果需要保留PV(用户数据),则在动态绑定成功后,用户需要将系统自动生成PV的回收策略从“Delete”改成“Retain”。说人话就是,如果是使用的default 的StorageClass,那么,策略一定要定为retain。

    PV生命周期的各个阶段

    ◎ Available:可用状态,还未与某个PVC绑定。

    ◎ Bound:已与某个PVC绑定。

    ◎ Released:绑定的PVC已经删除,资源已释放,但没有被集群回收。

    ◎ Failed:自动资源回收失败

    ◎Terminating:pv已经终结

     

    一般情况下,bound是表示正常的,如果使用了default的StorageClass,那么,pv由于是StorageClass自动启停管理的,因此,Terminating 也是表示正常的。

    6、

    挂载参数(Mount Options)

    在将PV挂载到一个Node上时,根据后端存储的特点,可能需要设置额外的挂载参数,可根据PV定义中的mountOptions字段进行设置。本例中没有用到。


     

    (2)pvc

    pvc=PersistentVolumeClaim,也是一个缩写,中文意思持久存储需求清单

    PVC是用户对存储资源的一个“申请”,就像Pod消费Node资源一样,PVC能够消费PV资源。PVC可以申请特定的存储空间和访问模式。

    示例:

    1. [root@master mysql]# cat pvc_mysql.yaml
    2. kind: PersistentVolumeClaim
    3. apiVersion: v1
    4. metadata:
    5. name: nfs-pvc-test
    6. namespace: database
    7. spec:
    8. accessModes:
    9. - ReadWriteOnce
    10. resources:
    11. requests:
    12. storage: 1.5Gi
    13. storageClassName: nfs

    kubectl apply -f  pvc_mysql.yaml就可以创建这个名叫nfs-pvc-test的pvc。

    1. [root@master mysql]# k get pvc -A
    2. NAMESPACE NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
    3. database mysql-pvc-test Bound mysql-pv-test 1Gi RWO nfs-provisioner 35h
    4. database nfs-pvc-test Bound nfs-pv-test 1536Mi RWO nfs 4h35m

    可以看到,pvc和命名空间有关了,也自动绑定了nfs-pv-test这个pv了。最后面也提示了使用了StorageClass  ,名称叫nfs。

    关键配置

    1、资源请求(Resources)

    描述对存储资源的请求,目前仅支持request.storage的设置,即是存储空间的大小,本例没有配置

    2、访问模式(AccessModes)

    用于描述对存储资源的访问权限,与PV设置相同,本例仍然配置的是once

    3、存储卷模式(Volume Modes)

    用于描述希望使用的PV存储卷模式,包括文件系统和块设备。本例使用的是默认,仍然是filesystem

    4、PV选择条件(Selector)

    通过对Label Selector的设置,可使PVC对于系统中已存在的各种PV进行筛选。

    选择条件可以使用matchLabels和matchExpressions进行设置,如果两个字段都设置了,则Selector的逻辑将是两组条件同时满足才能完成匹配

    本例没有配置

    5、存储类别(Class)

    PVC 在定义时可以设定需要的后端存储的类别(通过storageClassName字段指定),以减少对后端存储特性的详细信息的依赖。只有设置了该Class的PV才能被系统选出,并与该PVC进行绑定

    PVC也可以不设置Class需求。如果storageClassName字段的值被设置为空(storageClassName=""),则表示该PVC不要求特定的Class,系统将只选择未设定Class的PV与之匹配和绑定。PVC也可以完全不设置storageClassName字段,此时将根据系统是否启用了名为DefaultStorageClass的admission controller进行相应的操作

    本例配置了StorageClass,并且使用的是default。

    6、未启用DefaultStorageClass

    等效于PVC设置storageClassName的值为空(storageClassName=""),即只能选择未设定Class的PV与之匹配和绑定。

    本例中可以指定为非default,比如nfs-sc

    1. [root@master nfs-sc]# k get sc
    2. NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
    3. mynfs mynfs Delete Immediate true 4h57m
    4. nfs (default) nfs Delete Immediate true 4h59m
    5. nfs-provisioner choerodon.io/nfs-client-provisioner Delete Immediate false 3d21h
    6. nfs-sc storage.pri/nfs Delete Immediate true 5h45m

    二、什么时候需要使用StorageClass

    1.关键配置

    StorageClass作为对存储资源的抽象定义,对用户设置的PVC申请屏蔽后端存储的细节,一方面减少了用户对存储资源细节的关注,另一方面减少了管理员手工管理PV的工作,由系统自动完成PV的创建和绑定,实现了动态的资源供应。

    StorageClass的定义主要包括名称、后端存储的提供者(privisioner)和后端存储的相关参数配置。StorageClass一旦被创建,就无法修改,如需修改,只能删除重建。例如,生成一个全新的StorageClass:

    1. [root@master nfs-sc]# cat storageclass-nfs.yaml
    2. apiVersion: storage.k8s.io/v1
    3. kind: StorageClass
    4. metadata:
    5. name: mynfs
    6. provisioner: mynfs
    7. reclaimPolicy: Delete
    8. allowVolumeExpansion: True #允许pvc创建后扩容

    关键配置

    1、提供者(Privisioner)

    描述存储资源的提供者,也可以看作后端存储驱动。

    2、参数(Parameters)

    后端存储资源提供者的参数设置,不同的Provisioner包括不同的参数设置。某些参数可以不显示设定,Provisioner将使用其默认值。本例使用的是默认配置,没有使用参数。一般也不需要设置参数。

    3,allowVolumeExpansion: True  #允许pvc创建后扩容

    如果你不确定存储空间是否够用(比如,nfs),请设置为true。

    4,reclaimPolicy: Delete 这里还是看自己的需求,delete基本够用,如果对数据比较在意,那么就retain。

     

    2.设置默认的StorageClass

    例如,我现有4个StorageClass,通过k get sc -A 命令查出来的:

    1. [root@master nfs-sc]# k get sc -A
    2. NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
    3. mynfs mynfs Delete Immediate true 5h13m
    4. nfs (default) nfs Delete Immediate true 5h15m
    5. nfs-provisioner choerodon.io/nfs-client-provisioner Delete Immediate false 3d21h
    6. nfs-sc storage.pri/nfs Delete Immediate true 6h

    那么,我想设定nfs-sc这个是默认的default,怎么设定呢?

    kubectl patch storageclass nfs-sc -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'

    再次查询:

    1. [root@master nfs-sc]# k get sc -A
    2. NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
    3. mynfs mynfs Delete Immediate true 5h16m
    4. nfs (default) nfs Delete Immediate true 5h17m
    5. nfs-provisioner choerodon.io/nfs-client-provisioner Delete Immediate false 3d21h
    6. nfs-sc (default) storage.pri/nfs Delete Immediate true 6h3m

     这个就不行了,两个default,那么,以后使用肯定会有各种问题了(k8s不知道到底用哪个了嘛),把nfs(default)去掉default,简单:

    kubectl patch storageclass nfs -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"false"}}}'

    再次查询,就达到目的了:

    1. [root@master nfs-sc]# k get sc -A
    2. NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
    3. mynfs mynfs Delete Immediate true 5h18m
    4. nfs nfs Delete Immediate true 5h20m
    5. nfs-provisioner choerodon.io/nfs-client-provisioner Delete Immediate false 3d21h
    6. nfs-sc (default) storage.pri/nfs Delete Immediate true 6h6m

     

     


    总结

    pv,pvc和StorageClass三者的关系是比较紧密的,但还有一些运行规则需要重点提示:

    (1)资源供应

    k8s支持两种资源的供应模式:静态模式(Static)和动态模式(Dynamic)。资源供应的结果就是创建好的PV。

    静态模式:集群管理员手工创建许多PV,在定义PV时需要将后端存储的特性进行设置。

    动态模式:集群管理员无需手工创建PV,而是通过StorageClass的设置对后端存储进行描述,标记为某种类型。此时要求PVC对存储的类型进行声明,系统将自动完成PV的创建及与PVC的绑定。PVC可以声明Class为"",说明该PVC禁止使用动态模式。

    (2)资源绑定

    在定义好PVC之后,系统将根据PVC对存储资源的要求(存储空间和访问模式)在已存在的PV中选择一个满足PVC要求的PV,一旦找到,就将该PV与定义的PVC进行绑定,应用就可以使用这个PVC了。如果系统中没有这个PV,则PVC则会一直处理Pending状态,直到系统中有符合条件的PV。PV一旦绑定到PVC上,就会被PVC独占,不能再与其他PVC进行绑定。当PVC申请的存储空间比PV的少时,整个PV的空间就都能够为PVC所用,可能会造成资源的浪费。如果资源供应使用的是动态模式,则系统在为PVC找到合适的StorageClass后,将自动创建一个PV并完成与PVC的绑定。

    (3)资源使用

    Pod使用Volume定义,将PVC挂载到容器内的某个路径进行使用。Volume的类型为Persistent VolumeClaim,在容器挂载了一个PVC后,就能被持续独占使用。多个Pod可以挂载到同一个PVC上。

    1. volumes:
    2. - name: pv
    3. persistentVolumeClaim:
    4. claimName: pvc

    (4)资源释放

    当存储资源使用完毕后,可以删除PVC,与该PVC绑定的PV会被标记为“已释放”,但还不能立刻与其他PVC进行绑定。通过之前PVC写入的数据可能还被保留在存储设备上,只有在清除之后该PV才能被再次使用。

    (5)资源回收

    对于PV,管理员可以设定回收策略,用于设置与之绑定的PVC释放资源之后如何处理遗留数据的问题。只有PV的存储空间完成回收,才能供新的PVC绑定和使用。

    在静态资源供应模式下,通过PV和PVC完成绑定,并供Pod使用的存储管理机制

    在动态资源供应模式下,通过StorageClass和PVC完成资源动态绑定(系统自动生成PV),并供Pod使用的存储管理机制。

    (6)

    如果,启用DefaultStorageClass要求集群管理员已定义默认的StorageClass。如果在系统中不存在默认StorageClass,则等效于不启用DefaultStorageClass的情况。如果存在默认的StorageClass,则系统将自动为PVC创建一个PV(使用默认StorageClass的后端存储),并将它们进行绑定。集群管理员设置默认StorageClass的方法见总结的上面一点,如果管理员将多个StorageClass都定义为default,则由于不唯一,系统将无法为PVC创建相应的PV。

    (7)未启用DefaultStorageClass

    等效于PVC设置storageClassName的值为空(storageClassName=""),即只能选择未设定Class的PV与之匹配和绑定。



    这些规则非常重要,也比较绕口,需要仔细的多加实践,从而对k8s有一个正确的认识。

  • 相关阅读:
    《Effective Java》知识点(4)--泛型
    ARP欺骗攻击
    AI的安全应该由谁来保障?Sam Altman和Geoffrey Hinton观点激辩
    登录安全分析报告:小米官网注册
    一些 protobuf 的复盘(一)—— C++写完后的验证
    数据结构与算法3-数组
    C/C++语言100题练习计划 98——最长最短单词
    Cplex求解教程(基于OPL语言,可作为大规模运算输入参考)
    前端程序员接私活,直呼赚麻了
    2022 年最新【Java 经典面试 800 题】面试必备,查漏补缺;多线程 +spring+JVM 调优 + 分布式 +redis+ 算法
  • 原文地址:https://blog.csdn.net/alwaysbefine/article/details/125621826