简介
如何接入 K8s 持久化存储?K8s CSI 实现机制浅析 未读
Kubernetes存储方案发展过程概述
- 最开始是通过Volume Plugin实现集成外部存储系统,即不同的存储系统对应不同的Volume Plugin。Volume Plugin实现代码全都放在了Kubernetes主干代码中(in-tree),也就是说这些插件与核心Kubernetes二进制文件一起链接、编译、构建和发布。
- 从1.8开始,Kubernetes停止往Kubernetes代码中增加新的存储支持。从1.2开始,推出了一种新的插件形式支持外部存储系统,即FlexVolume。FlexVolume类似于CNI插件,通过外部脚本集成外部存储接口,这些脚本默认放在
/usr/libexec/kubernetes/kubelet-plugins/volume/exec/
,需要安装到所有Node节点上。它是只针对 Kubernetes 的私有的存储扩展,目前已经处于冻结状态,可以正常使用但不再发展新功能了。 - 从1.9开始又引入了Container Storage Interface(CSI)容器存储接口,CSI 是公开的技术规范,是目前 Kubernetes 重点发展的扩展机制。
与容器服务 ACK 发行版的深度对话最终弹:如何通过 open-local 玩转容器本地存储
CSI规范
CSI 规范可以分为需要容器系统去实现的组件,以及需要存储提供商去实现的组件两大部分。
- 前者包括了存储整体架构、Volume 的生命周期模型、驱动注册、Volume 创建、挂载、扩容、快照、度量等内容,这些 Kubernetes 都已经完整地实现了,大体上包括以下几个组件:
- Driver Register:负责注册第三方插件,CSI 0.3 版本之后已经处于 Deprecated 状态,将会被Node Driver Register所取代。
- External Provisioner:调用第三方插件的接口来完成数据卷的创建与删除功能。
- External Attacher:调用第三方插件的接口来完成数据卷的挂载和操作。
- External Resizer:调用第三方插件的接口来完成数据卷的扩容操作。
- External Snapshotter:调用第三方插件的接口来完成快照的创建和删除。
- External Health Monitor:调用第三方插件的接口来提供度量监控数据。
- 后者定义了外部存储挂载到容器过程中所涉及操作的抽象接口和具体的通讯方式,主要包括以下三个 gRPC 接口:
- CSI Identity 接口:用于描述插件的基本信息,比如插件版本号、插件所支持的 CSI 规范版本、插件是否支持存储卷创建、删除功能、是否支持存储卷挂载功能等等。
- CSI Controller 接口:用于从存储系统的角度对存储资源进行管理,比如准备和移除存储(Provision、Delete 操作)、附加与分离存储(Attach、Detach 操作)、对存储进行快照等等。存储插件并不一定要实现这个接口的所有方法,对于存储本身就不支持的功能,可以在 CSI Identity 接口中声明为不提供。
- CSI Node 接口:用于从集群节点的角度对存储资源进行操作,比如存储卷的分区和格式化、将存储卷挂载到指定目录上,或者将存储卷从指定目录上卸载,等等。
CSI 插件本身是由一组标准的 Kubernetes 资源所构成,CSI Controller 接口是一个以 StatefulSet 方式部署的 gRPC 服务,CSI Node 接口则是基于 DaemonSet 方式部署的 gRPC 服务。
整体设计
CSI 插件体系的设计思想,就是把Dynamic Provision 阶段以及 Kubernetes 里的一部分存储管理功能(比如“Attach 阶段”和“Mount 阶段”,实际上是通过调用 CSI 插件来完成的),从主干代码里剥离出来,做成了几个单独的组件。这些组件会通过 Watch API 监听 Kubernetes 里与存储相关的事件变化,比如 PVC 的创建,来执行具体的存储管理动作。
CSI 的设计思想,把插件的职责从“两阶段处理”,扩展成了Provision、Attach 和 Mount 三个阶段。其中
- Provision 等价于“创建磁盘”。它的逆操作是移除(Delete)存储。
- Attach 等价于“挂载磁盘到虚拟机”,此时尽管设备还不能使用,但你已经可以用操作系统的fdisk -l命令查看到设备。它的逆操作是分离(Detach)存储设备。
- Mount 等价于“将该磁盘格式化后,挂载在 Volume 的宿主机目录上”,也就是操作系统中mount命令的作用。它的逆操作是卸载(Unmount)存储设备。