天天看點

動手Lab|利用CSI和Kubernetes實作動态擴容

簡介

随着我們對客戶的關注,尤其是對金融領域的客戶,我們可以發現容器編排技術具有很大的發展空間。開發者們希望能通過開源解決方案來重新設計運作在虛拟化基礎設施和裸金屬上的獨立應用程式。   

對于可擴充性和技術成熟度兩方面,Kubernetes和Docker處于業内的頂端。關系資料庫對于遷移至關重要,但是将獨立應用程式遷移到像Kubernetes這樣的分布式編配十分具有挑戰性。

對于關系型資料庫來說,我們應該關注其存儲功能。Kubernetes本身具有強大的存儲子系統,其功能強大,包含用例廣泛。如果我們利用kubernetes建設關系資料庫平台,就需要面臨一個挑戰:建立資料存儲。但是Kubernetes還有一些基本的功能沒有實作,尤其是動态擴容。這聽起來很無聊,但是建立、删除、挂載和解除安裝等操作非常必要。

目前,擴容隻能與存儲提供程式一起使用,例如:

  • gcePersistentDisk
  • awsElasticBlockStore
  • OpenStack Cinder
  • glusterfs
  • rbd

為了啟用這個特性,我們需要設定feature-gate expandpersistentvolume為True,并打開PersistentVolumeClaimResize準入插件。一旦啟用了PersistentVolumeClaimResize,調整存儲大小的功能将被allowVolumeExpansion設定為True的存儲類開啟。

不幸的是,即使底層存儲提供程式具有此功能,通過容器存儲接口(CSI)和Kubernetes動态擴容依然不可用。

本文将給出CSI的簡化視圖,然後介紹如何在現有的CSI和Kubernetes上引入一個新的擴充卷特性。最後,本文将示範如何動态地擴容。

容器存儲接口(CSI)

為了更好地了解我們之後的工作,首先我們需要知道容器存儲接口是什麼。目前來看,Kubernetes現有的存儲子系統依然存在很多問題。存儲驅動程式代碼維護在Kubernetes core存儲庫中,這一問題使測試十分不便。但除此之外,Kubernetes還需要授權存儲供應商将代碼簽入Kubernetes核心存儲庫。但是理想情況下,這種需求應該在外部實作。CSI的設計目的是定義一個行業标準,該标準将使支援CSI的容器編排系統可用的存儲提供者能夠使用CSI。

這張圖描繪了一種與CSI結合的進階Kubernetes原型:

  • 引入了三個新的外部元件來解耦Kubernetes和存儲提供程式邏輯
  • 藍色箭頭表示對API伺服器調用的正常方法
  • 紅色箭頭表示gRPC調用卷驅動程式
  • 詳見:https://github.com/container-storage-interface/spec/blob/master/spec.md

擴充CSI和Kubernetes

為了實作在Kubernetes上擴充卷的功能,我們應該擴充多個元件,包括CSI規範、“In-Tree”卷插件、外部供應器和外部連接配接器。

擴充CSI規範

最新的CSI 0.2.0中還沒有定義擴充量的特性。應該引入新的3個rpc,包括RequiresFSResize,ControllerResizeVolume和NodeResizeVolume。

service Controller {
rpc CreateVolume (CreateVolumeRequest)
 returns (CreateVolumeResponse) {}
……
rpc RequiresFSResize (RequiresFSResizeRequest)
 returns (RequiresFSResizeResponse) {}
rpc ControllerResizeVolume (ControllerResizeVolumeRequest)
 returns (ControllerResizeVolumeResponse) {}
}
service Node {
rpc NodeStageVolume (NodeStageVolumeRequest)
 returns (NodeStageVolumeResponse) {}
……
rpc NodeResizeVolume (NodeResizeVolumeRequest)
 returns (NodeResizeVolumeResponse) {}
}           

擴充“In-Tree”卷插件

為了擴充CSI規範,csiPlugin接口需要在Kubernetes上實作。csiPlugin接口将會擴充PersistentVolumeClaim用來代理ExpanderController。

type ExpandableVolumePlugin interface {
VolumePlugin
ExpandVolumeDevice(spec Spec, newSize resource.Quantity, oldSizeresource.Quantity) (resource.Quantity, error)
RequiresFSResize() bool
}           

實作盤卷驅動

最後,為了抽象實作的複雜性,我們應該将單獨的存儲提供程式管理邏輯寫死到CSI規範中定義的以下函數中:

  • CreateVolume
  • DeleteVolume
  • ControllerPublishVolume
  • ControllerUnpublishVolume
  • ValidateVolumeCapabilities
  • ListVolumes
  • GetCapacity
  • ControllerGetCapabilities
  • RequiresFSResize
  • 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           
  • 跨Kubernetes叢集部署CSI卷驅動程式,包括存儲供應器CSI -qcfsplugin
  • 建立将由存儲類csi-qcfs動态提供的PVC qcfs-pvc
  • 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消耗更多的檔案系統容量
  • 增加查詢請求
  • 通過編輯pvc qcfs-pvc配置動态擴充容量

Prometheus和Grafana的內建使我們可視化相應的關鍵名額。

我們注意到中間的讀數顯示MySQL資料檔案大小在批量插入時緩慢增加。同時,底部讀數顯示檔案系統在大約20分鐘内擴充了兩次,從300G擴充到400G,然後是500G。同時,從上面的讀數可以看出,整個擴容過程立即完成,對MySQL QPS影響不大。

結論:

無論基礎設施應用程式運作在何處,資料庫始終是一個關鍵資源。用進階的存儲子系統來完全支援資料庫需求非常重要。這将有助于推動更廣泛地采用雲本地技術。

本文轉移K8S技術社群

動手Lab|利用CSI和Kubernetes實作動态擴容