有时,我们不想手动建立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.60.146
- name: NFS_PATH
value: /mnt/disk/nfs_data #这个nfs服务器上的目录
volumes:
- name: nfs-client-root
nfs:
server: 192.168.60.146
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申请正常了。

k8s~动态生成pvc和pv的更多相关文章

  1. 4.k8s存储之Volume、PV、PVC和StatefulSet

    3.Volume 容器磁盘上的文件的生命周期是短暂的,这就使得在容器中运行重要应用时会出现一些问题.首先,当容器崩溃时,kubelet 会重启它,但是容器中的文件将丢失--容器以干净的状态(镜像最初的 ...

  2. K8s存储之Volume、PV、PVC、SC

    Volume Volume(存储卷)是Pod中能够被多个容器访问的共享目录.Kubernetes的Volume概念.用途和目的与Docker的Volume比较类似,但两者不能等价.首先,Kuberne ...

  3. k8s_使用k8s部署博客系统-PV PVC(二)

    PV和PVC PV(PersistentVolume)在声明的时候需要指定大小和续写模式:["ReadWriteMany","ReadWriteOnce",&q ...

  4. Aop动态生成代理类时支持带参数构造函数

    一.背景 在某些情况下,我们需要植入AOP代码的类并没有默认构造函数.那么此时动态生成的代理类也需要相同签名的构造函数,并且内部调用原始类的构造函数.自己折腾了1晚上没搞定,现在搞定了发出来供大家一起 ...

  5. dynamic-css 动态 CSS 库,使得你可以借助 MVVM 模式动态生成和更新 css,从 js 事件和 css 选择器的苦海中脱离出来

    dynamic-css 使得你可以借助 MVVM 模式动态生成和更新 css,从而将本插件到来之前,打散.嵌套在 js 中的修改样式的代码剥离出来.比如你要做元素跟随鼠标移动,或者根据滚动条位置的变化 ...

  6. ABP(现代ASP.NET样板开发框架)系列之20、ABP展现层——动态生成WebApi

    点这里进入ABP系列文章总目录 ABP(现代ASP.NET样板开发框架)系列之20.ABP展现层——动态生成WebApi ABP是“ASP.NET Boilerplate Project (ASP.N ...

  7. 【.NET深呼吸】Zip文件操作(2):动态生成Zip文档

    通过前面一篇烂文的介绍,大伙儿知道,ZipArchive类表示一个zip文档实例,除了用上一篇文章中所列的方法来读写zip文件外,还可以直接通过ZipArchive类,动态生成zip文件. 文件流操作 ...

  8. jquery动态生成的元素添加事件的方法

    动态生成的元素如果要添加事件,要写成 $(document).on("click", "#txtName", function() { alert(this.v ...

  9. 利用Java动态生成 PDF 文档

    利用Java动态生成 PDF 文档,则需要开源的API.首先我们先想象需求,在企业应用中,客户会提出一些复杂的需求,比如会针对具体的业务,构建比较典型的具备文档性质的内容,一般会导出PDF进行存档.那 ...

  10. 用C#从数据库动态生成AdminLTE菜单的一种方法

    当前的应用设计风格趋于Flat扁平化,很多基于BootStrap实现了很多UI非常漂亮的管理界面(Bootstrap admin template). 此核心文件开源在Github:https://g ...

随机推荐

  1. 【Python爬虫实战】爬虫封你ip就不会了?ip代理池安排上

    前言 在进行网络爬取时,使用代理是经常遇到的问题.由于某些网站的限制,我们可能会被封禁或者频繁访问时会遇到访问速度变慢等问题.因此,我们需要使用代理池来避免这些问题.本文将为大家介绍如何使用IP代理池 ...

  2. 2023-09-23:用go语言,假设每一次获得随机数的时候,这个数字大于100的概率是P。 尝试N次,其中大于100的次数在A次~B次之间的概率是多少? 0 < P < 1, P是double类型,

    2023-09-23:用go语言,假设每一次获得随机数的时候,这个数字大于100的概率是P. 尝试N次,其中大于100的次数在A次~B次之间的概率是多少? 0 < P < 1, P是dou ...

  3. SpringBoot WebSocket STOMP

    SpringBoot WebSocket STOMP 关键词:Springboot, WebSocket, STOMP, broadcast, sendToUser, MessageMapping, ...

  4. 基于TRE文章的非线性模型化线性方法

    之前写过一篇有关TRE优化模型详解的博文: https://www.cnblogs.com/zoubilin/p/17270435.html 这篇文章里面的附录给出了非线性模型化线性的方式,具体内容如 ...

  5. Python中的转义符\

    1.转义符 可以百度百科查询 2.Python中的转义符 我目前知道的Python中的转义符使用场景有两个:一个是字符串,一个是正则表达式 2.1.字符串的转义 2.1.1.反斜杠"\&qu ...

  6. Vue2系列(lqz)——slot插槽 (内容分发)、2 transition过渡、3 生命周期、4 swiper学习、5 自定义组件的封装、6 自定义指令、7 过滤器

    文章目录 1 slot插槽 (内容分发) 1.1 基本使用 1.2 插槽应用场景1 1.3 插槽应用场景2 1.4 具名插槽 2 transition过渡 3 生命周期 4 swiper学习 5 自定 ...

  7. 中国科教工作者协会与CCF PTA联合认证学习须知

    中国科教工作者协会与CCF PTA联合认证学习须知 1.参与认证人员需在科技学堂(www.sciclass.cn)上进行课程学习,然后在PTA官网(pta.ccf.org.cn)报名并参加认证考试,考 ...

  8. 不写代码、构建一个开源的 ChatGPT,总共需要几步?|Hugging News #1020

    每一周,我们的同事都会向社区的成员们发布一些关于 Hugging Face 相关的更新,包括我们的产品和平台更新.社区活动.学习资源和内容更新.开源库和模型更新等,我们将其称之为「Hugging Ne ...

  9. re1-100

    虽然关键的判断函数和"成功"的提示也在这里,但是具体对输入flag的操作却在后面 看到对数组bufParentRead[1]开始赋值"53fc275d81",b ...

  10. C/C++ 开发SCM服务管理组件

    SCM(Service Control Manager)服务管理器是 Windows 操作系统中的一个关键组件,负责管理系统服务的启动.停止和配置.服务是一种在后台运行的应用程序,可以在系统启动时自动 ...