存储类storageclass

尽管PersistentVolumeClaimpvc) 允许用户消耗抽象的存储资源, 常见的情况是针对不同的问题用户需要的是具有不同属性(如,性能PersistentVolume卷。 集群管理员需要能够提供不同性质PersistentVolume, 并且这些PV卷之间的差别不仅限于卷大小访问模式,同时又不能卷是如何实现的这些细节暴露给用户。 为了满足这类需求,就有了存储类StorageClass资源

存储类的作用

一、定义存储特性

StorageClass管理员提供了一种描述存储的方式,允许他们定义特定存储提供者(如AWS EBSAzure DiskGCE Persistent Disk等)、预配置策略(如备份策略加密)、IO性能访问模式等。这使得用户能够以抽象的方式使用这些存储,而无需关心后端存储的具体实现细节。

二、动态卷供应

当用户在创建持久卷声明PersistentVolumeClaimPVC)时,只需要指定StorageClassNameKubernetes即可根据这个StorageClass自动创建持久卷PersistentVolumePV)及底层存储。这大大减少手动创建并维护PV工作量提高存储管理灵活性效率

三、管理多种存储类型

Kubernetes集群中,可能需要连接到不同类型存储,如SSDHDD等。StorageClass可以帮助管理这些存储选项,通过定义不同StorageClass来区分不同类型存储,从而满足应用程序存储性能容量等方面的不同需求

四、抽象存储细节

通过使用StorageClass,用户不需要了解后端存储的具体实现细节,只需要知道不同StorageClass名称及其提供存储类型性能。这使得存储管理更加简单直观,同时也提高了系统的可扩展性可维护性

五、支持存储扩展和回收策略

StorageClass还支持存储卷扩展回收策略配置。例如,可以设置是否允许卷扩展,以及当PVC被删除PV回收策略(如DeleteRetain)。这些配置使得存储管理更加灵活可控

六、应用场景

StorageClassKubernetes中的应用场景非常广泛,特别是在需要持久化存储应用程序中。例如,在部署需要存储数据集群时(如Elasticsearch集群),每个节点都需要存储数据,而传统PV只能挂载一个Pod上。通过定义StorageClass并配合StatefulSet控制器,可以为每个状态Pod自动创建PVC并进行挂载,从而实现数据的持久化存储

StorageClass说明

  • StorageClass管理员提供了描述存储类的方法。不同的类型可能会映射不同服务质量等级备份策略,或是由集群管理员制定的任意策略Kubernetes本身并不清楚各种类代表的什么
  • Kubernetes存储类概念类似于一些其他存储系统设计中的"配置文件"
  • 每个StorageClass都包含provisionerparametersreclaimPolicy字段, 这些字段会在StorageClass动态制备PersistentVolume以满足PersistentVolumeClaim (PVC) 时使用到
  • StorageClass对象命名很重要,用户使用这个命名来请求生成一个特定的类。 当创建StorageClass对象时,管理员设置StorageClass对象命名其他参数

默认StorageClass

  • 可以将某个StorageClass标记为集群默认存储类。当一个PVC没有指定storageClassName时,会使用默认的StorageClass。如果在集群中的多个StorageClass上将storageclass.kubernetes.io/is-default-class注解设置为true,然后创建一个未设置storageClassNamePersistentVolumeClaim (PVC),Kubernetes将使用最近创建的默认StorageClass
  • 可以在创建新的PVC时不指定storageClassName,即使在集群中没有默认StorageClass情况下也可以这样做。 在这种情况下,新的PVC会按照定义的方式进行创建,并且该PVCstorageClassName将保持 不设置, 直到有可用默认StorageClass为止
  • 可以拥有一个没有任何默认StorageClass集群。 如果集群中没有StorageClass标记为默认(例如,云服务提供商还没有为你设置默认值),那么Kubernetes无法为需要StorageClassPersistentVolumeClaim应用默认值
  • 默认StorageClass变得可用时,控制平面会查找所有设置storageClassName的现有PVC。 对于那些storageClassName值为没有此键PVC控制平面更新它们, 将storageClassName设置为匹配新的默认StorageClass。但是如果有一个现成的PVC,其storageClassName"", 并且之前就已经配置了默认的StorageClass,那么该PVC将不会被更新
  • 默认StorageClass存在时,为了继续绑定到storageClassName""PV, 需要将关联PVCstorageClassName设置为 ""

