> 技术文档 > 有关于k8s中的CSI和CRI的有关知识

有关于k8s中的CSI和CRI的有关知识

在 Kubernetes 中,CSI (Container Storage Interface) 和 CRI (Container Runtime Interface) 是两个关键的标准化接口,它们将 Kubernetes 核心组件与特定的底层实现解耦,提供了极大的灵活性和可扩展性。它们的作用截然不同:

  1. CRI (Container Runtime Interface) - 容器运行时接口

    • 作用: 管理容器的生命周期。它是 Kubelet(运行在每个节点上的 Kubernetes 代理)与容器运行时进行通信的接口。

    • 解决的问题: 在早期,Kubernetes 主要直接支持 Docker,代码耦合度高。随着其他容器运行时(如 containerd, CRI-O, Kata Containers, gVisor 等)的兴起,需要一种标准化的方式来让 Kubelet 与不同的运行时交互,而不需要修改 Kubelet 的核心代码。

    • 核心职责:

      • 创建、启动、停止和删除容器。

      • 管理容器镜像(拉取、列出、删除)。

      • 执行容器内的命令(kubectl exec)。

      • 获取容器的状态和日志(kubectl logs)。

      • 管理 Pod 沙箱环境(一组容器共享的运行环境,如网络命名空间、IPC 命名空间等)。

    • 常见实现 (容器运行时):

      • containerd: 目前最主流的运行时,由 Docker 分离出来的核心组件,轻量高效。

      • CRI-O: 专为 Kubernetes CRI 设计优化的轻量级运行时。

      • Docker Engine (通过 dockershim,现已废弃): 旧版本 Kubernetes 通过一个名为 dockershim 的适配层支持 Docker。Kubernetes 1.20 开始废弃 dockershim,1.24 版本中正式移除。Docker 本身可以作为 containerd 的客户端继续使用,但 Kubelet 不再直接通过 dockershim 与 Docker 对话。

    • 类比: 想象 Kubelet 是项目经理,CRI 就是项目经理给工程师团队(容器运行时)下达任务(创建/启动/停止容器等)和获取工作状态(容器日志/状态)的标准工作指令手册。

  2. CSI (Container Storage Interface) - 容器存储接口

    • 作用: 管理外部存储卷的供应、挂载、卸载、快照、扩容等生命周期。它是 Kubelet 和 Controller Manager(主要是 PersistentVolume 控制器(PVC)和 Attach/Detach 控制器)与存储插件进行通信的接口。

    • 解决的问题: Kubernetes 早期通过 In-Tree 卷插件(代码直接编译进 Kubernetes 核心)支持各种存储系统(如 AWS EBS, GCE PD, NFS, iSCSI 等)。这种方式导致:

      • Kubernetes 核心代码臃肿,难以维护。

      • 添加新存储系统或为现有系统添加新功能需要修改 Kubernetes 核心代码并等待新版本发布。

      • 存储供应商需要将专有代码暴露在 Kubernetes 代码库中。

    • 核心职责: CSI 定义了一组 gRPC 调用,存储供应商需要实现这些调用。Kubernetes 组件通过这些调用要求存储插件执行操作:

      • 创建/删除存储卷 (Provisioning/Deleting Volumes): 对应 PersistentVolumeClaim 的创建和删除。

      • 将卷挂载/卸载到节点 (Attaching/Detaching Volumes): 使卷在特定节点上可用(通常涉及网络或块设备映射)。

      • 将卷挂载/卸载到容器路径 (Mounting/Unmounting Volumes): 将已挂载到节点的卷绑定到 Pod 中容器的指定目录。

      • 卷快照 (Volume Snapshots): 创建和恢复存储卷的快照。

      • 卷扩容 (Volume Expansion): 扩展存储卷的容量。

      • 卷统计 (Volume Statistics): 获取卷的使用情况(容量、IOPS 等)。

    • 组件: CSI 驱动通常由两部分组成:

      • CSI Controller Plugin: 通常以 Deployment 形式运行在控制平面节点上。负责需要集群范围视角的操作,如创建/删除卷、卷快照、卷扩容、卷挂载/卸载(Attach/Detach,如果由控制器负责的话)。

      • CSI Node Plugin: 通常以 DaemonSet 形式运行在每个工作节点上。负责需要节点本地视角的操作,如将卷挂载/卸载到节点文件系统(Mount/Unmount)、将卷挂载到 Pod 的容器内。

    • 常见实现 (存储系统): 几乎所有主要的云提供商(AWS EBS/EFS, GCP PD, Azure Disk/File)和存储厂商(NetApp, Dell EMC, Portworx, Rook/Ceph, Longhorn, NFS, iSCSI, LVM 等)都提供了 CSI 驱动。

    • 类比: 想象 Kubernetes 是数据中心管理员,CSI 就是管理员与各种仓库(云存储、SAN/NAS、分布式存储)沟通的标准物流协议。管理员通过这个协议告诉仓库:“请创建这个规格的货柜(卷)”,“把这个货柜运到 X 号厂房(节点)”,“把货柜里的货物放到 Y 车间的 Z 号工位(Pod 容器路径)”,“给这个货柜拍个快照”,“把这个货柜扩大一倍”。

