K8s 实战 动态PV StorageClass 存储类

news2024/11/19 13:34:29

前面我们学习了 PV 和 PVC 的使用方法,但是前面的 PV 都是静态的,什么意思?就是我要使用的一个 PVC 的话就必须手动去创建一个 PV,我们也说过这种方式在很大程度上并不能满足我们的需求,比如我们有一个应用需要对存储的并发度要求比较高,而另外一个应用对读写速度又要求比较高,特别是对于 StatefulSet 类型的应用简单的来使用静态的 PV 就很不合适了,这种情况下我们就需要用到动态 PV,也就是我们今天要讲解的 StorageClass。

什么是StorageClass

Kubernetes提供了一套可以自动创建PV的机制,即:Dynamic Provisioning。而这个机制的核心在于StorageClass这个API对象。

StorageClass对象会定义下面两部分内容:

  1. PV的属性。比如,存储类型,Volume的大小等。
  2. 创建这种PV需要用到的存储插件,即存储制备器。
    有了这两个信息之后,Kubernetes就能够根据用户提交的PVC,找到一个对应的StorageClass,之后Kubernetes就会调用该StorageClass声明的存储插件,进而创建出需要的PV。

但是其实使用起来是一件很简单的事情,你只需要根据自己的需求,编写YAML文件即可,然后使用kubectl create命令执行即可。

StorageClass 为管理员提供了描述存储 “类” 的方法。 不同的类型可能会映射到不同的服务质量等级或备份策略,或是由集群管理员制定的任意策略。 Kubernetes 本身并不清楚各种类代表的什么。这个类的概念在其他存储系统中有时被称为 “配置文件”。

为什么需要StorageClass

在一个大规模的Kubernetes集群里,可能有成千上万个PVC,这就意味着运维人员必须实现创建出这个多个PV,此外,随着项目的需要,会有新的PVC不断被提交,那么运维人员就需要不断的添加新的,满足要求的PV,否则新的Pod就会因为PVC绑定不到PV而导致创建失败。而且通过 PVC 请求到一定的存储空间也很有可能不足以满足应用对于存储设备的各种需求。

而且不同的应用程序对于存储性能的要求可能也不尽相同,比如读写速度、并发性能等,为了解决这一问题,Kubernetes 又为我们引入了一个新的资源对象:StorageClass,通过 StorageClass 的定义,管理员可以将存储资源定义为某种类型的资源,比如快速存储、慢速存储等,用户根据 StorageClass 的描述就可以非常直观的知道各种存储资源的具体特性了,这样就可以根据应用的特性去申请合适的存储资源了。

StorageClass 资源

每个 StorageClass 都包含 provisionerparametersreclaimPolicy 字段, 这些字段会在 StorageClass 需要动态制备 PersistentVolume 时会使用到。

StorageClass 对象的命名很重要,用户使用这个命名来请求生成一个特定的类。 当创建 StorageClass 对象时,管理员设置 StorageClass 对象的命名和其他参数,一旦创建了对象就不能再对其更新。

管理员可以为没有申请绑定到特定 StorageClass 的 PVC 指定一个默认的存储类。

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: standard
provisioner: kubernetes.io/aws-ebs
parameters:
  type: gp2
reclaimPolicy: Retain
allowVolumeExpansion: true
mountOptions:
  - debug
volumeBindingMode: Immediate

存储制备器

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

卷插件内置制备器配置例子
AWSElasticBlockStoreAWS EBS
AzureFileAzure File
AzureDiskAzure Disk
CephFS--
CinderOpenStack Cinder
FC--
FlexVolume--
GCEPersistentDiskGCE PD
GlusterfsGlusterfs
iSCSI--
NFS-NFS
RBDCeph RBD
VsphereVolumevSphere
PortworxVolumePortworx Volume
Local-Local

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

例如,NFS 没有内部制备器,但可以使用外部制备器。 也有第三方存储供应商提供自己的外部制备器。

回收策略

由 StorageClass 动态创建的 PersistentVolume 会在类的 reclaimPolicy 字段中指定回收策略,可以是 Delete 或者 Retain。如果 StorageClass 对象被创建时没有指定 reclaimPolicy,它将默认为 Delete

通过 StorageClass 手动创建并管理的 PersistentVolume 会使用它们被创建时指定的回收策略。

使用 NFS Provisioner

创建