StorageClass的属性

属性说明:https://kubernetes.io/zh/docs/concepts/storage/storage-classes/

  • Provisioner存储制备器):用来决定使用哪个卷插件制备PV,该字段必须指定。可以指定内部分配器,也可以指定外部分配器外部分配器代码地址为: kubernetes-incubator/external-storage,其中包括NFSCeph
  • Reclaim Policy回收策略):通过reclaimPolicy字段指定创建的Persistent Volume回收策略回收策略包括:Delete或者Retain没有指定默认为Delete

存储制备器

  • 每个StorageClass都有一个制备器Provisioner),用来决定使用哪个卷插件制备PV该字段必须指定

在这里插入图片描述

  • 除了"内置" 制备器(其名称前缀为"kubernetes.io"并打包在Kubernetes中)。还可以运行和指定外部制备器,这些独立的程序遵循由Kubernetes定义的规范外部供应商作者完全可以自由决定他们的代码保存于何处、打包方式、运行方式、使用的插件(包括Flex)等。代码仓库kubernetes-sigs/sig-storage-lib-external-provisioner包含一个用于为外部制备器编写功能实现类库。可以访问代码仓库kubernetes-sigs/sig-storage-lib-external-provisioner了解外部驱动列表
  • 例如NFS没有内部制备器,但可以使用外部制备器。也有第三方存储供应商提供自己的外部制备器

存储制备器NFS Client Provisioner

  • 源码地址https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner
  • NFS Client Provisioner是一个automatic provisioner,使用NFS作为存储自动创建PV对应PVCk8s本身不提供NFS存储,需要外部先有一套NFS存储服务
  • PV${namespace}-${pvcName}-${pvName}命名格式提供(在NFS服务器上)
  • PV回收的时候,如果设置的回收策略保留,则会以archieved-${namespace}-${pvcName}-${pvName}命名格式NFS服务器上进行打包

什么是卷插件

KubernetesK8s)中,卷插件Volume Plugins)是K8s存储系统重要组成部分,它们允许用户将外部存储系统特定类型存储卷集成到K8s集群中,从而实现数据持久化存储管理。以下是对K8s卷插件详细解析

一、卷插件的作用

卷插件主要用于扩展K8s存储功能,使其能够支持多种不同存储后端,如网络存储、本地存储、云存储等。通过卷插件,用户可以将这些存储后端挂载到Pod中,从而实现数据持久化存储共享

二、卷插件的类型

K8s支持多种类型卷插件,包括但不限于以下几种:

  1. EmptyDir:一种临时目录,用于存储Pod中的临时数据。当Pod删除时,EmptyDir中的数据也会被删除
  2. HostPath:将节点上的文件系统目录挂载到Pod中。这种类型通常用于开发测试环境不推荐生产环境中使用。
  3. GCEPersistentDisk:Google Cloud Platform的持久化磁盘。
  4. AWSElasticBlockStore:Amazon Web Services的Elastic Block Store。
  5. NFS网络文件系统,允许Pod访问远程NFS服务器上的文件。
  6. CephFS:一种分布式文件系统,提供了高性能和可扩展性。
  7. Cinder:OpenStack的块存储服务。
  8. GlusterFS:一个开源的分布式文件系统,提供了高可用性、高扩展性和高性能。
  9. FlexVolume:一种通用卷插件,允许用户指定自定义的驱动程序来管理存储卷。
  10. CSI(Container Storage Interface):一种标准的存储接口,使得存储插件可以以容器的方式运行,并与K8s集群进行交互。CSI插件支持多种存储后端,并且具有更高的可扩展性和灵活性。

三、如何使用卷插件

使用K8s中的卷插件通常涉及以下几个步骤:

  1. 配置存储卷插件:首先,需要编写一个StorageClass定义文件,指定要使用的存储卷插件及其相关参数
  2. 创建存储卷声明PVC:然后,需要创建一个PersistentVolumeClaimPVC)来请求存储卷PVC指定存储卷访问模式大小以及要使用的StorageClass名称K8s会根据PVC中的请求自动找到合适的存储卷并绑定到PVC上。
  3. 创建Pod并挂载存储卷:最后,可以创建一个Pod来挂载PVC中的存储卷。在Pod的定义文件中,需要指定要挂载存储卷名称以及挂载路径。当Pod被创建时,K8s自动PVC绑定到的存储卷挂载到指定的路径上

