k8s~动态生成pvc和pv

打印 上一主题 下一主题

主题 542|帖子 542|积分 1626

有时,我们不想手动建立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)时,它们之间的关系可以用以下文字图示表示:
  1.            +------------------+
  2.            |   StorageClass   |
  3.            +------------------+
  4.                      |
  5.                      |  +------------------+
  6.                      |  |       PVC        |
  7.                      |  +------------------+
  8.                      |         |
  9.                      |         |
  10.                      |  +------------------+
  11.                      |  |        PV        |
  12.                      |  +------------------+
复制代码
在这个图示中:

  • StorageClass是用于定义动态卷分配的规则和配置的对象。
  • PVC是用来请求存储资源的声明,它指定了所需的存储容量、访问模式等。
  • PV是实际的持久化存储资源,它是由集群管理员预先创建并配置好的。
当一个PVC被创建时,它会根据所指定的StorageClass进行动态分配,并绑定到一个可用的PV上。这样,PVC就可以通过PV来获取所需的存储资源。PVC和PV之间的绑定关系是自动完成的,不需要用户手动干预。
集群权限与绑定rbac.yaml

首先,你要在k8s中添加pvc,pv这些资源,你需要有自己的sa(service account),然后把你的pod(建立pvc和pv)去分配这个有权限的sa,这个pod就可以像人一样,为你在k8s中创建资源了。
  1. ---
  2. apiVersion: v1
  3. kind: ServiceAccount
  4. metadata:
  5.   name: nfs-provisioner
  6.   namespace: elk
  7. ---
  8. kind: ClusterRole
  9. apiVersion: rbac.authorization.k8s.io/v1
  10. metadata:
  11.    name: nfs-provisioner-runner
  12. rules:
  13.    -  apiGroups: [""]
  14.       resources: ["persistentvolumes"]
  15.       verbs: ["get", "list", "watch", "create", "delete"]
  16.    -  apiGroups: [""]
  17.       resources: ["persistentvolumeclaims"]
  18.       verbs: ["get", "list", "watch", "update","create"]
  19.    -  apiGroups: ["storage.k8s.io"]
  20.       resources: ["storageclasses"]
  21.       verbs: ["get", "list", "watch"]
  22.    -  apiGroups: [""]
  23.       resources: ["events"]
  24.       verbs: ["list", "watch", "create", "update", "patch"]
  25.    -  apiGroups: [""]
  26.       resources: ["services", "endpoints"]
  27.       verbs: ["get","create","list", "watch","update"]
  28.    -  apiGroups: ["extensions"]
  29.       resources: ["podsecuritypolicies"]
  30.       resourceNames: ["nfs-provisioner"]
  31.       verbs: ["use"]
  32. ---
  33. kind: ClusterRoleBinding
  34. apiVersion: rbac.authorization.k8s.io/v1
  35. metadata:
  36.   name: run-nfs-provisioner
  37. subjects:
  38.   - kind: ServiceAccount
  39.     name: nfs-provisioner
  40. roleRef:
  41.   kind: ClusterRole
  42.   name: nfs-provisioner-runner
  43.   apiGroup: rbac.authorization.k8s.io
复制代码
在Kubernetes中,ClusterRole和ClusterRoleBinding都是一种用于定义集群级别权限的资源,它与特定的命名空间无关。因此,在创建ClusterRole时,不需要为它指定namespace。
ClusterRole的权限范围覆盖整个集群,可以被任何命名空间中的对象引用和使用。这使得ClusterRole能够控制跨多个命名空间的资源和操作。
建立动态pvc的provisioner.yaml
  1. ---
  2. kind: Deployment
  3. apiVersion: apps/v1
  4. metadata:
  5.   name: nfs-client-provisioner
  6.   namespace: elk
  7.   labels:
  8.     app: nfs-client-provisioner
  9. spec:
  10.   replicas: 1
  11.   strategy:
  12.     type: Recreate
  13.   selector:
  14.     matchLabels:
  15.       app: nfs-client-provisioner
  16.   template:
  17.     metadata:
  18.       labels:
  19.         app: nfs-client-provisioner
  20.     spec:
  21.       serviceAccount: nfs-provisioner
  22.       containers:
  23.         - name: nfs-client-provisioner
  24.           image: easzlab/nfs-subdir-external-provisioner:v4.0.1 #quay.io/external_storage/nfs-client-provisioner:latest
  25.           volumeMounts:
  26.             - name: nfs-client-root
  27.               mountPath: /persistentvolumes
  28.           env:
  29.             - name: PROVISIONER_NAME
  30.               value: nfs-provisioner # 指定分配器的名称,创建storageclass会用到
  31.             - name: NFS_SERVER
  32.               value: 192.168.1.x
  33.             - name: NFS_PATH
  34.               value: /mnt/disk/nfs_data #这个nfs服务器上的目录
  35.       volumes:
  36.         - name: nfs-client-root
  37.           nfs:
  38.             server: 192.168.1.x
  39.             path: /mnt/disk/nfs_data #这个nfs服务器上的目录
复制代码
建立strongClass的strongclass.yaml
  1. apiVersion: storage.k8s.io/v1
  2. kind: StorageClass
  3. metadata:
  4.   name: elk-nfs
  5. provisioner: nfs-provisioner # 必须与provisioner.yaml中PROVISIONER_NAME的值一致
  6. parameters:
  7.   archiveOnDelete: "true"  # 删除pv的时候,pv的内容是否要备份
  8. 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字段:
  1. apiVersion: apps/v1
  2. kind: StatefulSet
  3. metadata:
  4.   name: example-statefulset
  5. spec:
  6.   serviceName: "example"
  7.   replicas: 3
  8.   selector:
  9.     matchLabels:
  10.       app: example
  11.   template:
  12.     metadata:
  13.       labels:
  14.         app: example
  15.     spec:
  16.       containers:
  17.       - name: example-app
  18.         image: nginx
  19.         ports:
  20.         - containerPort: 80
  21.         volumeMounts:
  22.         - name: data
  23.           mountPath: /data
  24.   volumeClaimTemplates:
  25.   - metadata:
  26.       name: data
  27.     spec:
  28.       accessModes: [ "ReadWriteOnce" ]
  29.       storageClassName: elk-nfs
  30.       resources:
  31.         requests:
  32.           storage: 1Gi
复制代码
在上述配置中,我们定义了一个StatefulSet,它由3个Pod组成。每个Pod都会自动创建一个名为"data"的PVC,并将其挂载到/data路径上。你需要将elk-nfs替换为实际的存储类名称。
遇到的问题与解决

最近把kubernetes集群从1.18升级到1.20以后,新建pvc一直处于pending状态,查看nfs-client-provisioner日志,提示:
  1. unexpected error getting claim reference: selfLink was empty, can't  make reference
复制代码
主要原因是kubernetes 1.20版本 禁用了 selfLink导致。
网上大部分文档的解决方法都是修改kube-apiserver.yaml,添加- --feature-gates=RemoveSelfLink=false,然后重新部署。
  1. spec:
  2.   containers:
  3.   - command:
  4.     - kube-apiserver
  5.     - --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申请正常了。


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

曂沅仴駦

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表