原文来自:
https://blog.fleeto.us/post/kubernetes-storage-performance-comparison/
摘要
本文展示了一个简单的存储对比,使用未经性能优化的多种存储提供的存储卷进行测试和比较。
忽略 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 原生 StorageClass
我选择这一方案的动机是以此作为所有测试的基线。这个方案 应该 提供最佳性能。Azure 动态的创建托管磁盘,并把它们映射到 K8s 的虚拟机中,最终成为 Pod 的存储卷。
这个方案很方便,什么多余的步骤都不需要。创建一个新的 AKS 集群之后,就自动提供了两个预定义的 StorageClass,分别是 default
和 managed-premium
,premium 使用的是基于 SSD 的高性能低延迟磁盘。
$ kubectl get storageclasses
NAME PROVISIONER AGE
default(default) kubernetes.io/azure-disk 8m
managed-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
对我来说 OpenEBS 是个全新事物,因此我很有兴趣做他的测试。他提出了一个新的 Container Attached Storage(容器挂载存储) 概念,这是一个基于微服务的存储控制器,以及多个基于微服务的存储副本。他和 Portworx 同样,属于云原生存储分类的成员。
它是一个完全开源的方案,目前提供两种后端——Jiva 和 cStor。我最开始选择的是 Jiva,后来切换到 cStor。cStor 有很多长处,例如他的控制器和副本被部署到单一的 OpenEBS 所在的命名空间之中,能够管理原始磁盘等。每个 K8s 卷都有自己的存储控制器,能在节点存储容量的许可范围内对存储进行扩展。
在 AKS 上运行
在 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-184d99015253054c48c4aa3f17d137b15m disk-2f6bced7ba9b2be230ca5138fd0b07f15m disk-806d3e77dd2e38f188fdaf9c46020bdc5m
- 然后把这些磁盘加入 StoragePoolClaim,这个对象会在 StorageClass 中进行引用:--- apiVersion: storage.k8s.io/v1 kind:StorageClass metadata: name: openebs-custom annotations: openebs.io/cas-type: cstor cas.openebs.io/config