总结关键区别:

特性 CRI (Container Runtime Interface) CSI (Container Storage Interface) 核心目的 管理容器生命周期 (创建、启动、停止、日志、执行命令) 管理外部存储卷生命周期 (创建、挂载、卸载、快照、扩容) 主要用户 Kubelet Kubelet, Controller Manager (PV Controller, Attach/Detach Controller) 对接组件 容器运行时 (containerd, CRI-O 等) 存储插件/驱动 (AWS EBS CSI Driver, NFS CSI Driver 等) 关注点 容器进程、镜像、沙箱环境 存储卷、块设备/文件系统、快照、容量 类比 项目经理给工程师团队下达任务的标准手册 数据中心管理员与仓库沟通的标准物流协议 特性 CSI (存储接口) CRI (容器运行时接口) 职责 管理持久化存储 管理容器生命周期 操作对象 存储卷(Volume) 容器(Container) K8s 组件交互 kube-controller-manager, kubelet kubelet 接口类型 gRPC 接口 gRPC 接口 典型实现 AWS EBS CSI, Ceph CSI containerd, CRI-O

简单来说:

  • CRI 负责告诉节点上的软件(容器运行时)如何运行和停止你的容器程序。

  • CSI 负责告诉云或存储系统如何为你的容器提供持久化的存储空间。

这两种接口是 Kubernetes 架构实现“插件化”和“可扩展性”的关键设计,使得 Kubernetes 能够支持多样化的容器运行时和存储后端,而无需修改其核心代码。

GRPC介绍

gRPC(gRPC Remote Procedure Call)是一个由 Google 开发的高性能、开源的 RPC(远程过程调用)框架。它基于现代技术栈构建,专为微服务、云原生应用和分布式系统设计。以下是 gRPC 的核心特性和工作原理:

一、核心特性

  1. 基于 HTTP/2 协议

    • 多路复用(Multiplexing):多个请求/响应在同一连接上并行传输。

    • 二进制协议:高效压缩数据,性能远超 HTTP/1.x。

    • 头部压缩(HPACK):减少网络开销。

    • 流式传输(Streaming):支持客户端/服务端双向流。

  2. 使用 Protocol Buffers(Protobuf)

    • 接口定义语言(IDL):通过 .proto 文件定义服务接口和数据结构。

    • 高效序列化:二进制编码,体积小、解析快(比 JSON/XML 快 5-10 倍)。

    • 跨语言支持:自动生成多语言代码(Go, Java, Python, C++, Rust 等)。

  3. 四种通信模式

    模式 描述 适用场景 Unary RPC 一对一请求-响应(类似 REST) 简单查询 Server Streaming RPC 客户端发一个请求,服务端返回流式响应 服务端推送日志/实时数据 Client Streaming RPC 客户端发送流式请求,服务端返回一个响应 文件上传/批量处理 Bidirectional Streaming RPC 双向流式通信 实时聊天/游戏同步
  4. 高级功能

    • 超时控制、错误处理、拦截器(Middleware)

    • 负载均衡、服务发现、认证(TLS/OAuth2)

    • 连接复用、健康检查

 二、工作原理(以kubernetes CSI为例子)

 1、定义接口(.proto文件)