要使用 StorageClass,我们就得安装对应的自动配置程序,比如我们这里存储后端使用的是 nfs,那么我们就需要使用到一个 nfs-client 的自动配置程序,我们也叫它 Provisioner,这个程序使用我们已经配置好的 nfs 服务器,来自动创建持久卷,也就是自动帮我们创建 PV。

  • 自动创建的 PV 以${namespace}-${pvcName}-${pvName}这样的命名格式创建在 NFS 服务器上的共享数据目录中
  • 而当这个 PV 被回收后会以archieved-${namespace}-${pvcName}-${pvName}这样的命名格式存在 NFS 服务器上。

当然在部署nfs-client之前,我们需要先成功安装上 nfs 服务器,前面的课程中我们已经过了,服务地址是10.151.30.57,共享数据目录是**/data/k8s/**,然后接下来我们部署 nfs-client 即可,我们也可以直接参考 nfs-client 的文档:https://github.com/kubernetes-incubator/external-storage/tree/master/nfs-client,进行安装即可。

第一步:配置 NFS,

确保可以从Kubernetes集群访问您的NFS服务器,并获取连接到该服务器所需的信息。

第二步:使用 helm 快速部署nfs-subdir-external-provisioner

helm hub地址:https://artifacthub.io/packages/helm/nfs-subdir-external-provisioner/nfs-subdir-external-provisioner

添加helm仓库

helm repo add nfs-subdir-external-provisioner https://kubernetes-sigs.github.io/nfs-subdir-external-provisioner/

还不会 helm的请参考 https://blog.csdn.net/agonie201218/article/details/126966802

第三部:部署

使用helm部署,设置自动以参数

helm install nfs-subdir-external-provisioner nfs-subdir-external-provisioner/nfs-subdir-external-provisioner \
  --namespace=nfs-provisioner \
  --create-namespace \
  --set image.repository=willdockerhub/nfs-subdir-external-provisioner \
  --set replicaCount=2 \
  --set storageClass.name=nfs-client \
  --set storageClass.defaultClass=true \
  --set nfs.server=10.0.0.5 \
  --set nfs.path=/

查看创建的pods

[root@master ~]# kubectl -n nfs-provisioner get pods
NAME                                               READY   STATUS    RESTARTS   AGE
nfs-subdir-external-provisioner-855665bf6c-c7g4f   1/1     Running   0          19m
nfs-subdir-external-provisioner-855665bf6c-fn67g   1/1     Running   0          164m

查看创建的storageclass

[root@master ~]# kubectl get sc
NAME                   PROVISIONER                                     RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
nfs-client (default)   cluster.local/nfs-subdir-external-provisioner   Delete          Immediate           true                   166m

测试

新建

上面把StorageClass资源对象创建成功了,接下来我们来通过一个示例测试下动态 PV,首先创建一个 PVC 对象:(test-pvc.yaml)

kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: test-pvc
spec:
  accessModes:
  - ReadWriteMany
  resources:
    requests:
      storage: 1Mi

我们这里声明了一个 PVC 对象,采用 ReadWriteMany 的访问模式,请求 1Mi 的空间,但是我们可以看到上面的 PVC 文件我们没有标识出任何和 StorageClass 相关联的信息,那么如果我们现在直接创建这个 PVC 对象能够自动绑定上合适的 PV 对象吗?显然是不能的(前提是没有合适的 PV),我们这里有两种方法可以来利用上面我们创建的 StorageClass 对象来自动帮我们创建一个合适的 PV

如果安装时 storageClass.defaultClass=true,他会再 storageClass 为空时,自动选择当前 storageClass

  • 第一种方法:在这个 PVC 对象中添加一个声明 StorageClass 对象的标识,这里我们可以利用一个 annotations 属性来标识,如下:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: test-pvc
  annotations:
    volume.beta.kubernetes.io/storage-class: "course-nfs-storage"
spec:
  accessModes:
  - ReadWriteMany
  resources:
    requests:
      storage: 1Mi
  • 第二种方法:我们可以设置这个 course-nfs-storage 的 StorageClass 为 Kubernetes 的默认存储后端,我们可以用 kubectl patch 命令来更新:
$ kubectl patch storageclass course-nfs-storage -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'

上面这两种方法都是可以的,当然为了不影响系统的默认行为,我们这里还是采用第一种方法,直接创建即可:

$ kubectl create -f test-pvc.yaml
persistentvolumeclaim "test-pvc" created
$ kubectl get pvc
NAME         STATUS    VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS          AGE
...
test-pvc     Bound     pvc-73b5ffd2-8b4b-11e8-b585-525400db4df7   1Mi        RWX            course-nfs-storage    2m
...

我们可以看到一个名为 test-pvc 的 PVC 对象创建成功了,状态已经是 Bound 了,是不是也产生了一个对应的 VOLUME 对象,最重要的一栏是 STORAGECLASS,现在是不是也有值了,就是我们刚刚创建的 StorageClass 对象 course-nfs-storage。

然后查看下 PV 对象呢:

$ kubectl get pv
NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM                STORAGECLASS          REASON    AGE
...
pvc-73b5ffd2-8b4b-11e8-b585-525400db4df7   1Mi        RWX            Delete           Bound       default/test-pvc     course-nfs-storage              8m
...

可以看到是不是自动生成了一个关联的 PV 对象,访问模式是 RWX,回收策略是 Delete,这个 PV 对象并不是我们手动创建的吧,这是通过我们上面的 StorageClass 对象自动创建的。这就是 StorageClass 的创建方法。

# pwd
/mnt/data/nfs/DP
# ll
total 4
drwxrwxrwx 2 root root 4096 Dec  5 11:01 nfs-test-pvc-pvc-93d5d3a3-ac74-4246-9f35-90b06d8ca45c

测试

接下来我们还是用一个简单的示例来测试下我们上面用 StorageClass 方式声明的 PVC 对象吧:(test-pod.yaml)

kind: Pod
apiVersion: v1
metadata:
  name: test-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:
      claimName: test-pvc

上面这个 Pod 非常简单,就是用一个 busybox 容器,在 /mnt 目录下面新建一个 SUCCESS 的文件,然后把 /mnt 目录挂载到上面我们新建的 test-pvc 这个资源对象上面了,要验证很简单,只需要去查看下我们 nfs 服务器上面的共享数据目录下面是否有 SUCCESS 这个文件即可:

$ kubectl create -f test-pod.yaml
pod "test-pod" created

然后我们可以在 nfs 服务器的共享数据目录下面查看下数据:

$ ls /data/k8s/
default-test-pvc-pvc-73b5ffd2-8b4b-11e8-b585-525400db4df7

我们可以看到下面有名字很长的文件夹,这个文件夹的命名方式是不是和我们上面的规则:** n a m e s p a c e − {namespace}- namespace{pvcName}-${pvName}**是一样的,再看下这个文件夹下面是否有其他文件:

$ ls /data/k8s/default-test-pvc-pvc-73b5ffd2-8b4b-11e8-b585-525400db4df7
SUCCESS

我们看到下面有一个 SUCCESS 的文件,是不是就证明我们上面的验证是成功的啊。

另外我们可以看到我们这里是手动创建的一个 PVC 对象,在实际工作中,使用 StorageClass 更多的是 StatefulSet 类型的服务,StatefulSet 类型的服务我们也可以通过一个 volumeClaimTemplates 属性来直接使用 StorageClass,如下:(test-statefulset-nfs.yaml)

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: nfs-web
spec:
  serviceName: "nginx"
  replicas: 3
  selector:
    matchLabels:
      app: nfs-web
  template:
    metadata:
      labels:
        app: nfs-web
    spec:
      terminationGracePeriodSeconds: 10
      containers:
      - name: nginx
        image: nginx:1.7.9
        ports:
        - containerPort: 80
          name: web
        volumeMounts:
        - name: www
          mountPath: /usr/share/nginx/html
  volumeClaimTemplates:
  - metadata:
      name: www
      annotations:
        volume.beta.kubernetes.io/storage-class: course-nfs-storage
    spec:
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 1Gi

实际上 volumeClaimTemplates 下面就是一个 PVC 对象的模板,就类似于我们这里 StatefulSet 下面的 template,实际上就是一个 Pod 的模板,我们不单独创建成 PVC 对象,而用这种模板就可以动态的去创建了对象了,这种方式在 StatefulSet 类型的服务下面使用得非常多。

直接创建上面的对象:

$ kubectl create -f test-statefulset-nfs.yaml
statefulset.apps "nfs-web" created
$ kubectl get pods
NAME                                             READY     STATUS              RESTARTS   AGE
...
nfs-web-0                                        1/1       Running             0          1m
nfs-web-1                                        1/1       Running             0          1m
nfs-web-2                                        1/1       Running             0          33s
...

创建完成后可以看到上面的3个 Pod 已经运行成功,然后查看下 PVC 对象:

$ kubectl get pvc
NAME            STATUS    VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS          AGE
...
www-nfs-web-0   Bound     pvc-cc36b3ce-8b50-11e8-b585-525400db4df7   1Gi        RWO            course-nfs-storage    2m
www-nfs-web-1   Bound     pvc-d38285f9-8b50-11e8-b585-525400db4df7   1Gi        RWO            course-nfs-storage    2m
www-nfs-web-2   Bound     pvc-e348250b-8b50-11e8-b585-525400db4df7   1Gi        RWO            course-nfs-storage    1m
...

我们可以看到是不是也生成了3个 PVC 对象,名称由模板名称 name 加上 Pod 的名称组合而成,这3个 PVC 对象也都是 绑定状态了,很显然我们查看 PV 也可以看到对应的3个 PV 对象:

$ kubectl get pv
NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM                   STORAGECLASS          REASON    AGE
...                                                        1d
pvc-cc36b3ce-8b50-11e8-b585-525400db4df7   1Gi        RWO            Delete           Bound       default/www-nfs-web-0   course-nfs-storage              4m
pvc-d38285f9-8b50-11e8-b585-525400db4df7   1Gi        RWO            Delete           Bound       default/www-nfs-web-1   course-nfs-storage              4m
pvc-e348250b-8b50-11e8-b585-525400db4df7   1Gi        RWO            Delete           Bound       default/www-nfs-web-2   course-nfs-storage              4m
...

查看 nfs 服务器上面的共享数据目录:

$ ls /data/k8s/
...
default-www-nfs-web-0-pvc-cc36b3ce-8b50-11e8-b585-525400db4df7
default-www-nfs-web-1-pvc-d38285f9-8b50-11e8-b585-525400db4df7
default-www-nfs-web-2-pvc-e348250b-8b50-11e8-b585-525400db4df7
...

是不是也有对应的3个数据目录,这就是我们的 StorageClass 的使用方法,对于 StorageClass 多用于 StatefulSet 类型的服务,在后面的课程中我们还学不断的接触到。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/62772.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

说说你对slot的理解?

首先,大概了解一下插槽: 插槽是什么 ![在这里插入图片描述](https://img-blog.csdnimg.cn/90b04660769e49c286ee2e1821d2a2bb.png 插槽:在HTML中 slot 元素 ,作为 Web Components 技术套件的一部分,是Web组件内的一…

【蓝桥杯选拔赛真题33】python回文数升级 青少年组蓝桥杯python 选拔赛STEMA比赛真题解析

目录 ​编辑 python回文数升级 一、题目要求 1、编程实现 2、输入输出

Spring 框架介绍和使用

微信公众号:运维开发故事,作者:老郑 历史的选择 Spring 作为一个基础的框架,是在 Java EE 开发历史中,是成千上万公司选择。单独使用 Spring 的非常少了,很多都是用 Spring-Boot/Spring-Cloud 来开发&…

文件系统监视器

QFileSystemWatcher类通过监视指定路径的列表来监视文件系统对文件和目录的更改。 构造函数: 常用函数: addPath()添加路径addPaths()添加多个路径directory()返回正在监视的目录的…

【JS】数据结构之队列

文章目录基本概念代码实现基本概念 队列:它是一种运算受限的线性表,FIFO(先进先出)特性:它只运行表的前端进行删除操作,在表的后端进行添加操作面对无法同时处理多个请求的场景,我们通常就会使…

HTML小游戏16 —— 消除游戏《魔法石》源码(附完整源码)

💂 网站推荐:【神级源码资源网】【摸鱼小游戏】🤟 前端学习课程:👉【28个案例趣学前端】【400个JS面试题】💅 想寻找共同学习交流、摸鱼划水的小伙伴,请点击【摸鱼学习交流群】💬 免费且实用的计…

计算机组成原理(一)计算机系统概论

目录前言计算机硬件的组成和分类冯.诺依曼结构的基本思想运算器存储器控制器程序和指令控制器的基本任务指令流和数据流适配器与I/O设备输入设备计算机软件的组成与分类计算机系统的层次结构计算机系统的性能指标软硬件逻辑的等价性前言 计算机组成原理这门课可以说是计算机专…

b2b2c o2o 多商家入驻商城 直播带货商城 电子商务

一个好的SpringCloudSpringBoot b2b2c 电子商务平台涉及哪些技术、运营方案?以下是我结合公司的产品做的总结,希望可以帮助到大家! 搜索体验小程序:海哇 1. 涉及平台 平台管理、商家端(PC端、手机端)、买…

Aqwa 带你掌握船舶与海洋工程水动力理论与工程应用

作者:高巍,仿真秀科普作者 一、写在前面 20世纪60年代欧洲北海发现了储量丰富的油气资源,随着1973年第二次石油危机的到来,欧洲国家能源自主的迫切需要推进了北海油气资源的开发进程,推动了海洋工程技术发展。 为了…

【多线程(三)】生产者和消费者模式

文章目录3.生产者和消费者模式前言3.1生产者和消费者模式概述3.2生产者和消费者案例3.3 阻塞队列基本使用3.4 阻塞队列实现等待唤醒机制总结3.生产者和消费者模式 前言 在线程世界里,生产者就是生产数据的线程,消费者就是消费数据的线程。在多线 程开发…

SQL SERVER数据库修复之REPAIR_ALLOW_DATA_LOSS级别简介和实例

目录 (一)前言 (二)关于DBCC CHECKxxx系列命令 1. DBCC CHECKALLOC 2. DBCC CHECKCATALOG 3. DBCC CHECKDB (1)基本概念 (2)基本语法 (3)参数说明 &…

分析常见限流算法及手写三种(计数器、漏斗、令牌桶)代码实现

常见的限流算法分析 限流在我们日常生活中经常见到,如火车站门口的栏杆、一些景点的门票只出售一定的数量 等等。在我们的开发中也用到了这种思想。 为什么要限流 在保证可用的情况下尽可能多增加进入的人数,其余的人在排队等待,或者返回友好提示,保证里面的进行…

机器如何快速学习数据采集

很多人都在思考如何利用机器学习(ML)算法来提高产品或服务的质量。 如果你正在考虑采用ML,以正确的格式收集正确的数据,将会降低你的数据清理工作以及数据浪费。 要收集所有数据 收集所有数据是非常重要的。除非你真正训练一个…

Excel基于分隔符拆分列

1、示例数据 id name describe 1 张三 学生 2 李四 老师 3 王五 学生 2、将数据复制到Excel中 数据目前都在A列中 3、将数据一次拆分到多个列 Excel基于分隔符拆分列,将数据一次拆分到多个列。 选中数据,数据-分列-分列 设置分隔符 点击完成后&…

【Python自然语言处理】使用逻辑回归(logistic)对电影评论情感分析实战(超详细 附源码)

需要源码和数据集请点赞关注收藏后评论区留言私信~~~ 一、舆情分析 舆情分析很多情况下涉及到用户的情感分析,或者亦称为观点挖掘,是指用自然语言处理技术、文本挖掘以及计算机语言学等方法来正确识别和提取文本素材中的主观信息,通过对带有…

使用Visual Studio Code 进行Python编程(一)

1、下载Visual Studio Code 到微软的Visual Studio Code官方主页下载Visual Studio Code: Visual Studio: 面向软件开发人员和 Teams 的 IDE 和代码编辑器Visual Studio 开发工具和服务让任何开发人员在任何平台和语言的应用开发都更加轻松。 随时随地免费使用代码编辑器或 I…

Spire.Office for .NET 7.12.0 2022年最后版本?

谷歌能找到破解版是破坏强签名,不能用web,请把大家不要用Spire.Office for .NET is a combination of Enterprise-Level Office .NET API offered by E-iceblue. It includes Spire.Doc, Spire.XLS, Spire.Spreadsheet, Spire.Presentation, Spire.PDF, …

数据库开发项目 flask + html 01

目的 开放平台(网站) 前端开发 HTML CSS JavaScript Web框架: 接受请求并处理 MySQL数据库: 存储数据 快速上手: 基于 Flask Web框架 快速搭建网站。 进阶: 基于 Django框架 1. 快速开发网站 安装框架 …

(附源码)SSM介绍信智能实现系统 毕业设计 260930

SSM介绍信智能实现系统 摘 要 科技进步的飞速发展引起人们日常生活的巨大变化,电子信息技术的飞速发展使得电子信息技术的各个领域的应用水平得到普及和应用。信息时代的到来已成为不可阻挡的时尚潮流,人类发展的历史正进入一个新时代。在现实运用中&…

java+mysql基于SSM的大学生兼职信息系统-计算机毕业设计

开发环境 运行环境: 开发工具:IDEA /Eclipse 数据库:MYSQL5.7 应用服务:Tomcat7/Tomcat8 使用框架:SSM(springspringMVCmybatis)vue 项目介绍 论文主要是对大学生兼职信息系统进行了介绍,包括研究的现状,还有涉及的开发背景,然…