持久化存储 StorageClass

2023-12-18 06:44
文章标签 存储 持久 storageclass

本文主要是介绍持久化存储 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

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

#提前配置好了nfs
Server:    192.168.21.103
Path:      /data/nfs_root

首先,我们需要配置nfs-client的Deployment文件

apiVersion: apps/v1
kind: Deployment
metadata:name: nfs-client-provisionernamespace: test
spec:replicas: 1selector:matchLabels:app: nfs-client-provisionerstrategy:type: Recreatetemplate:metadata:labels:app: nfs-client-provisionerspec:serviceAccountName: nfs-client-provisionercontainers:- name: nfs-client-provisionerimage: quay.io/external_storage/nfs-client-provisioner:latestvolumeMounts:- name: nfs-client-rootmountPath: /persistentvolumesenv:- name: PROVISIONER_NAMEvalue: fuseim.pri/ifs- name: NFS_SERVERvalue: 192.168.21.103         #nfs server 地址- name: NFS_PATHvalue: /data/nfs_root         #nfs共享目录volumes:- name: nfs-client-rootnfs:server: 192.168.21.103path: /data/nfs_root

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

apiVersion: v1
kind: ServiceAccount
metadata:name: nfs-client-provisionernamespace: test---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:name: nfs-client-provisioner-runnernamespace: test
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-provisionernamespace: test
subjects:- kind: ServiceAccountname: nfs-client-provisionernamespace: test
roleRef:kind: ClusterRolename: nfs-client-provisioner-runnerapiGroup: rbac.authorization.k8s.io

创建storageclass

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:name: managed-nfs-storagenamespace: test
provisioner: fuseim.pri/ifs                #fuseim.pri/ifs 需要和deployment保持一致

创建

[root@master1 value_mount]# kubectl apply -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

接下来我们可以查看一下

[root@master1 value_mount]# kubectl get pods -n test
NAME                                     READY   STATUS    RESTARTS      AGE
nfs-client-provisioner-6b8d9f996-xmbzt   1/1     Running   0             35s
tomcat-698554b5d9-h9p75                  1/1     Running   2 (21d ago)   56d
[root@master1 value_mount]# kubectl get sc -n test
NAME                  PROVISIONER      RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
managed-nfs-storage   fuseim.pri/ifs   Delete          Immediate           false                  43s
[root@master1 value_mount]# kubectl get ServiceAccount -n test
NAME                     SECRETS   AGE
default                  1         56d
nfs-client-provisioner   1         72s

接下来我们需要创建一个pvc,来引用刚刚创建的storageclass

[root@master1 ~]# cat pvc.yaml
kind: PersistentVolumeClaim
apiVersion: v1
metadata:name: test-claimnamespace: testannotations:volume.beta.kubernetes.io/storage-class: "managed-nfs-storage"    #storageclass 名称
spec:accessModes:              #访问模式- ReadWriteManyresources:requests:storage: 1024Mi[root@master1 ~]# kubectl apply -f pvc.yaml
persistentvolumeclaim/test-claim created
#通过查看可以发现,新创建的pvc是Pending的状态,不可用
[root@master1 ~]# kubectl get pvc -n test
NAME         STATUS    VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS          AGE
test-claim   Pending                                      managed-nfs-storage   15s

通过日志查看新创建的pvc是Pending的状态的具体原因