部署NFS Client Provisioner存储分配器

创建sa并授权

[root@k8s-master volume]# vim rbac.yml
apiVersion: v1    #Kubernetes API的版本,这里是v1
kind: Namespace   #创建的资源类型是Namespace
metadata:   #namespace的元数据
  name: nfs-client-provisioner   #创建的命名空间的名称,这里被命名为nfs-client-provisioner。命名空间的名称在集群内必须是唯一的
#这个配置的作用是在Kubernetes集群中创建一个名为nfs-client-provisioner的新命名空间

---
apiVersion: v1   
kind: ServiceAccount  #资源类型是ServiceAccount
metadata:     #ServiceAccount的元数据
  name: nfs-client-provisioner   #ServiceAccount的名称
  namespace: nfs-client-provisioner   #指定了ServiceAccount所属的命名空间
#这段配置创建了一个名为nfs-client-provisioner的ServiceAccount,它位于名为nfs-client-provisioner的命名空间中

---
apiVersion: rbac.authorization.k8s.io/v1  #API版本是rbac.authorization.k8s.io/v1,这是rbac相关资源(如Role、ClusterRole、RoleBinding、ClusterRoleBinding等)的API版本
kind: ClusterRole    #Kubernetes资源类型是ClusterRole
metadata:   #ClusterRole的元数据
  name: nfs-client-provisioner-runner   #ClusterRole的名称
rules:   #ClusterRole的权限规则
  - apiGroups: [""]    #第一条规则允许对nodes资源进行get、list和watch操作
    resources: ["nodes"]
    verbs: ["get", "list", "watch"]
  - apiGroups: [""]   #第二条规则允许对persistentvolumes资源进行get、list、watch、create和delete操作
    resources: ["persistentvolumes"]
    verbs: ["get", "list", "watch", "create", "delete"]
  - apiGroups: [""]   #第三条规则允许对persistentvolumeclaims资源进行get、list、watch和update操作
    resources: ["persistentvolumeclaims"]
    verbs: ["get", "list", "watch", "update"]
  - apiGroups: ["storage.k8s.io"]   #第四条规则允许对storageclasses资源进行get、list和watch操作
    resources: ["storageclasses"] 
    verbs: ["get", "list", "watch"]
  - apiGroups: [""]    #第五条规则允许对events资源进行create、update和patch操作
    resources: ["events"]
    verbs: ["create", "update", "patch"]
#这个ClusterRole为nfs-client-provisioner提供了必要的权限来动态地管理NFS存储卷,包括创建、删除持久卷,响应持久卷请求,以及记录相关事件

---
apiVersion: rbac.authorization.k8s.io/v1   #API版本是rbac.authorization.k8s.io/v1,这是rbac相关资源(如Role、ClusterRole、RoleBinding、ClusterRoleBinding等)的API版本
kind: ClusterRoleBinding   #这是RBAC相关资源(如Role、ClusterRole、RoleBinding、ClusterRoleBinding等)的API版本
metadata:   #ClusterRoleBinding的元数据
  name: run-nfs-client-provisioner   #ClusterRoleBinding的名称
subjects:  #ClusterRoleBinding的主体列表,即哪些用户、组或服务账户将被授予ClusterRole的权限
  - kind: ServiceAccount    #主体的类型是ServiceAccount
    name: nfs-client-provisioner    #ServiceAccount的名称,与之前定义的ServiceAccount名称一致
    namespace: nfs-client-provisioner  #ServiceAccount所在的命名空间
roleRef:   #定义了ClusterRoleBinding引用的ClusterRole
  kind: ClusterRole   #指明引用的资源类型是ClusterRole
  name: nfs-client-provisioner-runner   #ClusterRole的名称,与之前定义的ClusterRole名称一致
  apiGroup: rbac.authorization.k8s.io    #API组,对于ClusterRole来说,这个值通常是rbac.authorization.k8s.io
#这个ClusterRoleBinding将nfs-client-provisioner-runner ClusterRole的权限授予了nfs-client-provisioner ServiceAccount


