Kubernetes之CSI详解

如何更好的用好Kubernetes CSI?本文尝试从CSI简介、CSI控制器实现原理、实现示例及最佳实践4方面进行阐述。希望对您有所帮助!

一、Kubernetes CSI 简介

CSI (Container Storage Interface) 是一种标准化的接口,用于在容器编排平台(如 Kubernetes)和存储系统之间进行交互。它的设计目的是使存储插件独立于 Kubernetes 核心代码,从而简化存储系统的集成和管理。

背景和动机

在 Kubernetes 的早期阶段,存储插件(即 Volume 插件)是直接嵌入到 Kubernetes 核心代码中的。随着 Kubernetes 的发展和存储需求的增加,这种方式带来了诸多问题:

  • 耦合性高:每次引入新的存储系统支持都需要修改 Kubernetes 核心代码,增加了维护复杂性。
  • 发布周期不同步:存储插件的发布周期与 Kubernetes 的发布周期耦合,不利于独立开发和发布。
  • 扩展性受限:无法灵活地支持多样化的存储系统。

CSI 旨在解决这些问题,通过定义标准化的接口,使存储供应商能够独立开发、发布和维护存储插件。

CSI 架构

CSI 的架构主要包括以下组件:

  • CSI Driver:由存储供应商提供的插件,实现了 CSI 定义的标准接口。包括 Controller Service 和 Node Service 两部分。
  • CSI Controller:运行在 Kubernetes 控制平面,用于处理与存储卷相关的管理操作(如创建、删除、附加等)。
  • CSI Node:运行在每个 Kubernetes 节点上,用于处理卷的挂载和卸载操作。
  • External Provisioner:一个 Kubernetes 控制器,用于根据 PVC(PersistentVolumeClaim)动态创建存储卷。
  • External Attacher:一个 Kubernetes 控制器,用于管理卷的附加和分离操作。
  • External Resizer:一个 Kubernetes 控制器,用于调整卷的大小。
  • External Snapshotter:一个 Kubernetes 控制器,用于管理卷的快照操作。
CSI 标准接口

CSI 定义了一组标准的 gRPC 接口,主要包括:

  • CreateVolume:创建一个新的存储卷。
  • DeleteVolume:删除一个存储卷。
  • ControllerPublishVolume:将存储卷附加到指定的节点。
  • ControllerUnpublishVolume:从指定节点分离存储卷。
  • NodeStageVolume:在节点上准备存储卷,使其可以被挂载。
  • NodeUnstageVolume:在节点上解除存储卷的准备状态。
  • NodePublishVolume:将存储卷挂载到指定的路径。
  • NodeUnpublishVolume:从指定路径卸载存储卷。
  • CreateSnapshot:创建存储卷的快照。
  • DeleteSnapshot:删除存储卷的快照。
部署和使用

部署 CSI 插件一般包括以下步骤:

  1. 安装 CSI Driver:使用存储供应商提供的部署清单文件,在 Kubernetes 集群中安装 CSI Driver。
  2. 创建 StorageClass:定义 StorageClass 资源,指定要使用的 CSI Driver。
  3. 创建 PVC:用户创建 PVC(PersistentVolumeClaim),指定所需的 StorageClass。
  4. 使用 PVC:在 Pod 中使用 PVC,Kubernetes 会自动处理卷的创建、附加和挂载。
优势
  • 解耦合:存储插件与 Kubernetes 核心代码解耦,可以独立开发和发布。
  • 灵活性:存储供应商可以根据自身需求实现定制化的存储解决方案。
  • 扩展性:通过 CSI,能够更容易地集成新的存储系统,扩展 Kubernetes 的存储能力。
  • 标准化:CSI 提供了标准化的接口,简化了存储系统的集成和管理。
结论

CSI 为 Kubernetes 提供了一种标准化、灵活且可扩展的方式来管理存储系统。通过 CSI,存储插件可以独立于 Kubernetes 核心代码进行开发和维护,极大地简化了存储系统的集成和管理过程。CSI 的引入,标志着 Kubernetes 存储系统管理进入了一个新的阶段,推动了容器存储生态系统的发展。