[root@master1 ~]# kubectl get pods -n test
NAME                                     READY   STATUS    RESTARTS      AGE
nfs-client-provisioner-6b8d9f996-xmbzt   1/1     Running   0             3m40s
tomcat-698554b5d9-h9p75                  1/1     Running   2 (21d ago)   56d
[root@master1 ~]# kubectl logs nfs-client-provisioner-6b8d9f996-xmbzt -n test
I1217 08:43:18.618926       1 leaderelection.go:185] attempting to acquire leader lease  test/fuseim.pri-ifs...
E1217 08:43:36.046744       1 event.go:259] Could not construct reference to: '&v1.Endpoints{TypeMeta:v1.TypeMeta{Kind:"", APIVersion:""}, ObjectMeta:v1.ObjectMeta{Name:"fuseim.pri-ifs", GenerateName:"", Namespace:"test", SelfLink:"", UID:"d526eedc-6d03-452a-b246-4bd8b0254af1", ResourceVersion:"84178", Generation:0, CreationTimestamp:v1.Time{Time:time.Time{wall:0x0, ext:63838397330, loc:(*time.Location)(0x1956800)}}, DeletionTimestamp:(*v1.Time)(nil), DeletionGracePeriodSeconds:(*int64)(nil), Labels:map[string]string(nil), Annotations:map[string]string{"control-plane.alpha.kubernetes.io/leader":"{\"holderIdentity\":\"nfs-client-provisioner-6b8d9f996-xmbzt_53a33f75-9cb8-11ee-a730-7a51051133c9\",\"leaseDurationSeconds\":15,\"acquireTime\":\"2023-12-17T08:43:36Z\",\"renewTime\":\"2023-12-17T08:43:36Z\",\"leaderTransitions\":2}"}, OwnerReferences:[]v1.OwnerReference(nil), Initializers:(*v1.Initializers)(nil), Finalizers:[]string(nil), ClusterName:""}, Subsets:[]v1.EndpointSubset(nil)}' due to: 'selfLink was empty, can't make reference'. Will not report event: 'Normal' 'LeaderElection' 'nfs-client-provisioner-6b8d9f996-xmbzt_53a33f75-9cb8-11ee-a730-7a51051133c9 became leader'
I1217 08:43:36.046837       1 leaderelection.go:194] successfully acquired lease test/fuseim.pri-ifs
I1217 08:43:36.046902       1 controller.go:631] Starting provisioner controller fuseim.pri/ifs_nfs-client-provisioner-6b8d9f996-xmbzt_53a33f75-9cb8-11ee-a730-7a51051133c9!
I1217 08:43:36.147231       1 controller.go:680] Started provisioner controller fuseim.pri/ifs_nfs-client-provisioner-6b8d9f996-xmbzt_53a33f75-9cb8-11ee-a730-7a51051133c9!
I1217 08:45:16.768115       1 controller.go:987] provision "test/test-claim" class "managed-nfs-storage": started
E1217 08:45:16.776910       1 controller.go:1004] provision "test/test-claim" class "managed-nfs-storage": unexpected error getting claim reference: selfLink was empty, can't make reference

通过日志可以看出,报了managed-nfs-storage": unexpected error getting claim reference: selfLink was empty的错误,由于Kubernetes 1.20禁用了selfLink,创建的时候会报错

解决错误的方法:使用新的不基于 SelfLink 功能的 provisioner 镜像,重新创建 provisioner 容器

[root@master1 ~]# kubectl get deployment -n test
NAME                     READY   UP-TO-DATE   AVAILABLE   AGE
nfs-client-provisioner   1/1     1            1           5m53s
tomcat                   1/1     1            1           56d
[root@master1 ~]# kubectl edit deployment nfs-client-provisioner -n test
deployment.apps/nfs-client-provisioner edited
将nfs-client-provisioner的pod镜像修改成不基于 SelfLink 功能的的镜像:registry.cn-beijing.aliyuncs.com/pylixm/nfs-subdir-external-provisioner:v4.0.0

服务重启完以后咱们在重新创建一下pvc验证一下