---
apiVersion: rbac.authorization.k8s.io/v1   #API版本是rbac.authorization.k8s.io/v1,这是rbac相关资源(如Role、ClusterRole、RoleBinding、ClusterRoleBinding等)的API版本
kind: Role   #表示定义的对象类型是一个角色(Role)。角色是权限的集合,可以授予给特定的用户或服务账户
metadata:   #role角色的元数据
  name: leader-locking-nfs-client-provisioner  #角色的名称
  namespace: nfs-client-provisioner   #指定了角色所在的命名空间
rules:   #角色拥有的权限
  - apiGroups: [""]   #指定了API组。空字符串""表示核心组(Core Group)
    resources: ["endpoints"]   #指定了角色可以访问的资源类型,这里是endpoints。Endpoints资源用于存储服务(Service)的IP地址和端口号
    verbs: ["get", "list", "watch", "create", "update", "patch"]  #列出了角色可以对指定的资源执行的操作。在这个例子中,角色可以执行get(获取)、list(列出)、watch(监听变化)、create(创建)、update(更新)和patch(部分更新)操作
---
apiVersion: rbac.authorization.k8s.io/v1   #API版本是rbac.authorization.k8s.io/v1,这是rbac相关资源(如Role、ClusterRole、RoleBinding、ClusterRoleBinding等)的API版本
kind: RoleBinding   #RoleBinding资源。RoleBinding用于将角色(Role)或集群角色(ClusterRole)绑定到一个或多个主体(subject),这些主体通常是用户(User)、组(Group)或服务账户(ServiceAccount)
metadata:   #RoleBinding的元数据
  name: leader-locking-nfs-client-provisioner   #RoleBinding的名称
  namespace: nfs-client-provisioner   #RoleBinding所在的命名空间
subjects:   #RoleBinding绑定到的主体列表
  - kind: ServiceAccount   #主体类型,这里是服务账户(ServiceAccount)
    name: nfs-client-provisioner   #服务账户的名称,这里是nfs-client-provisioner
    namespace: nfs-client-provisioner  #服务账户所在的命名空间,这里同样是nfs-client-provisioner
roleRef:    #RoleBinding引用的角色
  kind: Role   #角色类型,这里是Role
  name: leader-locking-nfs-client-provisioner   #角色的名称,这里与RoleBinding的名称相同,即leader-locking-nfs-client-provisioner
  apiGroup: rbac.authorization.k8s.io  #API组,这里是RBAC的API组
[root@k8s-master volume]# kubectl apply -f rbac.yml
namespace/nfs-client-provisioner created
serviceaccount/nfs-client-provisioner created
clusterrole.rbac.authorization.k8s.io/nfs-client-provisioner-runner created
clusterrolebinding.rbac.authorization.k8s.io/run-nfs-client-provisioner created
role.rbac.authorization.k8s.io/leader-locking-nfs-client-provisioner created
rolebinding.rbac.authorization.k8s.io/leader-locking-nfs-client-provisioner created
[root@k8s-master volume]# kubectl -n nfs-client-provisioner get sa
NAME                     SECRETS   AGE
default                  0         27s
nfs-client-provisioner   0         27s
[root@k8s-master volume]# vim deployment.yml
apiVersion: apps/v1   #API版本是apps/v1
kind: Deployment    #Deployment资源
metadata:   #Deployment的元数据
  name: nfs-client-provisioner  #Deployment的名称
  labels:
    app: nfs-client-provisioner    #标签app: nfs-client-provisioner
  namespace: nfs-client-provisioner   #Deployment所在的命名空间,这里是nfs-client-provisioner