二、Kubernetes CSI 控制器实现原理

下面介绍 CSI 的实现逻辑流程,并附上逻辑示意图。

1. CSI 逻辑流程

以下是 CSI 工作的核心逻辑流程:

  1. 部署 CSI Driver:部署由存储供应商提供的 CSI Driver,包括 CSI Controller 和 CSI Node。
  2. 创建 StorageClass:定义一个 StorageClass,指定要使用的 CSI Driver。
  3. 创建 PVC:用户创建 PVC(PersistentVolumeClaim),指定所需的 StorageClass。
  4. External Provisioner
    • 监听到 PVC 创建事件。
    • 调用 CSI Controller 的 CreateVolume 接口创建卷。
    • 创建 PV(PersistentVolume),并将其与 PVC 绑定。
  5. Pod 调度和卷附加
    • 当 Pod 需要使用 PVC 时,Scheduler 调度 Pod 到合适的节点。
    • External Attacher 调用 CSI Controller 的 ControllerPublishVolume 接口将卷附加到节点。
  6. 卷挂载
    • Kubelet 调用 CSI Node 的 NodePublishVolume 接口将卷挂载到容器的文件系统中。
  7. 卷的卸载和删除
    • 当 Pod 被删除或迁移时,External Attacher 调用 ControllerUnpublishVolume 接口将卷从节点分离。
    • 当 PVC 被删除时,External Provisioner 调用 DeleteVolume 接口删除卷。
2. 逻辑示意图

下面是 Kubernetes CSI 实现原理的逻辑示意图:

+-------------------+           +--------------------+
|                   |           |                    |
|     User          |           |    Kubernetes      |
|  +-------------+  |           |  +-------------+    |
|  |   Create    |  |           |  |  API Server |    |
|  |   PVC       +------------------->   (1)     |    |
|  +-------------+  |           |  +-------------+    |
|                   |           |                    |
+-------------------+           +--------------------+|| (2) PVC creation eventv+----------------------------+|   External Provisioner     ||                            |+----------------------------+|| (3) CreateVolumev+-------------------+|   CSI Controller  ||                   |+-------------------+|| (4) Volume creation requestv+-------------------+|   Storage System  ||                   |+-------------------+|| (5) Volume createdv+-------------------+|   CSI Controller  ||                   |+-------------------+|| (6) Create PV and bind to PVCv+----------------------------+|       Kubernetes API       |+----------------------------+|| (7) Pod creationv+-------------------+|   Kube-Scheduler  ||                   |+-------------------+|| (8) Schedule Podv+-------------------+|      Node         ||   (Kubelet, CSI   ||   Node Plugin)    |+-------------------+|| (9) NodePublishVolumev+-------------------+|  Storage System   |+-------------------+|| (10) Volume mounted to nodev+-------------------+|   Running Pod     |+-------------------+

三、Kubernetes CSI 具体实现示例

要实现一个 Kubernetes CSI 插件,通常需要实现 CSI 定义的一组标准接口,并提供相应的控制器(Controller Service)和节点服务(Node Service)。以下是一个简化的 CSI 插件实现示例,用于展示如何实现基本的卷创建、删除和挂载操作。

目录结构

首先,我们定义一个简单的目录结构:

csi-example/
├── cmd/
│   └── main.go
├── controller/
│   ├── controller.go
├── node/
│   ├── node.go
└── proto/├── csi.proto
1. 定义 CSI 接口

使用 CSI 标准的 gRPC 接口定义。假设 CSI 接口文件(csi.proto)已经存在,并编译生成了相应的 Go 代码。

2. 实现 Controller Service

controller/controller.go 文件:

