您好,登錄后才能下訂單哦!
Kubernetes幾種存儲方式性能對比是怎樣的,相信很多沒有經驗的人對此束手無策,為此本文總結了問題出現的原因和解決方法,通過這篇文章希望你能解決這個問題。
展示了一個簡單的存儲對比,使用未經性能優化的多種存儲提供的存儲卷進行測試和比較。
忽略 Azure 的原生 PVC 或 hostPath
,我們可以得出如下測試結果:
Portworx 是 AKS 上最快的容器存儲。
Ceph 是私有云集群上最快的開源存儲后端。對公有云來說,其操作太過復雜,這些多余的復雜性并沒有能提供更好的測試表現。
OpenEBS 的概念很棒,但是其后端需要更多優化。
如果你正在運行 Kubernetes,你可能正在使用,或者準備使用動態供給的塊存卷 ,而首當其沖的問題就是為集群選擇合適的存儲技術。這個事情并不能用一個簡單的測試來做出簡單的回答,告訴你目前市面上最好的技術是什么。存儲技術的選擇過程中,集群上運行的負載類型是一個重要的輸入。對于裸金屬集群來說,需要根據實際用例進行選擇,并集成到自己的硬件之中。公有云中的托管 K8s,例如 AKS、EKS 或者 GKE,都具有開箱可用的塊存儲能力,然而這也不見得就是最好的選擇。有很多因素需要考慮,比如說公有云的 StorageClass 的故障轉移時間太長。例如在 一個針對 AWS EBS 的故障測試中,加載了卷的 Pod 用了超過五分鐘才成功的在另一個節點上啟動。Portworx 或者 OpenEBS 這樣的云原生存儲產品,正在嘗試解決這類問題。
目標是使用最常見的 Kubernetes 存儲方案,進行基本的性能對比。我覺得在 Azure AKS 上使用下列后端:
AKS 原生 Storageclass:Azure native premium
使用 cStor 后端的 OpenEBS
Portworx
Heketi 管理的 Gluster
Rook 管理的 Ceph
現在我們來介紹每種存儲后端,并交代一下安裝過程,然后進入 AKS 測試環境進行測試,最后得出結果。
這一節中介紹測試中用到的存儲方案,包含安裝過程以及該方案的優缺點。
我選擇這一方案的動機是以此作為所有測試的基線。這個方案 應該 提供最佳性能。Azure 動態的創建托管磁盤,并把它們映射到 K8s 的虛擬機中,最終成為 Pod 的存儲卷。
這個方案很方便,什么多余的步驟都不需要。創建一個新的 AKS 集群之后,就自動提供了兩個預定義的 StorageClass,分別是 default
和 managed-premium
,premium 使用的是基于 SSD 的高性能低延遲磁盤。
$ kubectl get storageclasses NAME PROVISIONER AGEdefault(default) kubernetes.io/azure-disk 8mmanaged-premium kubernetes.io/azure-disk 8m$ kubectl get pvc NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE dbench-pv-claim Bound pvc-e7bd34a4-1dbd-11e9-8726-ae508476e8ad 1000Gi RWO managed-premium 10s$ kubectl get po NAME READY STATUS RESTARTS AGE dbench-w7nqf 0/1ContainerCreating029s
AKS 開箱即用。
故障轉移非常緩慢,有時需要十分鐘以后,存儲卷才能重新掛載到不同節點上的 Pod 里。
對我來說 OpenEBS 是個全新事物,因此我很有興趣做他的測試。他提出了一個新的 Container Attached Storage(容器掛載存儲) 概念,這是一個基于微服務的存儲控制器,以及多個基于微服務的存儲副本。他和 Portworx 同樣,屬于云原生存儲分類的成員。
它是一個完全開源的方案,目前提供兩種后端——Jiva 和 cStor。我最開始選擇的是 Jiva,后來切換到 cStor。cStor 有很多長處,例如他的控制器和副本被部署到單一的 OpenEBS 所在的命名空間之中,能夠管理原始磁盤等。每個 K8s 卷都有自己的存儲控制器,能在節點存儲容量的許可范圍內對存儲進行擴展。
在 AKS 上的安裝非常容易。
連接到所有 K8s 節點上,安裝 iSCSI,這是因為他需要使用 iSCSI 協議在 K8s 節點之間進行 Pod 和控制器的連接。
apt-get update apt install -y open-iscsi
使用一個 YAML 定義在 K8s 集群上完成部署:
kubectl apply -f https://openebs.github.io/charts/openebs-operator-0.8.0.yaml
下一步,OpenEBS 控制器發現了節點中的所有磁盤。但是我必須手工標識出我附加的 AWS 托管磁盤。
$ kubectl get disk NAME AGE disk-184d99015253054c48c4aa3f17d137b15mdisk-2f6bced7ba9b2be230ca5138fd0b07f15mdisk-806d3e77dd2e38f188fdaf9c46020bdc5m
然后把這些磁盤加入 StoragePoolClaim,這個對象會在 StorageClass 中進行引用:
---apiVersion: storage.k8s.io/v1 kind:StorageClassmetadata: name: openebs-custom annotations: openebs.io/cas-type: cstor cas.openebs.io/config???? - name:StoragePoolClaim value:"cstor-disk"provisioner: openebs.io/provisioner-iscsi---apiVersion: openebs.io/v1alpha1 kind:StoragePoolClaimmetadata: name: cstor-disk spec: name: cstor-disk type: disk maxPools:3 poolSpec: poolType: striped disks: diskList: - disk-2f6bced7ba9b2be230ca5138fd0b07f1 - disk-806d3e77dd2e38f188fdaf9c46020bdc - disk-184d99015253054c48c4aa3f17d137b1
完成這些步驟之后,就可以用 K8s 的 PVC 來動態的創建存儲卷了。
開源
Maya 在資源使用的可視化方面做得非常好。可以在 K8s 中部署多個服務,方便的為集群的各方面數據設置監控和日志。對于排錯工作來說,這十分重要。
CAS 概念:我非常欣賞這一概念,我相信這是未來的趨勢。
OpenEBS 社區:在社區中我的任何問題都能在幾分鐘內得到解決。Slack 上的團隊非常有幫助。
不成熟:OpenEBS 還很年輕,目前還沒有發布穩定版。核心團隊還在進行后端的優化,未來幾個月里會對性能做出很大提升。
Kubelet 和存儲控制器之間的 iSCSI 連接是通過 K8s Service 進行的,這在 Tungsten Fabric 之類的 CNI 插件環境中可能會出問題。
需要在 K8s 節點上安裝額外的軟件(iSCSI),這對于托管集群來說非常不便。
注:OpenEBS 團隊對我的案例場景進行了調整:
https://github.com/kmova/openebs/tree/fio-perf-tests/k8s/demo/dbench
Portworx 是另一個面向 Kubernetes 的容器原生存儲方案,它專注于高度分布式的環境。這是一個主機可尋址的存儲,每個卷都直接映射到掛在的主機上。他提供了基于應用 I/O 類型的自動微調能力。 官方網站 提供了更多信息。不幸的是,它也是本文中唯一的非開源產品。然而它提供了 3 節點的免費試用。
在 AKS 上的安裝同樣簡單,我用了他們 網站 提供的生成器。
azure0
$ kubectl get pods -o wide -n kube-system -l name=portworx NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE portworx-g9csq 1/1Running014m10.0.1.66 aks-agentpool-20273348-2<none>portworx-nt2lq 1/1Running014m10.0.1.4 aks-agentpool-20273348-0<none>portworx-wcjnx 1/1Running014m10.0.1.35 aks-agentpool-20273348-1<none>
為 PVC 創建一個 StorageClass,定義高優先級,以及三個副本:
root@aks-agentpool-20273348-0:~# kubectl get storageclass -o yaml portworx-scapiVersion: storage.k8s.io/v1 kind:StorageClassmetadata: creationTimestamp:2019-01-28T21:10:28Z name: portworx-sc resourceVersion:"55332" selfLink:/apis/storage.k8s.io/v1/storageclasses/portworx-sc uid:23455e40-2341-11e9-bfcb-a23b1ec87092 parameters: priority_io: high repl:"3"provisioner: kubernetes.io/portworx-volume reclaimPolicy:DeletevolumeBindingMode:Immediate
部署方便:生成器包含配置細節。
不像 Ceph 和 Glusterfs 那樣需要進行額外配置。
云原生存儲:公有云和裸金屬都可以運行。
存儲級別感知和應用感知的 I/O 微調。
閉源:商業解決方案
GlusterFS 是知名的開源存儲方案,是由 Redhat 提供的開源存儲方案。 Heketi 是 GlusterFS 的 RESTful 卷管理界面。它提供了易用的方式為 GlusterFS 卷提供了動態供給的功能。如果沒有 Heketi 的輔助,就只能手工創建 GlusterFS 卷并映射到 K8s PV 了。關于 GlusterFS 的更多信息,請閱讀 官方文檔 。
根據 Heketi 的 快速入門 文檔進行部署。
參照 樣例 ,創建一個包含磁盤和主機名的拓撲文件。
Heketi 主要的開發和測試都在基于 RHEL 的操作系統上,我在 AKS 上使用 Ubuntu 主機時,出現了內核模塊路徑錯誤的問題,我提交了一個 PR 來修正這個問題。
~~~ +++ b/deploy/kube-templates/glusterfs-daemonset.yaml @@ -67,7 +67,7 @@ spec: mountPath: “/etc/ssl” readOnly: true – name: kernel-modules
name: kernel-modules hostPath:
mountPath: “/usr/lib/modules”
mountPath: “/lib/modules” readOnly: true securityContext: capabilities: {} @@ -131,4 +131,4 @@ spec: path: “/etc/ssl”
path: “/usr/lib/modules”
path: “/lib/modules” ~~~
我在 AKS 環境中遇到的另一個問題是一個非空磁盤,所以我用 wipefs
為 glusterfs 進行清理。這個磁盤并未用過。
$ wipefs -a /dev/sdc /dev/sdc: 8 bytes were erased at offset 0x00000218 (LVM2_member): 4c 56 4d 32 20 30 30 31
最后運行 gk-deploy -g -t topology.json
,會在每個節點上運行 Heketi 控制器管理之下的 GlusterFS Pod。
$ kubectl get po -o wide NAME READY STATUS RESTARTS IP NODE NOMINATED NODE glusterfs-fgc8f 1/1Running010.0.1.35 aks-agentpool-20273348-1glusterfs-g8ht6 1/1Running010.0.1.4 aks-agentpool-20273348-0glusterfs-wpzzp 1/1Running010.0.1.66 aks-agentpool-20273348-2heketi-86f98754c-n8qfb 1/1Running010.0.1.69 aks-agentpool-20273348-2
然后我遇到了新問題。K8s 控制面無法使用 Heketi 的 restURL
。我測試了一下 kube dns 的記錄,pod IP 和 svc IP 都沒有生效。最后只能手工使用 Heketi CLI 來創建存儲卷。
$ export HEKETI_CLI_SERVER=http://10.0.1.69:8080$ heketi-cli volume create --size=10--persistent-volume --persistent-volume-endpoint=heketi-storage-endpoints | kubectl create -f -persistentvolume/glusterfs-efb3b155 created $ kubectl get pv NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE glusterfs-efb3b155 10Gi RWX RetainAvailable
然后把現存 PV 映射為 PVC,加載給測試 工具 進行測試。
kind:PersistentVolumeClaimapiVersion: v1 metadata: name: glusterfs-efb3b155 spec: accessModes: -ReadWriteMany storageClassName:"" resources: requests: storage:10Gi volumeName: glusterfs-efb3b155
$ kubectl get pvc NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE glusterfs-efb3b155 Bound glusterfs-efb3b155 10Gi RWX 36m
Heketi 的更多輸出:
$ gluster volume info vol_efb3b15529aa9aba889d7900f0ce9849VolumeName: vol_efb3b15529aa9aba889d7900f0ce9849Type:ReplicateVolume ID:96fde36b-e389-4dbe-887b-baae32789436Status:StartedSnapshotCount:0Number of Bricks:1 x 3=3Transport-type: tcpBricks:Brick1:10.0.1.66:/var/lib/heketi/mounts/vg_5413895eade683e1ca035760c1e0ffd0/brick_cd7c419bc4f4ff38bbc100c6d7b93605/brickBrick2:10.0.1.35:/var/lib/heketi/mounts/vg_3277c6764dbce56b5a01426088901f6d/brick_6cbd74e9bed4758110c67cfe4d4edb53/brickBrick3:10.0.1.4:/var/lib/heketi/mounts/vg_29d6152eeafc57a707bef56f091afe44/brick_4856d63b721d794e7a4cbb4a6f048d96/brickOptionsReconfigured:transport.address-family: inet nfs.disable: on performance.client-io-threads: off $ kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE heketi ClusterIP192.168.101.75<none>8080/TCP 5hheketi-storage-endpoints ClusterIP192.168.103.66<none>1/TCP 5h$ kubectl get endpoints NAME ENDPOINTS AGE heketi 10.0.1.69:80805hheketi-storage-endpoints 10.0.1.35:1,10.0.1.4:1,10.0.1.66:15hkubernetes 172.31.22.152:4431droot@aks-agentpool-20273348-0:~# kubectl get endpoints heketi-storage-endpoints -o yamlapiVersion: v1 kind:Endpointsmetadata: creationTimestamp:2019-01-29T15:14:28Z name: heketi-storage-endpoints namespace:default resourceVersion:"142212" selfLink:/api/v1/namespaces/default/endpoints/heketi-storage-endpoints uid:91f802eb-23d8-11e9-bfcb-a23b1ec87092 subsets:- addresses: - ip:10.0.1.35 - ip:10.0.1.4 - ip:10.0.1.66 ports: - port:1 protocol: TCP
久經考驗的存儲方案。
比 Ceph 輕量。
Heketi 在公有云上表現不佳。在私有云上表現良好,安裝會方便一些。
并非為結構化數據設計,例如 SQL 數據庫。然而可以使用 GlusterFS 為 數據庫 提供備份和恢復支持。
我在 OpenStack 私有云上嘗試過安裝和運行 Ceph。它需要為特定硬件定制參數,根據數據類型設計 pg 組、SSD 分區和 CRUSH 圖等。所以第一次聽說在 3 節點的 K8s 集群上運行 Ceph 的時候,我不太相信它能工作。結果 Rook 的編排工具讓我印象深刻,它把所有的步驟和 K8s 的編排能力結合在一起,讓安裝變得非常簡便。
Rook 的缺省安裝無需任何特定步驟,如果沒什么高級配置,會非常簡單。
我使用的是 Ceph 快速入門指南
為 AKS 配置 FLEXVOLUME_DIR_PATH
,這是因為它需要 /etc/kubernetes/volumeplugins/
,而不是 Ubuntu 中缺省的 /usr/libexec
,沒有這個步驟,Kubelet 就 無法加載 PVC 了。
~~~ diff –git a/cluster/examples/kubernetes/ceph/operator.yaml b/cluster/examples/kubernetes/ceph/operator.yaml index 73cde2e..33f45c8 100755 — a/cluster/examples/kubernetes/ceph/operator.yaml +++ b/cluster/examples/kubernetes/ceph/operator.yaml @@ -431,8 +431,8 @@ spec: # – name: AGENT_MOUNT_SECURITY_MODE # value: “Any” # Set the path where the Rook agent can find the flex volumes
# – name: FLEXVOLUME_DIR_PATH
# value: “
“
– name: FLEXVOLUME_DIR_PATH
value: “/etc/kubernetes/volumeplugins” # Set the path where kernel modules can be found # – name: LIB_MODULES_DIR_PATH # value: “
“ ~~~
還要在 deviceFilter
中指定要使用的設備,這里是 /dev/sdc
。
~~~ diff –git a/cluster/examples/kubernetes/ceph/cluster.yaml b/cluster/examples/kubernetes/ceph/cluster.yaml index 48cfeeb..0c91c48 100755 — a/cluster/examples/kubernetes/ceph/cluster.yaml +++ b/cluster/examples/kubernetes/ceph/cluster.yaml @@ -227,7 +227,7 @@ spec: storage: # cluster level storage configuration and selection useAllNodes: true useAllDevices: false
deviceFilter:
deviceFilter: “^sdc” location: config: ~~~
安裝之后,創建一個 Ceph block pool,以及 StorageClass,使用如下配置。
apiVersion: ceph.rook.io/v1 kind:CephBlockPoolmetadata: name: replicapool namespace: rook-ceph spec: failureDomain: host replicated: size:3---apiVersion: storage.k8s.io/v1 kind:StorageClassmetadata: name: rook-ceph-block provisioner: ceph.rook.io/block parameters: blockPool: replicapool clusterNamespace: rook-ceph fstype: xfs reclaimPolicy:Retain
最后使用部署 工具 進行檢查。
ceph status cluster: id: bee70a10-dce1-4725-9285-b9ec5d0c3a5e health: HEALTH_OK services: mon:3 daemons, quorum c,b,a mgr: a(active) osd:3 osds:3 up,3in data: pools:0 pools,0 pgs objects:0 objects,0 B usage:3.0GiB used,3.0TiB/3.0TiB avail pgs:[root@aks-agentpool-27654233-0/]#[root@aks-agentpool-27654233-0/]#[root@aks-agentpool-27654233-0/]# ceph osd status+----+--------------------------+-------+-------+--------+---------+--------+---------+-----------+| id | host | used | avail | wr ops | wr data | rd ops | rd data | state |+----+--------------------------+-------+-------+--------+---------+--------+---------+-----------+|0| aks-agentpool-27654233-0|1025M|1021G|0|0|0|0| exists,up ||1| aks-agentpool-27654233-1|1025M|1021G|0|0|0|0| exists,up ||2| aks-agentpool-27654233-2|1025M|1021G|0|0|0|0| exists,up |+----+--------------------------+-------+-------+--------+---------+--------+---------+-----------+
在大型生產環境上的健壯存儲系統。
Rook 很好的簡化了生命周期管理。
復雜:更加重量級,也不太適合在公有云上運行。在私有云上的運行可能更加合適。
我用 3 個虛擬機創建了基本的 Azure AKS 集群。為了連接到 Premium SSD 上,我只能使用 type E 以上級別的虛擬機。因此我選擇了 Standard_E2s_v3 ,其上配備了 2 vCPU 以及 16GB 的內存。
在 AKS 集群所在的資源足中,可以看到所有的虛擬機、網絡接口等資源。在這里創建 3 個 1TB 的 Premium SSD 存儲,并手工掛載到每個虛擬機上。
這樣在每個實例上,我都有 1TB 的空磁盤。Azure 的頁面上,根據我們選擇的虛擬機和磁盤尺寸來看,性能應該有 5000 IOPS 以及 200MB/s 的吞吐量。最后一節會顯示我們的真實結果。
注意:每種存儲的結果并不能作為獨立的評估結果,但是其比較情況是可以參考的。有很多種對比測試的方法,這是最簡單的一種。
為了運行測試,我決定使用現成的測試工具 Dbench ,它是一個 k8s 的 YAML 文件,會使用 FIO 運行 8 個測試用例。可以在 Dockerfile 中 指定不同測試 :
隨機讀寫帶寬。
隨機讀寫 IOPS。
讀寫延遲。
順序讀寫。
混合讀寫 IOPS。
所有測試的結果可以在 Github 上找到。
隨機讀寫測試表明,GlusterFS、Ceph 以及 Portworx 的讀取性能比 AWS 本地盤的 hostPath
快了幾倍。讀緩存是罪魁禍首。GlusterFS 和 Portworx 的寫入更快,其效率直逼本地磁盤。
隨機 IOPS 測試中,Portworx 和 Ceph 表現最好。Portworx 在寫入方面獲得了接近 Azure 原生 PVC 的 IOPS。
延遲測試的結果比較有趣,Azure 原生 PVC 比多數其它存儲都差。Portworx 和 Ceph 表現最好。寫入方面,GlusterFS 要優于 Ceph。OpenEBS 的延遲相對來說非常的高。
順序讀寫的結果和前面的隨機測試差不多,然而 Cpeh 在讀取方面比 GlusterFS 快了一倍多。寫入結果基本一致,只有 OpenEBS 表現奇差。
最后一個測試用例檢查的是混合讀寫情況下的 IOPS,Portworx 和 Ceph 都給出了優于 Azure 原生 PVC 的結果。
本文展示了一個簡單的存儲對比,使用未經性能優化的多種存儲提供的存儲卷進行測試和比較。建議關注本文所述方法,不建議直接采用結果進行判斷。
忽略 Azure 的原生 PVC 或 hostPath
,我們可以得出如下測試結果:
Portworx 是 AKS 上最快的容器存儲。
Ceph 是私有云集群上最快的開源存儲后端。對公有云來說,其操作太過復雜,這些多余的復雜性并沒有能提供更好的測試表現。
OpenEBS 的概念很棒,但是其后端需要更多優化。
調整性能數據的測試規模應該會很有意思。另外值得關注的對比就是 CPU 和內存的消耗。我會持續關注,并分享更多。
看完上述內容,你們掌握Kubernetes幾種存儲方式性能對比是怎樣的的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。