[root@master1 ~]# kubectl delete -f pvc.yaml
persistentvolumeclaim "test-claim" deleted
[root@master1 ~]# kubectl apply -f pvc.yaml
persistentvolumeclaim/test-claim created
在查看新创建的pvc状态就是正常的了
[root@master1 ~]# kubectl get pvc -n test
NAME         STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS          AGE
test-claim   Bound    pvc-4ae8644e-021e-4d38-99e4-76f331810575   1Gi        RWX            managed-nfs-storage   29s
#这里可以看到自动创建了一个pv
[root@master1 ~]# kubectl get pv -n test
NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                  STORAGECLASS          REASON   AGE
pvc-4ae8644e-021e-4d38-99e4-76f331810575   1Gi        RWX            Delete           Bound    test/test-claim        managed-nfs-storage            2m4s
pvc-e7d3d926-4fa4-4044-bf2f-30df06eef4aa   8Gi        RWO            Delete           Bound    app/data-zookeeper-0   nfs-client                     21d

在默认情况下,我们创建一个pvc需要有一个状态为空闲的pv,然后才会绑定到pvc上。使用storageclass之后,我们不需要的手动创建pv,只需要创建一个pvc,storageclass会自动将pv给创建并且关联

除了上面使用annotations参数指定storageclass的方式以外,还可以通过修改yaml或者或者通过patch的方式将storageclass设置为默认的存储。(如找不到指定的storageclass则会使用默认sc进行创建pv)

通过修改storageclass方式

[root@master1 value_mount]# cat nfs-client-provisioner-StorageClass.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:name: managed-nfs-storagenamespace: testannotations:                                          #加上这个参数storageclass.kubernetes.io/is-default-class: "true" #加上这个参数值
provisioner: fuseim.pri/ifs
[root@master1 value_mount]# kubectl apply -f nfs-client-provisioner-StorageClass.yaml
storageclass.storage.k8s.io/managed-nfs-storage created

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

使用Deployment 引用PVC

[root@master1 pods_demo]# cat test-app.yaml
kind: Pod
apiVersion: v1
metadata:name: test-pod                        #pod的名称namespace: test
spec:containers:- name: test-pod                      #容器的名称image: busyboximagePullPolicy: IfNotPresentcommand:                            #容器执行的命令- "/bin/sh"args:- "-c"- "touch /mnt/SUCCESS && sleep 3600 && exit 0 || exit 1"volumeMounts:- name: nfs-pvc                   #容器挂载点名称mountPath: "/mnt"               #容器挂载目录restartPolicy: "Never"volumes:- name: nfs-pvc                     #这里的名称要和上面容器挂载点的名称匹配persistentVolumeClaim:            #挂载使用pvcclaimName: test-claim                   #pvc的名称
[root@master1 pods_demo]# kubectl apply -f test-app.yaml

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

在nfs存储目录就可以看到这个目录

[root@k8s-node1 nfs_root]# cd test-test-claim-pvc-4ae8644e-021e-4d38-99e4-76f331810575
[root@k8s-node1 test-test-claim-pvc-4ae8644e-021e-4d38-99e4-76f331810575]# ll
total 0
-rw-r--r-- 1 root root 0 Dec 17 04:07 SUCCESS
[root@k8s-node1 test-test-claim-pvc-4ae8644e-021e-4d38-99e4-76f331810575]#

这篇关于持久化存储 StorageClass的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/507426

相关文章

异构存储(冷热数据分离)

异构存储主要解决不同的数据,存储在不同类型的硬盘中,达到最佳性能的问题。 异构存储Shell操作 (1)查看当前有哪些存储策略可以用 [lytfly@hadoop102 hadoop-3.1.4]$ hdfs storagepolicies -listPolicies (2)为指定路径(数据存储目录)设置指定的存储策略 hdfs storagepolicies -setStoragePo

HDFS—存储优化(纠删码)

纠删码原理 HDFS 默认情况下,一个文件有3个副本,这样提高了数据的可靠性,但也带来了2倍的冗余开销。 Hadoop3.x 引入了纠删码,采用计算的方式,可以节省约50%左右的存储空间。 此种方式节约了空间,但是会增加 cpu 的计算。 纠删码策略是给具体一个路径设置。所有往此路径下存储的文件,都会执行此策略。 默认只开启对 RS-6-3-1024k

