持久化存储 StorageClass

2023年 5月 4日 32.5k 0

上面文章我们创建的pv和pvc都是静态的,简单的来说静态的pv和pvc需要我们手动的创建,这种情况很大程度上并不能满足我们的需求,比如我们有一个应用需要对存储的并发度要求比较高,而另外一个应用对读写速度又要求比较高,特别是对于StatefulSet类型的应用。使用静态PV就很不合时了,这里就需要使用StorageClass

Kubernetes从v1.4版本开始引入了一个新的资源对象StorageClass,用于标记存储资源的特性和性能。到v1.6版本时,StorageClass和动态资源供应的机制得到了完善,实现了存储卷的按需创建,在共享存储的自动化管理进程中能够实现了重要的一步。
通过StorageClass的定义,管理员可以将存储资源定义为某种类别(Class),正如存储设备对于自身的配置描述(Profile),例如 "快速存储" "慢速存储" "有数据冗余" "无数据冗余"等。用户根据StorageClass的描述就能够直观得知各种存储资源的特性,就可以根据应用对存储资源的需求去申请存储资源了。
StorageClass作为对存储资源的抽象定义,对用户设置的PVC申请屏蔽后端的细节,一方面减轻用户对于存储资源细节的关注,另一方面也减轻了管理员手工管理PV的工作,由系统自动完成PV的创建和绑定,实现了动态的资源供应。使用基于StorageClass的动态资源供应模式将逐步成为云平台的标准存储配置模式
StorageClass的定义主要包括名称、后端存储的提供者(Provisioner)和后端存储的相关参数配置。StorageClass一旦被创建出来,将无法修改。如需修改,则只能删除原StorageClass的定义重建。
上面文章我们创建的pv和pvc都是静态的,简单的来说静态的pv和pvc需要我们手动的创建,这种情况很大程度上并不能满足我们的需求,比如我们有一个应用需要对存储的并发度要求比较高,而另外一个应用对读写速度又要求比较高,特别是对于StatefulSet类型的应用。使用静态PV就很不合时了,这里就需要使用StorageClass

创建Provisioner

如果需要使用StorageClass,我们就需要安装对应的自动配置程序,比如我们这里后端采用的是nfs,那么我们就需要使用到一个nfs-client的自动配置程序,我们也叫它Provisioner,这个程序使用我们已经配置好的nfs服务器,来自动创建持久卷,也就是自动帮我们创建PV
自动创建的PV以{namespace}-${pvcname}-${pvname}进行命名到服务器上
当pv被回收后会以archieved-${namespace}-${pvcname}-${pvname}格式存在服务器上
关于安装nfs这里不在介绍,需要的请点击下面的文章进行查看

Kubernetes PV与PVC

