• k8s~动态生成pvc和pv


    有时,我们不想手动建立pv和pvc,这时,我们可以通过strongClass存储类来帮我们实现,动态建立pvc,并动态为它分配pv存储空间,我们以nfs为例,说一下动态分配在nfs存储截至上建立pv的方式。

    本文导读

    • StorageClass和PVC及PV
    • 集群权限与绑定rbac.yaml
    • 建立动态pvc的provisioner.yaml
    • 建立strongClass的strongclass.yaml
    • 在有状态服务StatefulSet中使用strongClass
    • 遇到的问题与解决

    StorageClass和PVC及PV

    当使用StorageClass创建PersistentVolumeClaim(PVC)时,它们之间的关系可以用以下文字图示表示:

               +------------------+
               |   StorageClass   |
               +------------------+
                         |
                         |  +------------------+
                         |  |       PVC        |
                         |  +------------------+
                         |         |
                         |         |
                         |  +------------------+
                         |  |        PV        |
                         |  +------------------+
    

    在这个图示中:

    • StorageClass是用于定义动态卷分配的规则和配置的对象。
    • PVC是用来请求存储资源的声明,它指定了所需的存储容量、访问模式等。
    • PV是实际的持久化存储资源,它是由集群管理员预先创建并配置好的。

    当一个PVC被创建时,它会根据所指定的StorageClass进行动态分配,并绑定到一个可用的PV上。这样,PVC就可以通过PV来获取所需的存储资源。PVC和PV之间的绑定关系是自动完成的,不需要用户手动干预。

    集群权限与绑定rbac.yaml

    首先,你要在k8s中添加pvc,pv这些资源,你需要有自己的sa(service account),然后把你的pod(建立pvc和pv)去分配这个有权限的sa,这个pod就可以像人一样,为你在k8s中创建资源了。

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

    在Kubernetes中,ClusterRole和ClusterRoleBinding都是一种用于定义集群级别权限的资源,它与特定的命名空间无关。因此,在创建ClusterRole时,不需要为它指定namespace。
    ClusterRole的权限范围覆盖整个集群,可以被任何命名空间中的对象引用和使用。这使得ClusterRole能够控制跨多个命名空间的资源和操作。

    建立动态pvc的provisioner.yaml

    ---
    kind: Deployment
    apiVersion: apps/v1
    metadata:
      name: nfs-client-provisioner
      namespace: elk
      labels:
        app: nfs-client-provisioner
    spec:
      replicas: 1
      strategy:
        type: Recreate
      selector:
        matchLabels:
          app: nfs-client-provisioner
      template:
        metadata:
          labels:
            app: nfs-client-provisioner
        spec:
          serviceAccount: nfs-provisioner
          containers:
            - name: nfs-client-provisioner
              image: easzlab/nfs-subdir-external-provisioner:v4.0.1 #quay.io/external_storage/nfs-client-provisioner:latest
              volumeMounts:
                - name: nfs-client-root
                  mountPath: /persistentvolumes
              env:
                - name: PROVISIONER_NAME
                  value: nfs-provisioner # 指定分配器的名称,创建storageclass会用到
                - name: NFS_SERVER
                  value: 192.168.1.x
                - name: NFS_PATH
                  value: /mnt/disk/nfs_data #这个nfs服务器上的目录
          volumes:
            - name: nfs-client-root
              nfs:
                server: 192.168.1.x
                path: /mnt/disk/nfs_data #这个nfs服务器上的目录
    

    建立strongClass的strongclass.yaml

    apiVersion: storage.k8s.io/v1
    kind: StorageClass
    metadata:
      name: elk-nfs
    provisioner: nfs-provisioner # 必须与provisioner.yaml中PROVISIONER_NAME的值一致
    parameters:
      archiveOnDelete: "true"  # 删除pv的时候,pv的内容是否要备份
    allowVolumeExpansion: true  #如果对PVC扩容,则其对应的"storage class"中allowVolumeExpansion字段需要设置成true
    

    在Kubernetes中,建立StorageClass时不需要指定命名空间(namespace)。StorageClass是一种用于定义持久卷的存储类别的资源,它是集群级别的。

    在有状态服务StatefulSet中使用strongClass

    在Kubernetes中,StatefulSet是一种用于管理有状态应用的控制器。它可以确保Pod按照指定的顺序和唯一标识符进行创建、更新和删除。StatefulSet通常与PersistentVolumeClaim(PVC)一起使用,以为每个Pod提供持久化存储。

    要动态创建PVC并将其绑定到StatefulSet的Pod上,你可以使用volumeClaimTemplates字段。这个字段允许你定义一个模板,用于创建PVC。

    下面是一个示例StatefulSet配置文件,其中包含了volumeClaimTemplates字段:

    apiVersion: apps/v1
    kind: StatefulSet
    metadata:
      name: example-statefulset
    spec:
      serviceName: "example"
      replicas: 3
      selector:
        matchLabels:
          app: example
      template:
        metadata:
          labels:
            app: example
        spec:
          containers:
          - name: example-app
            image: nginx
            ports:
            - containerPort: 80
            volumeMounts:
            - name: data
              mountPath: /data
      volumeClaimTemplates:
      - metadata:
          name: data
        spec:
          accessModes: [ "ReadWriteOnce" ]
          storageClassName: elk-nfs
          resources:
            requests:
              storage: 1Gi
    

    在上述配置中,我们定义了一个StatefulSet,它由3个Pod组成。每个Pod都会自动创建一个名为"data"的PVC,并将其挂载到/data路径上。你需要将elk-nfs替换为实际的存储类名称。

    遇到的问题与解决

    最近把kubernetes集群从1.18升级到1.20以后,新建pvc一直处于pending状态,查看nfs-client-provisioner日志,提示:

    unexpected error getting claim reference: selfLink was empty, can't  make reference
    

    主要原因是kubernetes 1.20版本 禁用了 selfLink导致。

    网上大部分文档的解决方法都是修改kube-apiserver.yaml,添加- --feature-gates=RemoveSelfLink=false,然后重新部署。

    spec:
      containers:
      - command:
        - kube-apiserver
        - --feature-gates=RemoveSelfLink=false
    

    但是根据github的issues,直接更改nfs-subdir-external-provisioner为v4.0.0以上的版本就可以了。

    相关文档:https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner/issues/25

    网上找了一个可以下载的镜像easzlab/nfs-subdir-external-provisioner:v4.0.1,pull以后测试,发现pvc申请正常了。

  • 相关阅读:
    AtomicInteger类简介说明
    《C++游戏编程入门》第9章 高级类与动态内存:Game Lobby
    gd32部分映射1/2,完全映射,备用功能选择等
    量化分析革新金融服务软件的三种方式
    Windows11+Ubuntu24.04双系统安装及配置
    HTML CSS 个人网页设计 WEB前端大作业代码
    首届CCF GitLink开源编程夏令营,来了
    C++教程系列之-02-win10系统下codeblocks-20.03下载与安装
    基于高斯混合模型的分布拟合与参数估计:高维复数域的详细推导
    【C++】引用’&‘的深入解析
  • 原文地址:https://www.cnblogs.com/lori/p/17944619