有关于k8s中的CSI和CRI的有关知识
在 Kubernetes 中,CSI (Container Storage Interface) 和 CRI (Container Runtime Interface) 是两个关键的标准化接口,它们将 Kubernetes 核心组件与特定的底层实现解耦,提供了极大的灵活性和可扩展性。它们的作用截然不同:
-
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 就是项目经理给工程师团队(容器运行时)下达任务(创建/启动/停止容器等)和获取工作状态(容器日志/状态)的标准工作指令手册。
-
-
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 的核心特性和工作原理:
一、核心特性
-
基于 HTTP/2 协议
-
多路复用(Multiplexing):多个请求/响应在同一连接上并行传输。
-
二进制协议:高效压缩数据,性能远超 HTTP/1.x。
-
头部压缩(HPACK):减少网络开销。
-
流式传输(Streaming):支持客户端/服务端双向流。
-
-
使用 Protocol Buffers(Protobuf)
-
接口定义语言(IDL):通过
.proto
文件定义服务接口和数据结构。 -
高效序列化:二进制编码,体积小、解析快(比 JSON/XML 快 5-10 倍)。
-
跨语言支持:自动生成多语言代码(Go, Java, Python, C++, Rust 等)。
-
-
四种通信模式
模式 描述 适用场景 Unary RPC 一对一请求-响应(类似 REST) 简单查询 Server Streaming RPC 客户端发一个请求,服务端返回流式响应 服务端推送日志/实时数据 Client Streaming RPC 客户端发送流式请求,服务端返回一个响应 文件上传/批量处理 Bidirectional Streaming RPC 双向流式通信 实时聊天/游戏同步 -
高级功能
-
超时控制、错误处理、拦截器(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 |
四、典型应用场景
-
微服务间通信(替代 REST)
-
云原生基础设施
-
Kubernetes CRI(容器运行时)、CSI(存储)、CNI(网络)插件接口
-
etcd、Istio、Envoy 等底层通信
-
-
移动端与后端通信(低延迟、省流量)
-
实时流系统(如金融交易、游戏)
五、与 REST 对比
特性 | gRPC | REST/HTTP-JSON |
---|---|---|
协议 | HTTP/2(二进制) | HTTP/1.1(文本) |
数据格式 | Protobuf(二进制) | JSON/XML(文本) |
性能 | ⭐⭐⭐⭐⭐(高吞吐、低延迟) | ⭐⭐(解析开销大) |
接口规范 | 强类型(.proto 文件) | 弱类型(OpenAPI) |
流式支持 | 原生完善 | 有限(SSE/WebSocket) |
浏览器支持 | 有限(需 gRPC-Web) | 原生完善 |
六、学习资源
-
官方文档
-
Protobuf 语言指南
-
实践教程:
bash
# 安装编译工具 go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.28 go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.2
💡 提示:在 Kubernetes 中调试 gRPC 服务可使用工具 grpcui 或 grpcurl。
gRPC 已成为云原生时代的通信标准,理解其原理对开发高效分布式系统至关重要。