package controllerimport ("context""fmt"csipb "github.com/container-storage-interface/spec/lib/go/csi"
)type ControllerServer struct {csipb.UnimplementedControllerServer
}func (c *ControllerServer) CreateVolume(ctx context.Context, req *csipb.CreateVolumeRequest) (*csipb.CreateVolumeResponse, error) {// 模拟创建卷volumeID := "example-volume-id"fmt.Println("Creating volume:", volumeID)return &csipb.CreateVolumeResponse{Volume: &csipb.Volume{VolumeId:      volumeID,CapacityBytes: req.CapacityRange.RequiredBytes,},}, nil
}func (c *ControllerServer) DeleteVolume(ctx context.Context, req *csipb.DeleteVolumeRequest) (*csipb.DeleteVolumeResponse, error) {// 模拟删除卷fmt.Println("Deleting volume:", req.VolumeId)return &csipb.DeleteVolumeResponse{}, nil
}// 其他接口可以根据需要实现
3. 实现 Node Service

node/node.go 文件:

package nodeimport ("context""fmt"csipb "github.com/container-storage-interface/spec/lib/go/csi"
)type NodeServer struct {csipb.UnimplementedNodeServer
}func (n *NodeServer) NodePublishVolume(ctx context.Context, req *csipb.NodePublishVolumeRequest) (*csipb.NodePublishVolumeResponse, error) {// 模拟挂载卷fmt.Println("Publishing volume:", req.VolumeId, "to", req.TargetPath)return &csipb.NodePublishVolumeResponse{}, nil
}func (n *NodeServer) NodeUnpublishVolume(ctx context.Context, req *csipb.NodeUnpublishVolumeRequest) (*csipb.NodeUnpublishVolumeResponse, error) {// 模拟卸载卷fmt.Println("Unpublishing volume:", req.VolumeId, "from", req.TargetPath)return &csipb.NodeUnpublishVolumeResponse{}, nil
}// 其他接口可以根据需要实现
4. 启动 CSI gRPC 服务

cmd/main.go 文件:

package mainimport ("fmt""net""google.golang.org/grpc"csipb "github.com/container-storage-interface/spec/lib/go/csi""csi-example/controller""csi-example/node"
)func main() {server := grpc.NewServer()csipb.RegisterControllerServer(server, &controller.ControllerServer{})csipb.RegisterNodeServer(server, &node.NodeServer{})lis, err := net.Listen("tcp", ":10000")if err != nil {fmt.Printf("Failed to listen: %v\n", err)return}fmt.Println("CSI gRPC server started")if err := server.Serve(lis); err != nil {fmt.Printf("Failed to serve: %v\n", err)}
}
5. 构建和运行

首先确保你已经安装了 Go 语言环境,然后在项目根目录下执行以下命令:

go mod init csi-example
go mod tidy
go build -o csi-example cmd/main.go
./csi-example

这会启动一个 gRPC 服务器,监听在 :10000 端口。

解释

  1. ControllerServerNodeServer 实现了 CSI 的 Controller 和 Node 接口,分别处理卷的管理和挂载操作。
  2. main.go 启动一个 gRPC 服务器,并注册了 Controller 和 Node 服务。
  3. CreateVolumeDeleteVolume 方法在 ControllerServer 中实现,用于创建和删除存储卷。
  4. NodePublishVolumeNodeUnpublishVolume 方法在 NodeServer 中实现,用于挂载和卸载存储卷。

这个示例提供了一个基础框架,可以扩展以支持更多的 CSI 功能,如卷的扩展(ControllerExpandVolume)和快照管理(CreateSnapshotDeleteSnapshot)等。通过这种方式,可以将不同存储系统集成到 Kubernetes 中,实现灵活和可扩展的存储管理。

结论

本节通过理解 CSI 的核心组件和逻辑流程,可以更好地部署和使用 Kubernetes 的存储解决方案。

四、Kubernetes CSI最佳实践

在 Kubernetes 中使用 CSI(Container Storage Interface)插件的最佳实践有助于确保稳定、可靠和高效的存储管理。以下是一些重要的最佳实践:

