容器化RDS:借助CSI扩展Kubernetes存储能力
-
容器化RDS:计算存储分离架构下的“Split-Brain”
成都创新互联公司企业建站,十余年网站建设经验,专注于网站建设技术,精于网页设计,有多年建站和网站代运营经验,设计师为客户打造网络企业风格,提供周到的建站售前咨询和贴心的售后服务。对于成都做网站、网站设计、外贸营销网站建设中不同领域进行深入了解和探索,创新互联在网站建设中充分了解客户行业的需求,以灵动的思维在网页中充分展现,通过对客户行业精准市场调研,为客户提供的解决方案。
-
容器化RDS:计算存储分离还是本地存储?
-
容器化RDS:你需要了解数据是如何被写"坏"的
-
容器化RDS:PersistentLocalVolumes和VolumeScheduling
-
现有 Kubernetes 存储插件系统问题
-
Container Storage Interface(CSI)
-
基于CSI 和分布式文件系统实现在 MySQL 的 Volume 动态扩展
-
对 CSI 的展望
原名 | 简称 |
容器编排系统 | CO. |
存储提供者 | SP. |
存储插件接口 | Volume Plugin Interface |
存储驱动 | Volume Driver |
容器存储接口 Container Storage Interface | CSI |
如有遗漏,不吝赐教。
现有 Kubernetes 存储插件系统问题
可供选的容器编排系统(后面简称 CO.)不少,除去 Kubernetes 还有 Mesos、Swarm、Cloud Foundry。以 Kubernetes 为例,其通过 PersistentVolume 抽象对以下存储的支持:
-
GCEPersistentDisk
-
AWSElasticBlockStore
-
AzureFile
-
Azuredisk
-
FC(Fibre Channel)**
-
FlexVolume
-
Flocker
-
NFS
-
iSCSI
-
RBD(Ceph Block Device)
-
CephFS
-
Cinder(OpenStack block storage)
-
GlusterFS
-
VsphereVolume
-
Quobyte Volumes
-
HostPath
-
VMware Photon
-
Portworx Volumes
-
ScaleIO Volumes
-
StorageOS
-
VolumePlugin
-
PersistentVolumePlugin
-
DeletableVolumePlugin
-
ProvisionableVolumePlugin
-
ExpandableVolumePlugin
-
Provisioner
-
Deleter
以上接口并不需要全部实现,其中 VolumePlugin[1] 是必须实现的接口。
系统架构图如下:
这种方式为 Kubernetes 提供了丰富的存储支持列表,但是在具体实现上,SP. Volume Driver 代码也在 Kubernetes 代码仓库(又叫in-tree),它带来几个显著的问题。
从 Kubernetes 的角度看:
-
需要在 Kubernetes 中给各个 SP. 赋权以便他们能够提交代码到仓库;
-
Volume Driver 由各个 SP. 提供,Kubernetes 的开发者并不了解每个细节,导致这些代码难于维护和测试;
-
Kubernetes 的发布节奏和各位 SP. Volume Driver 的节奏并不一致,随着支持的 SP. 增多,沟通、维护、测试成本会越来越高;
-
这些 SP. Volume Driver 并不是 Kubernetes 本身需要的。
从 SP. 的角度看:
-
提交一个新特性或者修复 bug,都需要提交代码到 Kubernetes 仓库,在本地编译 Kubernetes 的都知道,这个过程是很痛苦的,这对 SP. 而言是完全不必要的成本。
Container Storage Interface(CSI)
基于这些问题和挑战,CO 厂商提出 Container Storage Interface 用来定义容器存储标准,它独立于 Kubernetes Storage SIG,由 Kubernetes、Mesos、Cloud Foundry 三家一起推动。个人理解它有如下2个核心目标:
-
提供统一的 CO. 和 SP. 都遵循的容器存储接口。
-
一旦 SP. 基于 CSI 实现了自身的 Volume Driver,即可在所有支持 CSI 的 CO 中平滑迁移。
还有一个附带的好处是,一旦 CO. 和 SP. 都遵循 CSI,就便于将 Volume Driver 解耦到 Kubernetes 的外部(又叫 out-of-tree)。Kubernetes 只用维护 CSI 接口,不用再维护 SP. 的具体实现,维护成本大大降低。
CSI 优化下的架构图:
可以看到,Kubernetes 和 SP. 从此泾渭分明,但事情并没有那么简单,借用一位大神说的:The performance improvement does not materialize from the air, it comes with code complexity increase.和性能一样,扩展性和解耦也不是凭空出现。上图可进一步细化成下图:
明显的变化有:
-
Controller Plane、Kubelet 不再直接与 Volume Driver 交互,引入 external-provisioner 和 external-attacher 完成该工作;
-
SP. Volume Driver 会由独立的容器运行;
-
为了实现 external-provisioner、external-attacher 和 SP. Volume Driver 的交互引入 gRPC 协议(标红箭头)。
还有一些其他的变化:
-
在 Kubernetes 端 引入新的对象:
CSIPersistentVolumeSource:该类型 PV 由 CSI Driver 提供
VolumeAttachment:同步 Attach 和 Dettach 信息
-
引入新的名称:
mount/umount:NodePublishVolume/NodeUnpublishVolume
attach/dettach:ControllerPublishVolume/ControllerUnpublishVolume
Note:Kubernetes 适配 CSI 设计文档[3]。
可见,为了达到这个目标,相比原来复杂不少,但收益巨大,Kubernetes 和 SP. 的开发者可以专注于自身的业务。
即便如此,在现有的 CSI 上做扩展有时也在所难免。
基于 CSI 和分布式文件系统实现在 MySQL 上的 Dynamically Expand Volume
Kubernetes 存储子系统已经非常强大,但是还欠缺一些基础功能,譬如支持 Expand Volume (部分 Storage Vendor 支持)和 SnapShot,尤其是 Expand Volume,这是必须的功能,因为随着业务的变化,容量的增加在所难免,一旦容量接近阈值,若以迁库的方式扩展存储容量,成本太高。但现状并不乐观,Kubernetes 1.10.2 使用 CSI 0.2.0,其并不包含 Expand Volume 接口,这意味着即便底层的存储支持扩容,Kubernetes 也无法使用该功能,所以我们需要做点 hard code 实现该功能:
-
扩展 CSI Spec
-
扩展 CSI Plugin
-
基于 CSI Spec 实现 Storage Driver
-
演示
-
其他
扩展 CSI Spec
前面提到,在 CSI 中引入了 gRPC,个人理解在 CSI 的场景有如下3个优点:
-
基于 protobuf 定义强类型结构,便于阅读和理解
-
通过 stub 实现远程调用,编程逻辑更清晰
-
支持双工和流式,提供双向交互和实时交互
网络上介绍 gRPC 和 protobuf 的文章很多,这里不赘述。
通过 gRPC,实现 CSI 各个组件的交互。为支持 expand volume 接口,需要修改 csi.proto,在 CSI 0.2.0 的基础上添加需要的 rpc,重点如下:
CSI Driver 实现如下所有接口:
CreateVolume
DeleteVolume
ControllerPublishVolume
ControllerUnpublishVolume
ValidateVolumeCapabilities
ListVolumes
GetCapacity
ControllerGetCapabilities
RequiresFSResize
ControllerResizeVolume
这里涉及到比较复杂的调试和适配工作,还有一些其他的工作:
-
定义 CSI 对应的 StorageClass,并设置 allowVolumeExpansion 为 true
-
启用 Feature Gates:ExpandPersistentVolumes
-
新增 Admission Control:PersistentVolumeClaimResize
-
……
通过扩展 Container Storage Interface 0.2.0,我们在Kubernetes 1.10.2 上实现了在线扩容文件系统扩容。对 MySQL 实例制造两种类型工作负载:
-
通过键值更新和查询
-
批量数据加载数据
-
读数一:MySQL QPS 在正常波动范围内;
-
读数二:持续批量加载数据,MySQL 文件系统容量不断变大;
-
读数三:在20分钟内,在线动态扩容 Volume 和 Filesystem 2 次, 过程高效平滑。
其他
工作到这里基本结束,要改动的地方不少,客观上并不简单。如果没有 Kubernetes 和 CSI,难度会更大。
通过此方法可以完成对其他 Storage Vendor 的扩展,譬如 FCSan、iSCSI。
对 CSI 的展望
目前 CSI 已发展到 0.2.0,0.3.0 也发布在即。
0.3.0 中呼声最高的特性是 Snapshot。借助该功能,可以实现备份和异地容灾。但是为了实现该功能,在 Kubernetes 现有的 Control-Plane 上还要添加新的 Controller,客观上,复杂度会进一步提高。同时,部分 in-tree Volume Driver 已通过 CSI 迁移到外部,考虑到 Kubernetes 整体的发布节奏和 API 的稳定性,个人觉得节奏不会太快。
除此之外,CSI 可能还有更多工作要做。以一个高可用的场景为例,当一个 Node 发生故障时,CO 触发 Unmount->Dettach->Attach->Mount 的流程,配合 Pod 的漂移,借助 CSI 定义的接口,Unmount、Dettach、Attach、Mount 由SP. 自身现实,但是 Unmount->Dettach->Attach->Mount 的流程还是有 CO 控制,这个流程并不标准,但是对 workload 又至关重要。
又想起<人月神话>中的那句 “No Silver Bullet”。
相关链接:
-
https://github.com/kubernetes/kubernetes/blob/afa68cc28749c09f8655941b111e46d85689daf8/pkg/volume/plugins.go#L95
-
https://github.com/container-storage-interface/spec/blob/master/spec.md
-
https://github.com/kubernetes/community/blob/master/contributors/design-proposals/storage/container-storage-interface.md
-
https://github.com/container-storage-interface/spec/blob/master/csi.proto
-
https://docs.google.com/document/d/1kVrNwA2f4ite8_9QvCy-JQA_00hxGGMdER3I84dUDqQ/edit?usp=sharing
| 作者简介
熊中哲,沃趣科技产品及研发负责人
曾就职于阿里巴巴和百度,超过10年关系型数据库工作经验,目前致力于将云原生技术引入到关系型数据库服务中。
当前文章:容器化RDS:借助CSI扩展Kubernetes存储能力
文章分享:http://scyanting.com/article/jjdjhe.html