新闻联播老司机

  • 20年1月31日
  • 喜欢:0
  • 浏览:4.9k
  • 首先,我们需要配置nfs-client的Deployment文件

    #环境说明
    本次nfs服务器地址192.168.0.14
    数据存储目录 /data1/k8s-volume
    
    kind: Deployment
    apiVersion: apps/v1
    metadata:
      name: nfs-client-provisioner
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: nfs-client-provisioner
      strategy:
        type: Recreate
      template:
        metadata:
          labels:
            app: nfs-client-provisioner
        spec:
          serviceAccountName: nfs-client-provisioner
          containers:
            - name: nfs-client-provisioner
              image: quay.io/external_storage/nfs-client-provisioner:latest
              volumeMounts:
                - name: nfs-client-root
                  mountPath: /persistentvolumes
              env:
                - name: PROVISIONER_NAME
                  value: fuseim.pri/ifs
                - name: NFS_SERVER
                  value: 192.168.0.14           #nfs server 地址
                - name: NFS_PATH
                  value: /data1/k8s-volume     #nfs共享目录
          volumes:
            - name: nfs-client-root
              nfs:
                server: 192.168.0.14
                path: /data1/k8s-volume
    

    接下来我们还需要创建一个serveraccount,用于将nfs-client-provisioner中的ServiceAccount绑定到一个nfs-client-provisioner-runner的ClusterRole。而该ClusterRole声明了一些权限,其中就包括了对persistentvolumes的增删改查,所以我们就可以利用ServiceAccount来自动创建PV

    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: nfs-client-provisioner
    
    ---
    kind: ClusterRole
    apiVersion: rbac.authorization.k8s.io/v1
    metadata:
      name: nfs-client-provisioner-runner
    rules:
      - apiGroups: [""]
        resources: ["persistentvolumes"]
        verbs: ["get", "list", "watch", "create", "delete"]
      - apiGroups: [""]
        resources: ["persistentvolumeclaims"]
        verbs: ["get", "list", "watch", "update"]
      - apiGroups: ["storage.k8s.io"]
        resources: ["storageclasses"]
        verbs: ["get", "list", "watch"]
      - apiGroups: [""]
        resources: ["events"]
        verbs: ["list", "watch", "create", "update", "patch"]
      - apiGroups: [""]
        resources: ["endpoints"]
        verbs: ["create", "delete", "get", "list", "watch", "patch", "update"]
    
    ---
    kind: ClusterRoleBinding
    apiVersion: rbac.authorization.k8s.io/v1
    metadata:
      name: run-nfs-client-provisioner
    subjects:
      - kind: ServiceAccount
        name: nfs-client-provisioner
        namespace: default
    roleRef:
      kind: ClusterRole
      name: nfs-client-provisioner-runner
      apiGroup: rbac.authorization.k8s.io
    

    创建storageclass
    fuseim.pri/ifs 需要和deployment保持一直
    这里我们声明了一个名为managed-nfs-storage的Storageclass对象

    apiVersion: storage.k8s.io/v1
    kind: StorageClass
    metadata:
      name: managed-nfs-storage
    provisioner: fuseim.pri/ifs # or choose another name, must match deployment's env PROVISIONER_NAME'
    

    创建

    [root@k8s-01 nfs-client]# kubectl create -f .
    deployment.apps/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
    storageclass.storage.k8s.io/managed-nfs-storage created
    

    这里也可以直接参考nfs-client的官方文档 (里面有不同存储后端的文件)
    https://github.com/kubernetes-incubator/external-storage/tree/master/nfs-client/deploy
    接下来我们可以查看一下

    #Pod状态Running
    [root@k8s-01 nfs-client]# kubectl get pod
    NAME                                      READY   STATUS    RESTARTS   AGE
    nfs-client-provisioner-57cb5b4cfd-lhqpw   1/1     Running   0          61m
    
    #serveraccount也已经创建完成。
    [root@k8s-01 nfs-client]# kubectl get sc
    NAME                  PROVISIONER      AGE
    managed-nfs-storage   fuseim.pri/ifs   62m
    

    image_1e004vmm76btdru16ck1iq91g0c9.png-247.3kB
    接下来我们需要创建一个pvc,来引用刚刚创建的storageclass

    kind: PersistentVolumeClaim
    apiVersion: v1
    metadata:
      name: test-claim
      annotations:
        volume.beta.kubernetes.io/storage-class: "managed-nfs-storage"    #storageclass 名称
    spec:
      accessModes:              #访问模式
        - ReadWriteMany
      resources:
        requests:
          storage: 1024Mi              #请求数据大小
    
    
    #查看sc的名称可以使用kubectl get sc
    

    创建完成后我们可以查看一下pvc

    [root@k8s-01 nfs-client]# kubectl apply -f  nfs-pvc.yaml
    persistentvolumeclaim/test-claim created
    
    
    
    #这里可以看到一个名称为test-claim的pvc,自动帮我们创建了一个pv并绑定到当前的pvc上
    [root@k8s-01 nfs-client]# kubectl get pvc
    NAME         STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS          AGE
    pvc-nfs      Bound    pv1                                        10Gi       RWO                                  3h4m
    test-claim   Bound    pvc-72ecd497-44e0-11ea-b5f6-000c29eeccce   1Gi        RWX            managed-nfs-storage   37s
    
    #这里可以看到自动创建了一个pv
    [root@k8s-01 nfs-client]# kubectl get pv
    NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                STORAGECLASS          REASON   AGE
    pvc-72ecd497-44e0-11ea-b5f6-000c29eeccce   1Gi        RWX            Delete           Bound    default/test-claim   managed-nfs-storage            16m
    

    在默认情况下,我们创建一个pvc需要有一个状态为空闲的pv,然后才会绑定到pvc上。使用storageclass之后,我们不需要的手动创建pv,只需要创建一个pvc,storageclass会自动将pv给创建并且关联
    除了上面使用annotations参数指定storageclass的方式以外,还可以通过修改yaml或者或者通过patch的方式将storageclass设置为默认的存储。(如找不到指定的storageclass则会使用默认sc进行创建pv)

    ##1.通过命令的方式进行修改
    kubectl patch storageclass course-nfs-storage -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'
    
    #2.通过修改storageclass方式
    apiVersion: storage.k8s.io/v1
    kind: StorageClass
    metadata:
      name: managed-nfs-storage
      annotations:
        storageclass.kubernetes.io/is-default-class": "true"
    provisioner: fuseim.pri/ifs
    
    
    #提示: 如果我们有一个默认的sc,则不需要在pvc中声明sc的名称
    

    测试

    上面我们创建了nfs-client以及storageclass和pvc,现在我们后端存储已经做好了,接下来我们需要创建一个应用进行演示

    使用Deployment 引用PVC

    这里的Pod类型和Deployment使用方式是一样的,官方默认使用的是Pod这里就不变,修改为Deployment也是一样的格式

    kind: Pod
    apiVersion: v1
    metadata:
      name: test-pod                        #pod的名称
    spec:
      containers:
      - name: test-pod                      #容器的名称
        image: busybox
        imagePullPolicy: IfNotPresent
        command:                            #容器执行的命令
          - "/bin/sh"
        args:
          - "-c"
          - "touch /mnt/SUCCESS && exit 0 || exit 1"
        volumeMounts:
          - name: nfs-pvc                   #容器挂载点名称
            mountPath: "/mnt"               #容器挂载目录
      restartPolicy: "Never"
      volumes:
        - name: nfs-pvc                    #这里的名称要和上面容器挂载点的名称匹配
          persistentVolumeClaim:            #挂载使用pvc
            claimName: test-claim                   #pvc的名称
    

    我们在busybox创建一个SUCCESS的文件,同时将/mnt目录挂载到pvc中

    [root@k8s-01 nfs-client]# kubectl apply -f test.yaml
    pod/test-pod created
    
    [root@k8s-01 nfs-client]# kubectl get pod|grep test-pod
    test-pod                                  0/1     Completed   0          4m30s
    
    #在nfs存储目录就可以看到这个目录
    [root@k8s-01 nfs-client]# ls /data1/k8s/default-test-claim-pvc-72ecd497-44e0-11ea-b5f6-000c29eeccce/
    SUCCESS
    #前面说过,在storageclass中创建的存储,会以${namespace}-${pvc name}-${pv name}
    

    使用StatefulSet 引用Storageclass

    如果我们使用手动指定pvc的方式,当我们pod为多实例的时候,多个pod使用的是一个pvc。但是我们使用statefulset时,storageclass会为我们每一个Pod创建一个pv和pvc

    apiVersion: apps/v1beta1
    kind: StatefulSet
    metadata:
      name: storageclass-test
    spec:
      replicas: 3
      serviceName: "nginx"                      #使用statefulSet需要在配置文件中设置一个service的名称
      template:
        metadata:
          labels:
            app: sc-web
        spec:
          containers:
          - name: nginx
            images: nginx
            ports:
              - containerPort: 80
            volumeMounts:
            - name: nginx-test-pvc                   #挂载点名称 要和下面的关联
              mountPath: /usr/share/nginx/html      #容器挂载目录    
      volumeClaimTemplates:  #使用pvc的情况下就直接在下面创建一个volumes就可以,但是这里不使用pvc
        - metadata:       #这里的格式和我们创建pvc的格式是相同的
            name: nginx-test-pvc                    #pvc名称 要和上面的关联
            annotations:
              volume.beta.kubernetes.io/storage-class: "managed-nfs-storage"   #sc的名称
          spec:
              accessModes:                      #访问模式
                - ReadWriteMany
              resources:
                requests:
                  storage: 10Gi               #存储空间
    

    接下来我们创建查看pv和pvc并且查看一下nfs挂载目录的文件

    [root@k8s-01 nfs-client]# kubectl get pod
    NAME                                      READY   STATUS    RESTARTS   AGE
    nfs-client-provisioner-57cb5b4cfd-lhqpw   1/1     Running   0          169m
    
    storageclass-test-0                       1/1     Running   0          2m38s
    storageclass-test-1                       1/1     Running   0          2m16s
    storageclass-test-2                       1/1     Running   0          2m9s
    
    
    #当Pod状态为Running时,已经帮我们创建好pv和pvc并且相互绑定
    [root@k8s-01 nfs-client]# kubectl get pv
    NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                                        STORAGECLASS          REASON   AGE
    pv1                                        10Gi       RWO            Recycle          Bound    default/pvc-nfs                                                             4h33m
    pvc-72ecd497-44e0-11ea-b5f6-000c29eeccce   1Gi        RWX            Delete           Bound    default/test-claim                           managed-nfs-storage            89m
    pvc-81272745-44ec-11ea-b5f6-000c29eeccce   10Gi       RWX            Delete           Bound    default/nginx-test-pvc-storageclass-test-0   managed-nfs-storage            2m51s
    pvc-8dfe513e-44ec-11ea-b5f6-000c29eeccce   10Gi       RWX            Delete           Bound    default/nginx-test-pvc-storageclass-test-1   managed-nfs-storage            2m42s
    pvc-91f8193c-44ec-11ea-b5f6-000c29eeccce   10Gi       RWX            Delete           Bound    default/nginx-test-pvc-storageclass-test-2   managed-nfs-storage            2m21s
    
    
    [root@k8s-01 nfs-client]# kubectl get pvc
    NAME                                 STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS          AGE
    nginx-test-pvc-storageclass-test-0   Bound    pvc-81272745-44ec-11ea-b5f6-000c29eeccce   10Gi       RWX            managed-nfs-storage   3m16s
    nginx-test-pvc-storageclass-test-1   Bound    pvc-8dfe513e-44ec-11ea-b5f6-000c29eeccce   10Gi       RWX            managed-nfs-storage   2m54s
    nginx-test-pvc-storageclass-test-2   Bound    pvc-91f8193c-44ec-11ea-b5f6-000c29eeccce   10Gi       RWX            managed-nfs-storage   2m47s
    
    
    #同时按照storageclass的生成目录规则帮我们在nfs共享存储中创建好目录
    [root@k8s-01 nfs-client]# ll /data1/k8s/
    总用量 0
    drwxrwxrwx 2 root root  6 2月   1 20:15 default-nginx-test-pvc-storageclass-test-0-pvc-81272745-44ec-11ea-b5f6-000c29eeccce
    drwxrwxrwx 2 root root  6 2月   1 20:15 default-nginx-test-pvc-storageclass-test-1-pvc-8dfe513e-44ec-11ea-b5f6-000c29eeccce
    drwxrwxrwx 2 root root  6 2月   1 20:15 default-nginx-test-pvc-storageclass-test-2-pvc-91f8193c-44ec-11ea-b5f6-000c29eeccce
    

    扩展资料
    在Deployment中,与之对应的服务是service,而在StatefulSet中与之对应的headless service,headless service,即无头服务,与service的区别就是它没有Cluster IP,解析它的名称时将返回该Headless Service对应的全部Pod的Endpoint列表。
    除此之外,StatefulSet在Headless Service的基础上又为StatefulSet控制的每个Pod副本创建了一个DNS域名,这个域名的格式为:

    $(podname).(headless server name)   
    FQDN: $(podname).(headless server name).namespace.svc.cluster.local
    
    #Headless Service,名为nginx,用来定义Pod网络标识(DNS domain)
    扩展资料http://www.mamicode.com/info-detail-2368542.html
    

    如果不是使用NFS,使用其他如ceph等,依旧可以参考nfs-client的官方文档
    https://github.com/kubernetes-incubator/external-storage

    相关文章:

    1. Kubernetes 1.14 二进制集群安装
    2. Prometheus Operator 持久化存储
    3. CentOS 7 ETCD集群配置大全
    4. Kubernetes PV与PVC

    相关文章

    KubeSphere 部署向量数据库 Milvus 实战指南
    探索 Kubernetes 持久化存储之 Longhorn 初窥门径
    征服 Docker 镜像访问限制!KubeSphere v3.4.1 成功部署全攻略
    那些年在 Terraform 上吃到的糖和踩过的坑
    无需 Kubernetes 测试 Kubernetes 网络实现
    Kubernetes v1.31 中的移除和主要变更

    发布评论