1. 选择合适的 CSI 插件

  • 与需求匹配:选择能够满足应用程序存储需求的 CSI 插件。例如,对于高性能需求,可以选择支持 NVMe 存储的插件。
  • 社区支持:选择具有活跃社区支持和定期更新的 CSI 插件,确保可以获得及时的 bug 修复和新功能。
  • 兼容性:确保 CSI 插件与 Kubernetes 版本兼容。

2. 安全配置

  • RBAC:配置严格的 RBAC(Role-Based Access Control)策略,限制 CSI 插件的权限。
  • 证书管理:使用安全的证书管理方式保护 CSI 插件的通信,防止数据泄露。

3. 高可用性

  • 冗余部署:部署多个 CSI 控制器实例以实现高可用性,避免单点故障。
  • Pod 安全策略:配置 Pod 安全策略(Pod Security Policies)以限制 CSI 插件的运行环境,增强安全性。

4. 性能优化

  • 节点亲和性:配置节点亲和性规则,使 CSI 插件能够在特定节点上运行,提升性能和可靠性。
  • 资源请求和限制:为 CSI 插件配置合理的资源请求和限制,确保插件有足够的资源运行且不会影响其他应用的性能。

5. 监控和日志记录

  • 监控:使用监控工具(如 Prometheus)监控 CSI 插件的性能和状态,及时发现并解决问题。
  • 日志记录:配置详细的日志记录,便于故障排查和性能分析。

6. 卷的生命周期管理

  • 卷快照和备份:定期创建卷的快照和备份,确保数据的安全性和恢复能力。
  • 卷的清理:定期清理不再使用的卷,释放存储资源,避免资源浪费。

7. 升级策略

  • 渐进式升级:采用渐进式升级策略,逐步升级 CSI 插件,避免大规模升级带来的风险。
  • 回滚机制:确保具有回滚机制,以便在升级出现问题时能够快速恢复到稳定版本。

8. 测试和验证

  • 测试环境:在生产环境部署前,在测试环境中验证 CSI 插件的功能和性能。
  • CI/CD 集成:将 CSI 插件的部署和升级集成到 CI/CD 流水线中,实现自动化测试和部署。

实践示例

以下是一个示例,展示如何在 Kubernetes 中使用 Helm 部署一个 CSI 插件(以 Ceph CSI 为例):

1. 安装 Helm
curl https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | bash
2. 添加 Ceph CSI Helm 仓库
helm repo add ceph-csi https://ceph.github.io/csi-charts
helm repo update
3. 创建 Kubernetes 命名空间
kubectl create namespace ceph-csi
4. 部署 Ceph CSI 插件
helm install ceph-csi ceph-csi/ceph-csi --namespace ceph-csi
5. 验证部署

检查 CSI 插件的 Pod 是否运行:

kubectl get pods -n ceph-csi

创建一个 StorageClass:

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:name: ceph-rbd
provisioner: rbd.csi.ceph.com
parameters:clusterID: <ceph-cluster-id>pool: rbdimageFeatures: layeringcsi.storage.k8s.io/provisioner-secret-name: csi-rbd-secretcsi.storage.k8s.io/provisioner-secret-namespace: ceph-csicsi.storage.k8s.io/node-stage-secret-name: csi-rbd-secretcsi.storage.k8s.io/node-stage-secret-namespace: ceph-csi
reclaimPolicy: Delete
allowVolumeExpansion: true
mountOptions:- discard

创建一个 PVC:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:name: ceph-rbd-pvc
spec:accessModes:- ReadWriteOnceresources:requests:storage: 10GistorageClassName: ceph-rbd
6. 配置监控和日志记录

使用 Prometheus 监控 CSI 插件:

apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:name: ceph-csi-metricsnamespace: ceph-csi
spec:selector:matchLabels:app: ceph-csiendpoints:- port: metrics

结论

遵循这些最佳实践,可以确保 Kubernetes 中的 CSI 插件安全、稳定、高效地运行。通过合理的配置和监控,可以及时发现并解决问题,确保存储系统的高可用性和可靠性。

完。

希望对您有用!关注锅总,可及时获得更多运维实用操作!

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

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

相关文章

尚品汇-(六)