spec:    #Deployment的规格
  replicas: 1   #Pod的副本数量为1
  strategy:   #Pod的更新策略
    type: Recreate   #更新策略类型为重建(Recreate),即先销毁旧的Pod,再创建新的Pod
  selector:  #Pod的选择器,用于匹配哪些Pod属于这个Deployment
    matchLabels:
      app: nfs-client-provisioner   #匹配标签app: nfs-client-provisioner
  template:   #Pod的模板
    metadata:  #Pod的元数据
      labels:
        app: nfs-client-provisioner   #Pod定义标签
    spec:   #Pod的规格
      serviceAccountName: nfs-client-provisioner   #指定Pod使用的服务账户(ServiceAccount)名称,这里是nfs-client-provisioner
      containers:    #Pod中的容器列表
        - name: nfs-client-provisioner
          image: sig-storage/nfs-subdir-external-provisioner:v4.0.2
          volumeMounts:  #容器挂载的卷列表
            - name: nfs-client-root  #挂载的卷名称,这里与后面定义的卷名称对应
              mountPath: /persistentvolumes   #挂载路径,即容器内的路径
          env:   #容器的环境变量列表
            - name: PROVISIONER_NAME     
              value: k8s-sigs.io/nfs-subdir-external-provisioner   #NFS存储卷配置器的名称,这里是k8s-sigs.io/nfs-subdir-external-provisioner
            - name: NFS_SERVER
              value: 172.25.254.250   #NFS服务器的IP地址,这里是172.25.254.250
            - name: NFS_PATH  
              value: /nfsdata   #NFS服务器上存储数据的路径,这里是/nfsdata 
      volumes:   #Pod中的卷列表
        - name: nfs-client-root  #卷的名称,这里与前面容器挂载的卷名称对应
          nfs:   #NFS类型的卷
            server: 172.25.254.250   #NFS服务器的IP地址
            path: /nfsdata  #NFS服务器上存储数据的路径
#这个Deployment将部署一个Pod,该Pod运行NFS客户端动态存储卷配置器,它使用指定的NFS服务器和路径来动态地为Kubernetes集群提供存储卷。通过配置环境变量,NFS客户端动态存储卷配置器知道如何注册到Kubernetes集群中,并响应存储卷的创建和删除请求

在这里插入图片描述
在这里插入图片描述

  • nfs-subdir-external-provisioner存储类用到的外部插件
[root@k8s-master volume]# docker load -i nfs-subdir-external-provisioner-4.0.2.tar

[root@k8s-master volume]# docker tag registry.k8s.io/sig-storage/nfs-subdir-external-provisioner:v4.0.2 harbor.huazi.org/sig-storage/nfs-subdir-external-provisioner:v4.0.2
[root@k8s-master volume]# docker push harbor.huazi.org/sig-storage/nfs-subdir-external-provisioner:v4.0.2
[root@k8s-master volume]# kubectl apply -f deployment.yml
deployment.apps/nfs-client-provisioner created
[root@k8s-master volume]# kubectl -n nfs-client-provisioner get deployments.apps
NAME                     READY   UP-TO-DATE   AVAILABLE   AGE
nfs-client-provisioner   1/1     1            1           27s

创建StorageClass存储类

[root@k8s-master volume]# vim class.yml
apiVersion: storage.k8s.io/v1  #API版本是storage.k8s.io/v1,这是StorageClass资源的稳定版本
kind: StorageClass   #指定这是一个StorageClass资源
metadata:   #StorageClass的元数据
  name: nfs-client   #StorageClass的名称
provisioner: k8s-sigs.io/nfs-subdir-external-provisioner   #指定了动态存储卷的提供者,这里是k8s-sigs.io/nfs-subdir-external-provisioner。这意味着当需要创建新的存储卷时,Kubernetes将调用这个NFS客户端动态存储卷配置器来创建
parameters:   #这是一个可选字段,用于向存储卷提供者传递额外的配置参数
  archiveOnDelete: "false"   #这个参数告诉NFS客户端动态存储卷配置器,在删除PVC(PersistentVolumeClaim)时,是否应该将对应的NFS子目录归档(或保留)。这里设置为"false",意味着当PVC被删除时,对应的NFS子目录也会被删除
[root@k8s-master volume]# kubectl apply -f class.yml
storageclass.storage.k8s.io/nfs-client created
#StorageClass的缩写sc
[root@k8s-master volume]# kubectl get sc
NAME         PROVISIONER                                   RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
nfs-client   k8s-sigs.io/nfs-subdir-external-provisioner   Delete          Immediate           false                  34s

创建pvc

[root@k8s-master volume]# vim pvc.yml
apiVersion: v1  #API版本是v1
kind: PersistentVolumeClaim   #PersistentVolumeClaim资源
metadata:  #PVC的元数据
  name: test-claim   #PVC的名称
spec:   #PVC的规格
  storageClassName: nfs-client  #指定了这个PVC应该使用的StorageClass的名称,这里是nfs-client。这意味着Kubernetes将使用这个StorageClass的配置来动态地创建一个满足PVC要求的PersistentVolume(PV)
  accessModes:   #PVC的访问模式列表
    - ReadWriteMany   #多点读写
  resources:   #PVC请求的存储资源
    requests:   #请求的存储大小和类型
      storage: 1G   #请求的存储大小为1GB