CSI规范中定义的gRPC服务:

service Controller { rpc CreateVolume(CreateVolumeRequest) returns (CreateVolumeResponse) {} rpc DeleteVolume(DeleteVolumeRequest) returns (DeleteVolumeResponse) {}}
2、生成代码

用protoc编译器生成目标语言代码(如Go):

// 自动生成的 CSI 服务端接口type ControllerServer interface { CreateVolume(context.Context, *CreateVolumeRequest) (*CreateVolumeResponse, error) DeleteVolume(context.Context, *DeleteVolumeRequest) (*DeleteVolumeResponse, error)}
3、实现服务端

存储厂商实现这些接口:

type MyCSIDriver struct {}func (d *MyCSIDriver) CreateVolume(ctx context.Context, req *csi.CreateVolumeRequest) (*csi.CreateVolumeResponse, error) { // 调用 AWS API 创建 EBS 卷 volumeID := aws.CreateVolume(req.Parameters) return &csi.CreateVolumeResponse{VolumeId: volumeID}, nil}
4、客户端调用

Kubernetes 组件(如 external-provisioner)作为 gRPC 客户端:

conn, _ := grpc.Dial(\"unix:///csi/csi.sock\", grpc.WithInsecure())client := csi.NewControllerClient(conn)resp, _ := client.CreateVolume(ctx, &csi.CreateVolumeRequest{ Name: \"pvc-123\", CapacityRange: &csi.CapacityRange{RequiredBytes: 10 * 1024 * 1024 * 1024},})fmt.Println(\"Created Volume ID:\", resp.VolumeId)

 

三、为什么 Kubernetes 生态广泛使用 gRPC?

需求 gRPC 解决方案 跨语言通信 Protobuf 支持 10+ 语言 高性能 HTTP/2 + 二进制编码 + 多路复用 强类型接口 .proto 文件即契约 流式处理 原生支持 4 种流模式 可扩展性 拦截器机制支持中间件 安全 原生集成 TLS/SSL

四、典型应用场景

  1. 微服务间通信(替代 REST)

  2. 云原生基础设施

    • Kubernetes CRI(容器运行时)、CSI(存储)、CNI(网络)插件接口

    • etcd、Istio、Envoy 等底层通信

  3. 移动端与后端通信(低延迟、省流量)

  4. 实时流系统(如金融交易、游戏)


五、与 REST 对比

特性 gRPC REST/HTTP-JSON 协议 HTTP/2(二进制) HTTP/1.1(文本) 数据格式 Protobuf(二进制) JSON/XML(文本) 性能 ⭐⭐⭐⭐⭐(高吞吐、低延迟) ⭐⭐(解析开销大) 接口规范 强类型(.proto 文件) 弱类型(OpenAPI) 流式支持 原生完善 有限(SSE/WebSocket) 浏览器支持 有限(需 gRPC-Web) 原生完善

六、学习资源

  1. 官方文档

  2. Protobuf 语言指南

  3. 实践教程:

    bash

    # 安装编译工具go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.28go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.2

💡 提示:在 Kubernetes 中调试 gRPC 服务可使用工具 grpcui 或 grpcurl。

gRPC 已成为云原生时代的通信标准,理解其原理对开发高效分布式系统至关重要。