使用CSI和Kubernetes动态扩展卷

作者:Orain Xiong(WoquTech联合创始人)

Kubernetes本身内部有一个非常强大的存储子系统,涵盖了相当广泛的用例。而当计划使用Kubernetes构建产品级关系数据库平台时,我们面临着一个巨大的挑战:提供存储。本文介绍了如何扩展最新的Container Storage Interface 0.2.0并与Kubernetes集成,并演示了动态扩展卷容量的基本方面。

介绍

当我们专注于客户时,尤其是在金融领域,采用容器编排技术的情况大大增加。

他们期待开源解决方案来重新设计已经存在的整体应用程序,这些应用程序已经在虚拟化基础架构或裸机上运行了几年。

考虑到可扩展性和技术成熟程度,Kubernetes和Docker排在首位。但是将单片应用程序迁移到Kubernetes之类的分布式业务流程具有挑战性,关系数据库对于迁移至关重要。

关于关系数据库,我们应该注意存储。 Kubernetes本身内部有一个非常强大的存储子系统。它非常有用,涵盖了相当广泛的用例。计划在生产中使用Kubernetes运行关系数据库时,我们面临一个巨大的挑战:提供存储。仍有一些基本功能尚未实现。具体来说,是动态扩大交易量。听起来很无聊,但除创建,删除,安装和卸载之类的操作外,它是非常必要的。

当前,扩展容量仅适用于那些存储供应商:

  • gcePersistentDisk
  • awsElasticBlockStore
  • OpenStack煤渣
  • 糊精
  • rbd

In order to enable this feature, we should set feature gate ExpandPersistentVolumes true and turn on the PersistentVolumeClaimResize admission plugin. Once PersistentVolumeClaimResize has been enabled, resizing will be allowed by a Storage Class whose allowVolumeExpansion field is set to true.

不幸的是,即使基础存储提供者具有此功能,也无法通过容器存储接口(CSI)和Kubernetes动态扩展卷。

本文将给出CSI的简化视图,然后逐步介绍如何在现有CSI和Kubernetes上引入新的扩展卷功能。最后,本文将演示如何动态扩展卷容量。

容器存储接口(CSI)

为了更好地了解我们将要做什么,我们首先需要知道的是容器存储接口是什么。当前,Kubernetes中已经存在的存储子系统仍然存在一些问题。存储驱动程序代码在Kubernetes核心存储库中维护,很难测试。但除此之外,Kubernetes需要授予存储供应商许可,以将代码签入Kubernetes核心存储库。理想情况下,应在外部实施。

CSI旨在定义行业标准,该标准将使支持CSI的存储提供商能够在支持CSI的容器编排系统中使用。

该图描述了一种与CSI集成的高级Kubernetes原型:

csi图

  • 引入了三个新的外部组件以分离Kubernetes和存储提供程序逻辑
  • 蓝色箭头表示针对API服务器进行调用的常规方法
  • 红色箭头显示gRPC以针对Volume Driver进行调用

有关更多详细信息,请访问: //github.com/container-storage-interface/spec/blob/master/spec.md

扩展CSI和Kubernetes

为了实现在Kubernetes上扩展卷的功能,我们应该扩展几个组件,包括CSI规范,“树内”卷插件,external-provisioner和external-attacher。

扩展CSI规范

The feature of expanding volume is still undefined in latest CSI 0.2.0. The new 3 RPCs, including 需要FSResize and ControllerResizeVolume and NodeResizeVolume, should be introduced.

service Controller {
 rpc 创建卷 (CreateVolumeRequest)
   returns (CreateVolumeResponse) {}
……
 rpc 需要FSResize (RequiresFSResizeRequest)
   returns (RequiresFSResizeResponse) {}
 rpc ControllerResizeVolume (ControllerResizeVolumeRequest)
   returns (ControllerResizeVolumeResponse) {}
}

service Node {
 rpc NodeStageVolume (NodeStageVolumeRequest)
   returns (NodeStageVolumeResponse) {}
……
 rpc NodeResizeVolume (NodeResizeVolumeRequest)
   returns (NodeResizeVolumeResponse) {}
}

扩展“ In-Tree”卷插件

In addition to the extend CSI specification, the csiPlugin interface within Kubernetes should also implement expandablePlugin. The csiPlugin interface will expand PersistentVolumeClaim representing for ExpanderController.

type ExpandableVolumePlugin interface {
VolumePlugin
ExpandVolumeDevice(spec Spec, newSize resource.Quantity, oldSize resource.Quantity) (resource.Quantity, error)
需要FSResize() bool
}

实施音量驱动器

最后,为了抽象化实现的复杂性,我们应该将单独的存储提供程序管理逻辑硬编码为以下功能,这些功能在CSI规范中已明确定义:

  • 创建卷
  • 删除卷
  • ControllerPublishVolume
  • ControllerUnpublishVolume
  • ValidateVolumeCapabilities
  • 列表卷
  • 获取容量
  • ControllerGetCapabilities
  • 需要FSResize
  • ControllerResizeVolume

示范

让我们以具体的用户案例来演示此功能。

  • 为CSI存储预配器创建存储类
allowVolumeExpansion: true
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: csi-qcfs
parameters:
  csiProvisionerSecretName: orain-test
  csiProvisionerSecretNamespace: default
provisioner: csi-qcfsplugin
reclaimPolicy: Delete
volumeBindingMode: Immediate
  • Deploy CSI Volume Driver including storage provisioner csi-qcfsplugin across Kubernetes cluster

  • Create PVC qcfs-pvc which will be dynamically provisioned by storage class csi-qcfs

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: qcfs-pvc
  namespace: default
....
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 300Gi
  storageClassName: csi-qcfs
  • 创建MySQL 5.7实例以使用PVC qcfs-pvc
  • 为了反映完全相同的生产级别方案,实际上有两种不同类型的工作负载,包括:
    • 批量插入使MySQL消耗更多的文件系统容量
    • 浪涌查询请求
  • Dynamically expand volume capacity through edit pvc qcfs-pvc configuration

Prometheus和Grafana的集成使我们可以可视化相应的关键指标。

普罗米修斯

我们注意到中间的读数显示在批量插入期间MySQL数据文件的大小缓慢增加。同时,底部读数显示文件系统在大约20分钟内扩展了两次,从300 GiB扩展到400 GiB,然后扩展到500 GiB。同时,上半部分显示,扩展卷的整个过程立即完成,几乎不会影响MySQL QPS。

结论

无论运行什么基础结构应用程序,数据库始终是关键资源。拥有更高级的存储子系统以完全支持数据库需求至关重要。这将有助于推动云原生技术的更广泛采用。