持久化存储 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]#

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

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

相关文章

ELK(八)—Metricbeat部署

目录 介绍修改配置文件启动 Modulenginx开启状态查询配置Nginx module查看是否配置成功 介绍 Metricbeat 是一个轻量级的开源度量数据收集器,用于监控系统和服务。它由 Elastic 公司开发,并作为 Elastic Stack(Elasticsearch、Logstash、Kiba…

【Linux】在vim中批量注释与批量取消注释

在vim编辑器中,批量注释和取消注释的操作可以通过进入V-BLOCK模式、选择要注释或取消注释的内容、输入注释符号或选中已有的注释符号和按键完成。这些操作可以大大提高代码或文本的编写和修改效率,是vim编辑器中常用的操作之一。 1.在vim中批量注释的步…

[elementPlus] teleported 在 ElSubMenu中的用途

如图 一个菜单对应的路由结构如上图 如果做适配窄屏幕 如果在 <ElSubMenu :index"route.path" >中不加入 teleported 就会出现问题 加上就OK了 <ElSubMenu :index"route.path" teleported>

力扣200. 岛屿数量(java DFS解法)

Problem: 200. 岛屿数量 文章目录 题目描述思路解题方法复杂度Code 题目描述 思路 该问题可以归纳为一类遍历二维矩阵的题目&#xff0c;此类中的一部分题目可以利用DFS来解决&#xff0c;具体到本题目&#xff1a; 1.我们首先要针对于二维数组上的每一个点&#xff0c;尝试展…

单片机期末复习

前言 发现很多人都写了单片机原理及接口技术课后习题的答案&#xff0c;但是也就只写了答案而已&#xff0c;可能是他们觉得太简单的缘故吧&#xff0c;我这里对此进行一下我近段时间复习的总结&#xff0c;本篇博客只展示选择题、填空题和判断题的答案&#xff0c;仅供参考&a…

饥荒Mod 开发(十一):修改物品堆叠

饥荒Mod 开发(十)&#xff1a;制作一把AOE武器 饥荒Mod 开发(十二)&#xff1a;一键制作 饥荒中物品栏有限&#xff0c;要拾取的物品有很多&#xff0c;经常装不下要忍痛丢掉各种东西&#xff0c;即使可以将物品放在仓库但是使用不方便&#xff0c;所以可以将物品的堆叠个数设…

1264. 动态求连续区间和(树状数组---某个位置加上一个数/求在线(动态)前缀和/蓝桥杯)

题目&#xff1a; 输入样例&#xff1a; 10 5 1 2 3 4 5 6 7 8 9 10 1 1 5 0 1 3 0 4 8 1 7 5 0 4 8输出样例&#xff1a; 11 30 35 树状数组&#xff1a; 代码&#xff1a; #include<cstdio> #include<iostream> using namespace std;const int N100010; int n,…

系统架构设计师教程(七)系统架构设计基础知识

系统架构设计基础知识 7.1 软件架构概念7.1.1 软件架构的定义7.1.2 软件架构设计与生命周期需求分析阶段设计阶段实现阶段构件组装阶段部署阶段后开发阶段 7.1.3 软件架构的重要性 7.2 基于架构的软件开发方法7.2.1 体系结构的设计方法概述7.2.2 概念与术语7.2.3 基于体系结构的…

Autosar通信实战系列07-Com模块要点及其配置介绍(二)

本文框架 前言1. ComGeneral配置2. ComConfig配置2.1 ComGwMapping2.2 ComIPdus2.3 ComIPduGroups2.4 ComIPduSignals2.5 ComIPduSignalGroups2.6 ComTimeBasis前言 在本系列笔者将结合工作中对通信实战部分的应用经验进一步介绍常用,包括但不限于通信各模块的开发教程,代码…

基于sfunction builder的c-sfunction编写及案例测试分析

目录 前言 1.前期准备工作及文件说明 1.1前期准备工作 1.2 文件说明 1.3 编译方式

深度剖析JavaScript中冒泡和捕获机制、事件代理

JS事件传播的两种机制包括冒泡和捕获&#xff0c;下面将具体剖析它们之间本质的区别。 事件冒泡: 先触发子元素的事件&#xff0c;再触发父元素的事件。 创建一个 ul label 和 li label, 分别绑定一个父id 和 子 id, 再通过创建 script&#xff0c;去绑定各自的点击事件。 <…

阿里云|人工智能(AI)技术解决方案

函数计算部署Stable Diffusion AI绘画技术解决方案 通过函数计算快速部署Stable Diffusion模型为用户提供快速通过文字生成图片的能力。该方案通过函数计算快速搭建了AIGC的能力&#xff0c;无需管理服务器等基础设施&#xff0c;专注模型的能力即可。该方案具有高效免运维、弹…

设计模式——责任链模式(行为模式)

引言 责任链模式是一种行为设计模式&#xff0c; 允许你将请求沿着处理者链进行发送。 收到请求后&#xff0c; 每个处理者均可对请求进行处理&#xff0c; 或将其传递给链上的下个处理者。 问题 假如你正在开发一个在线订购系统。 你希望对系统访问进行限制&#xff0c; 只允…

Pod控制器详解【五】

文章目录 5. Pod控制器详解5.1 Pod控制器介绍5.2 ReplicaSet(RS)5.3 Deployment(Deploy)5.4 Horizontal Pod Autoscaler(HPA)5.5 DaemonSet(DS)5.6 Job5.7 CronJob(CJ) 5. Pod控制器详解 5.1 Pod控制器介绍 Pod是kubernetes的最小管理单元&#xff0c;在kubernetes中&#xf…

docker文档转译1

写在最前面 本文主要是转译docker官方文档。主题是Docker overview&#xff0c;这里是链接 Docker概述 Docker是一个用于开发、发布和运行应用程序的开放平台。Docker使你能够将应用程序与基础设施分离&#xff0c;从而可以快速交付软件。你可以使用相同的方法像管理应用程序…

如何提高RAG增强的准确性

在一个典型的RAG应用开发中&#xff0c;必要的步骤为文档加载&#xff0c;文档拆分&#xff0c;向量化&#xff0c;向量存储。然后基于向量存储进行相似性查询&#xff0c;或基于向量距离的查询。这类查询就叫检索&#xff0c;LangChain所提供的对应组件就是检索器。 但这种方…

英伟达盒子 Jetson Xshell连接串口查看日志方法(串口日志、盒子日志)

文章目录 连接串口xshell连接串口信息 连接串口 接盒子上的A2、B2&#xff0c;以及接地线&#xff1a; 另外一头接上电脑&#xff08;我用的RS485转USB工具&#xff09;&#xff1a; xshell连接 协议选择SERIAL&#xff1a; 设置盒子厂商约定的端口号、波特率、数据位、停止位…

轻量封装WebGPU渲染系统示例<51>- 视差贴图(Parallax Map)(源码)

视差纹理是一种片段着色阶段增强材质表面凹凸细节的技术。 当前示例源码github地址: https://github.com/vilyLei/voxwebgpu/blob/feature/material/src/voxgpu/sample/ParallaxTexTest.ts 当前示例运行效果: 此示例基于此渲染系统实现&#xff0c;当前示例TypeScript源码如…

split函数与join函数(字符串的分割 与连接)

split函数可将字符串分割为若干字符并存于数组中&#xff0c;函数说明如下&#xff1a; 函数split 描述 返回一个下标从零开始的一维数组&#xff0c;它包含指定数目的子字符串。 语法 Split(expression[, delimiter[, limit[, compare]]]) Split函数语法有如下命名参数&am…

Docker插件和扩展:深入Docker功能的完整指南

Docker作为一种流行的容器化技术&#xff0c;不仅令应用程序的部署更为便捷&#xff0c;同时也提供了丰富的插件和扩展机制&#xff0c;以满足更多复杂场景下的需求。本文将深入研究Docker的插件和扩展&#xff0c;提供更为详实和全面的示例代码&#xff0c;助力读者更好地理解…