#创建这个PVC后,Kubernetes将查找一个匹配的StorageClass(在这个例子中是nfs-client),并根据PVC的规格和请求的参数动态地创建一个PersistentVolume(PV)。一旦PV被成功创建并绑定到PVC上,用户就可以在Pod中使用这个PVC来访问存储资源了
[root@k8s-master volume]# kubectl apply -f pvc.yml
persistentvolumeclaim/test-claim created
[root@k8s-master volume]# kubectl get pvc
NAME         STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   VOLUMEATTRIBUTESCLASS   AGE
test-claim   Bound    pvc-a164d606-732f-4005-a6a6-4798fdbc75f4   1G         RWX            nfs-client     <unset>                 90s
#在nfs服务器上可以看到
[root@harbor ~]# cd /nfsdata/
[root@harbor nfsdata]# ls
default-test-claim-pvc-a164d606-732f-4005-a6a6-4798fdbc75f4
#当我们删掉pvc后
[root@k8s-master volume]# kubectl delete -f pvc.yml
persistentvolumeclaim "test-claim" deleted

#再查看nfs服务器,发现pv已经被自动删除了
[root@harbor nfsdata]# ls
[root@harbor nfsdata]#
[root@k8s-master volume]# kubectl apply -f pvc.yml
persistentvolumeclaim/test-claim created

创建测试pod

[root@k8s-master volume]# vim pod.yml
apiVersion: v1   #API版本是v1
kind: Pod   #指定这是一个Pod资源
metadata:   #Pod的元数据
  name: test-pod   #Pod的名称,这里是test-pod
spec:   #Pod的规格
  containers:
  - name: test-pod
    image: busybox
    command:   #容器启动时执行的命令
      - "/bin/sh"
    args:
      - "-c"  #容器将执行/bin/sh -c "touch /mnt/SUCCESS && exit 0 || exit 1",这个命令会在/mnt目录下创建一个名为SUCCESS的文件,如果成功则退出状态码为0,否则为1
      - "touch /mnt/SUCCESS && exit 0 || exit 1"   
    volumeMounts:   #容器内挂载的卷列表
      - name: nfs-pvc   #挂载的卷的名称,与Pod规格中的volumes部分定义的卷名称相对应
        mountPath: "/mnt"   #卷在容器内的挂载路径
  restartPolicy: "Never"   #Pod的重启策略。在这个例子中,如果容器退出,Pod将不会被重启
  volumes:   #Pod中使用的卷列表
    - name: nfs-pvc   #卷的名称,与volumeMounts中引用的名称相对应
      persistentVolumeClaim:   #指定这个卷是一个PersistentVolumeClaim
        claimName: test-claim   #PVC的名称
#创建这个Pod后,Kubernetes将尝试找到名为test-claim的PVC,并查找与之绑定的PersistentVolume(PV)。一旦找到了匹配的PV,Pod中的容器就可以通过/mnt路径访问这个NFS存储卷了。容器将尝试在/mnt目录下创建一个名为SUCCESS的文件,如果成功,Pod将正常退出(状态码0),否则将异常退出(非0状态码)
[root@k8s-master volume]# kubectl apply -f pod.yml
pod/test-pod created
[root@k8s-master volume]# kubectl get pods -o wide
NAME       READY   STATUS      RESTARTS   AGE   IP            NODE            NOMINATED NODE   READINESS GATES
test-pod   0/1     Completed   0          38s   10.244.2.38   k8s-node2.org   <none>           <none>
[root@harbor nfsdata]# ls
default-test-claim-pvc-4460dd22-b4d8-4192-b249-3b687dacdf39
[root@harbor nfsdata]# cd default-test-claim-pvc-4460dd22-b4d8-4192-b249-3b687dacdf39/
[root@harbor default-test-claim-pvc-4460dd22-b4d8-4192-b249-3b687dacdf39]# ls
SUCCESS
[root@harbor default-test-claim-pvc-4460dd22-b4d8-4192-b249-3b687dacdf39]# ll
总用量 0
-rw-r--r-- 1 root root 0 114 22:36 SUCCESS

pod--->pvc--->pv--->storageclass

设置默认的存储类

更多推荐