&#xff08;1&#xff09;属性的添加修改 平台属性对象&#xff1a; package com.atguigu.gmall.model.product;import com.atguigu.gmall.model.base.BaseEntity; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.Tab…

GitHub每日最火火火项目(6.24)

modelscope / DiffSynth-Studio&#xff1a; 项目介绍&#xff1a;DiffSynth-Studio 是一个基于扩散模型的音频合成工具&#xff0c;它可以生成各种逼真的音频效果&#xff0c;如乐器演奏、环境声音等。该项目提供了一个易于使用的界面&#xff0c;让用户可以通过简单的操作来创…

市盈率(Price-Earnings Ratio)是什么?股市中还结合哪些指标分析一家公司?

市盈率是什么&#xff1f; 中文版 市盈率&#xff08;Price-Earnings Ratio, P/E Ratio&#xff09; 是一种评估公司股票价值的重要财务指标。它是通过将公司的股票价格&#xff08;Price&#xff09;除以每股收益&#xff08;Earnings per Share, EPS&#xff09;计算得出的…

基于Pytorch框架构建ResNet模型

Pytorch 一、训练模型1.导入资源包2.定义数据预处理3.读取数据 二、定义卷积神经网络1.导入必要的库2.定义名为convolutional_block的卷积块类3.定义了一个名为identity_block的恒等块类4.定义了一个名为Resnet的深度卷积神经网络类 三、创建模型1. 检查GPU设备2. 训练过程 四、…

玄机平台流量特征分析—蚂蚁爱上树

前言 依旧是流量分析&#xff0c;老规矩先看看要求。 步骤1.1 这里要求我们找到admin的密码&#xff0c;ctrlf筛选出product2.php的访问包&#xff0c;因为只有这类型流量包才有东西。其他的流量包都是没啥用的&#xff0c;至于我为啥知道&#xff0c;因为每个类型的流量包我…

地信大四,实习重要吗?怎么找实习岗位?

“地信怎么找实习啊&#xff1f;” “实习三个月以上&#xff1f;暑假只有两个月啊” “什么岗位实习比较有用&#xff1f;” “助理类岗位是做什么&#xff1f;” …… 同学们好啊&#xff0c;不知不觉24年已经是过完一小半了&#xff0c;24届毕业的同学们也差不多就要迎来…

快手2019年秋季校园招聘笔试试卷—工程A试卷

a/b 题目描述 求 a/b 的小数表现形式。如果 a 可以整除 b 则不需要小数点。如果是有限小数&#xff0c;则可以直接输出。如果是无限循环小数&#xff0c;则需要把小数循环的部分用"()"括起来。 输入描述 两个整数a和b&#xff0c;其中 0 < a < 1000 000 1…

测试工程师如何学习系统架构

面对同一个“知识点”不同的工作角色需要考虑的问题不一样&#xff0c;比如在系统架构中会使用到消息队列功能&#xff0c;系统架构师&#xff0c;开发人员&#xff0c;测试人员&#xff0c;运维人员&#xff0c;需求人员等需要考虑的问题不一样。 系统架构师在考虑消息队列功能…

数电大作业-四输入表决器

&#xff08;PCB和multisim仿真画的有很大问题&#xff0c;没有VCC输入和GND&#xff0c;没学过直接裸画的&#xff0c;之后会好好看视频学习&#xff09; 应用背景&#xff1a; 四个评委&#xff0c;三个及以上评委同时按下通过按钮时&#xff0c;选手才能通过。否则不通过。…

自动驾驶ADAS

1 ToF摄像头分类 1.1 ToF原理 类似雷达测距&#xff0c;生成3D点云&#xff0c;或者叫3D贴图。ToF相机的分辨率一般在3万像素左右。ToF距离计算公式如图所示。 Figure 1-1 ToF距离计算公式 D&#xff1a;距离 c&#xff1a;光速 PHI&#xff1a;相位差 fmod&#xff1a;调制频率…

创新指南|品牌电商新策略:五大转型思路与RGM举措