速了解MySQL 数据库不同存储引擎

快速了解MySQL 数据库不同存储引擎 MySQL 提供了多种存储引擎,每种存储引擎都有其特定的特性和适用场景。了解这些存储引擎的特性,有助于在设计数据库时做出合理的选择。以下是 MySQL 中几种常用存储引擎的详细介绍。 1. InnoDB 特点: 事务支持:InnoDB 是一个支持 ACID(原子性、一致性、隔离性、持久性)事务的存储引擎。行级锁:使用行级锁来提高并发性,减少锁竞争

ORACLE语法-包(package)、存储过程(procedure)、游标(cursor)以及java对Result结果集的处理

陈科肇 示例: 包规范 CREATE OR REPLACE PACKAGE PACK_WMS_YX IS-- Author : CKZ-- Created : 2015/8/28 9:52:29-- Purpose : 同步数据-- Public type declarations,游标 退休订单TYPE retCursor IS REF CURSOR;-- RETURN vi_co_co

OpenStack离线Train版安装系列—11.5实例使用-Cinder存储服务组件

本系列文章包含从OpenStack离线源制作到完成OpenStack安装的全部过程。 在本系列教程中使用的OpenStack的安装版本为第20个版本Train(简称T版本),2020年5月13日,OpenStack社区发布了第21个版本Ussuri(简称U版本)。 OpenStack部署系列文章 OpenStack Victoria版 安装部署系列教程 OpenStack Ussuri版

多云架构下大模型训练的存储稳定性探索

一、多云架构与大模型训练的融合 (一)多云架构的优势与挑战 多云架构为大模型训练带来了诸多优势。首先,资源灵活性显著提高,不同的云平台可以提供不同类型的计算资源和存储服务,满足大模型训练在不同阶段的需求。例如,某些云平台可能在 GPU 计算资源上具有优势,而另一些则在存储成本或性能上表现出色,企业可以根据实际情况进行选择和组合。其次,扩展性得以增强,当大模型的规模不断扩大时,单一云平

MySQL技术内幕_innodb存储引擎

MySQL技术内幕_innodb存储引擎 INNODB innodb中如果表没有主键 表是否由 非空唯一键,有则该字段为主键没有,则自动创建一个6字节大小的指针 innodb存储引擎的所有数据都存储在表空间中,表空间由段,区,页(块)组成。 如果启用了 innodb_file_per_table, 则每张表内的数据可以单独放在一个表空间中即使启用了上面参数,共享表空间也会因为 系统事务信息

单精度浮点数按存储格式转为整数的程序

///#include<cstdio>//-----------------union int_char{unsigned char ch[4];float i;};void out_put(union int_char x)//x86是小端对其模式,即最数据的最低位存储在地址的最低位上。{printf("单精度浮点数值为:%f\n",x.i,x.i);printf("存储位置从左到右

Unity数据持久化 之 一个通过2进制读取Excel并存储的轮子(4)

本文仅作笔记学习和分享,不用做任何商业用途 本文包括但不限于unity官方手册,unity唐老狮等教程知识,如有不足还请斧正​​ Unity数据持久化 之 一个通过2进制读取Excel并存储的轮子(3)-CSDN博客  这节就是真正的存储数据了   理清一下思路: 1.存储路径并检查 //2进制文件类存储private static string Data_Binary_Pa

C语言-数据结构 克鲁斯卡尔算法(Kruskal)邻接矩阵存储

相比普里姆算法来说,克鲁斯卡尔的想法是从边出发,不管是理解上还是实现上都更简单,实现思路:我们先把找到所有边存到一个边集数组里面,并进行升序排序,然后依次从里面取出每一条边,如果不存在回路,就说明可以取,否则就跳过去看下一条边。其中看是否是回路这个操作利用到了并查集,就是判断新加入的这条边的两个顶点是否在同一个集合中,如果在就说明产生回路,如果没在同一个集合那么说明没有回路可以加入