在流量红利过去的背景下&#xff0c;品牌电商面对多渠道运营的难题&#xff0c;如缺乏统盘经营、绩效管理分散、价格战失控、用户体验不足以及流量过度依赖&#xff0c;品牌电商如何有效应对这些挑战&#xff0c;本文从5个维度探讨全渠道电商RGM破局之路&#xff0c;实现品牌的…

pyppeteer模块经常使用的功能,相关操作案例

官方仓库地址&#xff1a;https://github.com/miyakogi/pyppeteer 官方文档地址&#xff1a;API Reference — Pyppeteer 0.0.25 documentation Selenium环境的相关配置比较繁琐&#xff0c;此外&#xff0c;有的网站会对selenium和webdriver进行识别和反爬&#xff0c;因此在…

区块链小故事

大灰狼与小白兔 一天兔子妈妈出门了&#xff0c;在大门上安装了一个区块链的门把手&#xff0c;这个门把手只有兔子妈妈、小兔子、以及另一个客人都同意的时候&#xff0c;才会开门&#xff0c;有一天客人a的钥匙丢了&#xff0c;被大灰狼捡到了&#xff0c;大灰狼于是去开门&…

【MySQL】数据库——事务

一.事务概念 事务是一种机制、一个操作序列&#xff0c;包含了一组数据库操作命令&#xff0c;并且把所有的命令作为一个整体一起向系统提交或撤销操作请求&#xff0c;即这一组数据库命令要么都执行&#xff0c;要么都不执行事务是一个不可分割的工作逻辑单元&#xff0c;在数…

【因果推断python】54_效应异质性和非线性带来的挑战2

目录 Continues Treatment and Non Linearity Key Concepts Continues Treatment and Non Linearity 我们只是深入探讨了二元结果增加异质性治疗效果分析难度的一个例子。但这种现象并不局限于市场营销中的转换问题。例如&#xff0c;2021 年&#xff0c;全球成功向公众提供了…

com.google.flatbuffers序列化原理和java使用场景

简介 FlatBuffers 的主要目标是为序列化和反序列化提供一个高效且灵活的解决方案,同时支持多种语言和平台。 实现原理 FlatBuffers 的实现原理可以概括为以下几个关键点: 序列化与存储: FlatBuffers 使用一种二进制序列化格式,将数据直接存储为平面化的二进制数据缓冲区…

如何使用Python接收电子邮件

哈喽,大家好,我是木头左! 本文将详细介绍如何使用Python接收电子邮件,包括SMTP协议的基本概念、Python邮件库的使用以及实际的代码示例。通过阅读本文,你将能够掌握邮件自动处理的技巧,提高工作效率,同时也可以提升自己的Python编程能力。 SMTP协议简介 SMTP(Simple …

深度学习 --- stanford cs231学习笔记五(训练神经网络的几个重要组成部分之三,权重矩阵的初始化)

权重矩阵的初始化 3&#xff0c;权重矩阵的初始化 深度学习所学习的重点就是要根据损失函数训练权重矩阵中的系数。即便如此&#xff0c;权重函数也不能为空&#xff0c;总是需要初始化为某个值。 3&#xff0c;1 全都初始化为同一个常数可以吗&#xff1f; 首先要简单回顾一下…

Ubuntu美化+安装软件

Ubuntu美化安装软件 安装软件 g sudo apt install g curl sudo apt install curl git sudo apt install git Vim sudo apt install vim VSCode https://code.visualstudio.com/Download 找到下载文件夹&#xff0c;有一个code***.deb文件 sudo dpkg -i code***.deb 一些小小的…

仿微信图片查看器`WPF`实现`ListBox` 鼠标滑动批量选中与反选效果

看到微信中&#xff0c;上传图片时的图片查看功能可以通过手指长按并滑动实现多选&#xff0c;于是为解析实现思路&#xff0c;也通过WPF 使用ListBox 实现了一版案例。 参考效果 微信效果如下&#xff0c;支持图片单选和鼠标长按滑动实现批量操作。 WPF模仿效果&#xff1a…