Kubernetes PV/PVC 性能比较
如果正在运行Kubernetes,则可能会使用或想要使用卷进行块存储通过动态配置。最大的难题是为的集群选择正确的存储技术。没有简单的答案或单一测试,它可以告诉什么是市场上最好的技术。实际上,这很大程度上取决于要运行的工作负载的类型。对于裸机集群,与公共云托管的k8s集群相比,需要选择正确的选项,并将其集成在自己的硬件上。由AKS,EKS或GKE提供的由公有云管理的k8s带有块存储开箱即用,但这并不意味着它是最佳选择。在许多情况下,默认公共云存储类的故障转移时间花费的时间太长。例如,在附加了Pod的Pod的AWS EBS中测试失败的VM超过5分钟在另一个节点上重新联机。因此,像Portworx或OpenEBS这样的云原生存储正在尝试解决此类问题。
我的目标是采用Kubernetes可用的最常见的存储解决方案,并准备基本的性能比较。使用以下后端在Azure AKS上执行所有测试:
- AKS 原生存储类 (native) - Azure native premium
- AWS 云硬盘 (pass through)—带有附加的Azure托管磁盘的Azure hostPath
- cStore 管理的 OpenEBS
- Portworx
- Heketi 管理的 Gluster
- Rook 管理的 Cook
- OpenEBS MayaStor
- Longhorn
现在,让我们介绍每个存储后端及其安装说明,然后我们将介绍所使用的AKS测试群集环境,并在最后显示结果。
存储部署
本节介绍测试中使用的存储解决方案。它描述了安装过程以及每种解决方案的优点/缺点。
截至2019年1月,CNCF的存储格局和解决方案已更改。在存储的旗帜下,它已从30个解决方案增长到45个解决方案,同时还对公共云集成(如AWS EBS,Google永久磁盘或Azure磁盘存储)进行了治理扩展。一些新解决方案像Alluxio一样,更侧重于分布式文件系统或对象存储。我最初的目标,并且仍然是相同的,是评估块存储选项。让我们重新查看原始列表。
GlusterFS Heketi在性能结果上排名倒数第二,它的改进为零,并且大多数情况下是一个沉寂的项目(Heketi作为REST协调器而不是GlusterFS本身)。如果查看他们的官方GitHub,您会发现他们将其置于接近维护模式,并且云本地存储功能没有任何更新。
根据GIGAOM 2020报告, PortWorx仍然是Kubernetes的顶级商业存储解决方案。但是,从性能的角度来看,2.0版和2.5版之间的发行说明中并未对技术或体系结构进行重大更改。
最好的开源存储,通过Rook精心策划的CEPH,发布了2个新版本,并推出了一个新的CEPH版本,称为Octopus。Octopus对缓存机制进行了一些优化,并使用了更现代的内核接口(请参阅官方页面上的更多内容)。
唯一的主要体系结构更改发生在OpenEBS中,它引入了一个称为MayaStor的新后端。这个后端看起来非常有前途。
我还从社区收到了很多关于为什么我不测试Rancher的Longhorn的反馈。因此,我决定增加我的范围。
我评估了Longhorn和OpenEBS MayaStor,并将其结果与PortWorx,CEPH,GlusterFS和本机Azure PVC的先前结果进行了比较。以下小节介绍了添加到现有测试套件中的存储解决方案。它还描述了安装过程以及每种解决方案的优点/缺点。
Azure 原生存储类
之所以选择该存储类,是为了获得所有测试的基准。此存储类应提供最佳性能。Azure动态创建托管磁盘,并将其映射到具有k8s作为Pod卷的VM。
无需使用任何特殊功能。设置新的AKS群集时,将自动预定义2个存储类,分别称为“默认”和“托管-高级”。高级存储类(managed-premium SC)使用基于SSD的高性能和低延迟磁盘。
kubectl get storageclasses |
好处
- 傻瓜式开箱即用
缺点
- 故障转移情况下非常慢-有时需要将近10分钟才能将卷重新连接到其他节点上的Pod。
OpenEBS
OpenEBS 是一个全新的概念。它代表了新的容器附加存储(CAS)概念,其中是单个基于微服务的存储控制器和多个基于微服务的存储副本。它与Portworx一起属于云本机存储类别。
它是完全开源的,目前提供2个后端-Jiva和cStor。我从Jiva开始,然后切换到cStor。cStor进行了一些改进,因为控制器及其副本部署在单个名称空间(安装openebs的名称空间)中,或者它使用原始磁盘而不是格式化分区。每个k8s卷都有其自己的存储控制器,该存储可以在节点上可用存储容量的允许范围内扩展。
如何在AKS上获取它?
在AKS上安装非常容易。
- 我必须连接到所有k8s节点的控制台并安装iSCSI,因为它使用iSCSI协议在Pod和存储控制器与k8s节点之间进行连接。
apt-get update
apt install -y open-iscsi
2.然后,我将单个YAML定义应用于我的k8s集群
kubectl apply -f https://openebs.github.io/charts/openebs-operator-0.8.0.yaml
3.下一步,OpenEBS控制器在底层节点发现了我所有的磁盘。但是我必须手动确定附加的附加AWS托管磁盘。
kubectl get disk |
4.然后,我将这些磁盘添加到标准StorageClass引用的自定义k8s资源StoragePoolClaim中。
apiVersion: storage.k8s.io/v1 |
完成这些步骤后,我便能够通过k8s PVC动态地配置新卷。
好处
- 开源的
- Maya在资源使用可视化方面做得很好。可以轻松地在k8s集群中部署多个服务,并轻松设置监视和日志记录以收集集群的所有重要方面。这是调试的理想工具。
- CAS概念 – 我真的很喜欢容器存储背后的想法,应该是未来趋势。
- OpenEBS的社区—非常活跃
缺点
- 不成熟 - OpenEBS是一个相当新的项目,尚未达到稳定版本。核心团队仍在进行后端优化,这将在接下来的几个月中显着提高性能。
- Kubelet和存储控制器之间的iSCSI连接由k8s服务实现,这在某些覆盖网络CNI插件(例如Tungsten Fabric)中可能是一个问题。
- 需要在Kubernetes节点上安装其他软件(iSCSI),这使其在托管Kubernetes集群的情况下不切实际。
注意:OpenEBS团队在那里调整了我的测试用例场景https://github.com/kmova/openebs/tree/fio-perf-tests/k8s/demo/dbench
Portworx
Portworx是为kubernetes设计的另一种容器本机存储,专注于高度分布式的环境。它是主机可寻址的存储,其中每个卷都直接映射到其连接的主机。它提供基于应用程序I / O类型的自动调整。那里有更多信息。不幸的是,它是此博客中唯一的存储解决方案,它不是开源的。但是,它免费提供3个节点试用版。
如何在AKS上安装它?
在AKS上安装也非常容易。我使用了可在其网站上找到的Kubernetes spec生成器。
- 我选择了Portworx托管的etcd来简化设置,并填充了k8s 1.11.4版本。
- 我必须将数据网络接口修改为azure0,因为我使用的是具有高级联网功能的Azure cni。否则,Portworx将使用来自docker bridge的IP地址而不是VM接口。
- 最后一步,网站生成器向我提供了渲染的k8s YAML清单以应用于我的集群。
- 引导后,我在每个k8s节点上运行了Portworx Pod
root@aks-agentpool-20273348-0:~# kubectl get pods -o wide -n kube-system -l name=portworx |
我创建了具有高优先级和3个副本的存储类,然后可以配置k8s pvc。
root@aks-agentpool-20273348-0:~# kubectl get storageclass -o yaml portworx-sc |
好处
- 易于部署-具有详细配置的网站配置器。
- AKS集群的配置器,不需要任何其他步骤,如ceph或glusterfs。
- 云原生存储-它可以在硬件集群和公共云上运行。
- 存储感知的服务等级(COS)和应用感知的I / O调整
缺点
- 封闭源—专有供应商解决方案。
GlusterFS Heketi
GlusterFS是众所周知的开源存储解决方案。它沿用Ceph,这是RedHat支持的传统开源存储之一。Heketi是用于GlusterFS的RESTful卷管理接口。它提供了一种方便的方法来释放动态预配置的GlusterFS卷的功能。如果没有此访问权限,则必须手动创建GlusterFS卷并将其映射到k8s pv。可以在此处了解有关GlusterFS的更多信息。
如何在AKS上安装它?
我使用了默认的Heketi快速入门指南。
- 首先,我基于示例一创建了一个拓扑文件,其中包含磁盘和主机名。
- 由于Heketi主要是在基于RHEL的操作系统上开发和测试的,因此我在使用Ubuntu主机的AKS上遇到了一个问题,该内核路径错误。这是解决此问题的PR。
+++ b/deploy/kube-templates/glusterfs-daemonset.yaml |
3.我遇到的AKS的另一个问题是非空磁盘,因此我使用了擦拭来清理glusterfs的磁盘。该磁盘以前没有用于其他任何用途。
wipefs -a /dev/sdc
/dev/sdc: 8 bytes were erased at offset 0x00000218 (LVM2_member): 4c 56 4d 32 20 30 30 31
4.最后一步,我运行命令gk-deploy -g -t topology.json,该命令在由heketi控制器控制的每个节点上部署了glusterfs pod。
root@aks-agentpool-20273348-0:~# kubectl get po -o wide |
然后,我面临着动态配置的问题。Heketi restURL对于k8s控制平面不可用。我尝试了kube dns记录,pod IP和svc IP。两者都不起作用。因此,我不得不通过Heketi CLI手动创建卷。
root@aks-agentpool-20273348-0:~# export HEKETI_CLI_SERVER=http://10.0.1.69:8080 |
然后,必须为我的dbench工具将现有的PV映射到PVC。
kind: PersistentVolumeClaim |
从k8s上的Heketi Gluster安装获得更多输出。
gluster volume info vol_efb3b15529aa9aba889d7900f0ce9849 |
好处
- 成熟的存储解决方案
- 比Ceph更轻
缺点
- Heketi不是为公共管理的k8设计的。它与HW群集配合使用,安装更容易。
- 并非真正为“结构化数据”设计的,如SQL数据库。但是,可以使用Gluster备份和还原数据库。
Ceph Rook
我有与OpenStack私有云一起安装和运行Ceph的经验。它始终需要设计特定的硬件配置,根据数据类型生成pg组,配置日志SSD分区(在bluestore之前)并定义美眉贴图。因此,当我第一次听说在3节点k8s集群中使用Ceph时,我不敢相信它实际上可以工作。但是,Rook编排工具给我留下了深刻的印象,该工具为我完成了所有痛苦的步骤,并且与k8s编排一起提供了一种非常简单的方法来处理整个存储集群的安装。
如何在AKS上安装它?
在默认安装中,Rook不需要任何特殊步骤,并且如果不希望使用高级配置,它会非常平滑。
我使用了https://github.com/rook/rook/blob/master/Documentation/ceph-quickstart.md#ceph-storage-quickstartCeph快速入门指南
我必须配置特定于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: "<PathToFlexVolumes>"
+ - name: FLEXVOLUME_DIR_PATH
+ value: "/etc/kubernetes/volumeplugins"
# Set the path where kernel modules can be found
# - name: LIB_MODULES_DIR_PATH
# value: "<PathToLibModules>"
然后,我必须指定要在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块池和存储类
apiVersion: ceph.rook.io/v1
kind: CephBlockPool
metadata:
name: replicapool
namespace: rook-ceph
spec:
failureDomain: host
replicated:
size: 3
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: rook-ceph-block
provisioner: ceph.rook.io/block
parameters:
blockPool: replicapool
clusterNamespace: rook-ceph
fstype: xfs
reclaimPolicy: Retain
- 最后,我通过以下部署工具箱 https://github.com/rook/rook/blob/master/Documentation/ceph-toolbox.md 检查了状态
ceph status |
好处
- 在大型生产环境中运行的强大存储
- Rook使生命周期管理变得更加简单。
缺点
- 复杂-更重,甚至不适合在公共云中运行。最好只在配置正确的硬件群集上运行。
Longhorn
Longhorn是Rancher开发的用于Kubernetes的云原生分布式块存储。它主要是为微服务用例设计的。它为每个块设备卷创建一个专用的存储控制器,并跨存储在多个节点上的多个副本同步复制该卷。Longhorn在附加了卷的节点上创建了Longhorn Engine,并在复制了卷的节点上创建了副本。与其他类似,整个控制平面运行,而数据平面由Kubernetes编排。它是完全开源的。有趣的是,OpenEBS Jiva后端实际上基于Longhorn,或者至少最初是基于Longhorn的。主要区别在于Longhorn使用TCMU Linux驱动程序,而OpenEBS Jiva使用gotgt。
如何在AKS上获取它?
轻松安装到AKS
- 运行一个命令,它将所有组件安装到我的AKS集群中
kubectl apply -f https://raw.githubusercontent.com/longhorn/longhorn/master/deploy/longhorn.yaml |
2.将带有ext4文件系统的/dev/sdc1挂载到/var/lib/longhorn,这是卷存储的默认路径。最好在Longhorn安装之前将磁盘安装到那里。
Longhorn中节点磁盘配置的屏幕截图
3.最后一步是创建一个具有3个副本定义的默认存储类。
kubectl create -f https://raw.githubusercontent.com/longhorn/longhorn/master/examples/storageclass.yaml |
好处
- 开源的
- 云原生存储-它可以在硬件集群和公共云上运行。
- 易于部署-它只需要一个命令,并且“开箱即用”。
- 自动卷备份/还原到S3
缺点
- 它使用带有标准文件系统(ext4或xfs)的 /var/lib/longhorn 挂载点。每个卷就像一个磁盘文件。它可以随着许多控制器副本进行扩展,这会带来额外的网络开销。类似于我为OpenEBS Jiva描述的内容。
- 卷的挂载有时会花费很长时间(几分钟),并且显示错误并最终从中恢复。
OpenEBS MayaStor
OpenEBS表示容器附加存储(CAS)的概念,其中有一个基于微服务的存储控制器和多个基于微服务的存储副本。如果您阅读了2019年以来的上一篇博客文章,您会知道我在玩2个后端-Jiva和cStor。我最终使用了cStor,其性能结果确实很差。但是1.5年是很长的时间,OpenEBS团队引入了一个名为MayStor的新后端。
这是用Rust编写的云原生声明性数据平面,由2个组件组成:
- 以CSI概念和数据平面实现的控制平面。与以前的后端相比,主要区别在于利用NVMe而不是光纤网络(NVMe-oF),这有望为存储敏感型工作负载提供更好的IOPS和延迟。
- 这种存储设计的另一个优点是,它在主机用户空间中完全用尽了内核,并消除了由不同Linux发行版中可用的各种内核引起的差异。它根本不依赖于内核进行访问。在此博客中,我找到了一个很好的MayStor设计说明。
如何在AKS上获取它?
在AKS上进行安装非常简单,我遵循了他们的快速入门指南。
我必须在AKS群集中的每个节点上用512个数字配置2MB的大页面。
echo 512 | sudo tee /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages
但是我决定通过下面的k8s daemonset强制执行它们,而不是通过ssh进入我的每个实例。
apiVersion: apps/v1 |
2.我必须标记我的存储节点VM。
kubectl label node aks-agentpool-13651304-0 openebs.io/engine=mayastor |
3.然后,我应用了MayaStor存储库中指定的所有清单。
kubectl create -f nats-deployment.yaml |
4.当所有内容都在运行时,您可以开始创建用于卷置备的存储池。在我的情况下,我创建了3个存储池,每个节点有一个磁盘。
cat <<EOF | kubectl create -f - |
5.在继续进行StorageClass定义之前,检查每个存储池的状态很重要。状态必须是在线状态。
kubectl -n mayastor describe msp pool-on-node-1 |
6.该过程的最后一步是StorageClass定义,在其中,我配置了3个副本以具有与之前的存储解决方案相同的测试环境。
cat <<EOF | kubectl create -f - |
完成这些步骤后,我便能够通过K8s PVC动态预配新卷。
好处
- 具有强大社区支持的开源
- 云原生存储-它可以在硬件集群和公共云上运行。
- 与仅具有一个队列的SCSI相比,NVMe的使用旨在实现高度并行性,并且可以具有64K队列。
- 它使用NVMe-oF作为传输方式,可以在各种传输方式(nvmf,uring,pcie)上工作,并且完全在用户空间(目标用户和发起者)中完成。在用户空间中运行可以避免进行大量的系统调用,避免后期崩溃/崩溃等。而且它与内核无关,因此跨云或物理环境的linux类型之间没有区别。
缺点
- 早期版本-OpenEBS MayaStor的版本为0.3,因此它仍然存在一些限制和稳定性问题。但是,它们走在正确的轨道上,并且在几个月后,它可能是在K8中存储的首选。
- 需要在Kubernetes节点上支持2MB的大页面。但是,与1GB的大页面相比,几乎在所有物理或虚拟环境中都可用。
AKS测试环境
我预配置了带有3个VM的基本Azure AKS群集。为了能够连接托管的Premium SSD,我必须至少使用VM大小类型E。因此,我选择了Standard_E2s_v3(仅具有2个vCPU和16GB RAM)。
每个AKS群集都会自动配置第二个资源组(RG)MC_
这样,我可以在每个专用于测试的实例中获得1TB的空磁盘。根据Azure,根据VM和磁盘大小,估计性能应约为5000 IOPS和200 MB / s吞吐量。实数在最后一部分中可见。
测试结果
重要说明:单个存储性能测试的结果无法单独评估,但必须将测量结果相互比较。如何执行比较测试有多种方法,这是最简单的方法之一。
为了运行测试,我决定使用称为Dbench的现有负载测试器。它是pod的k8s部署清单,它在其中运行FIO,这是带有8个测试用例的Flexible IO Tester。在Docker映像的入口点中指定了测试:
- 随机读写带宽
- 随机读写IOPS
- 读写延迟
- 顺序读/写
- 混合读/写IOPS
所有测试的完整测试输出可在https://gist.github.com/pupapaik/76c5b7f124dbb69080840f01bf71f924
随机读写带宽
随机读取测试表明,GlusterFS,Ceph和Portworx的读取性能比Azure本地磁盘上的主机路径好几倍。OpenEBS和Longhorn的性能几乎是本地磁盘的两倍。原因是读取缓存。对于OpenEBS,写入速度最快,但是Longhorn和GlusterFS的值也几乎与本地磁盘相同。
随机读写IOPS
随机IOPS对于Portworx和OpenEBS表现出最好的结果。这次,OpenEBS在写入方面的IOPS比本地Azure PVC更好,这在技术上几乎是不可能的。它很可能与在测试用例运行的不同时间处的Azure存储负载有关。
读写延迟
延迟读取获胜者与上次相同。LongHorn和OpenEBS几乎拥有PortWorx的两倍。这仍然不错,因为本机Azure pvc比大多数其他经过测试的存储要慢。但是,在OpenEBS和Longhorn上写入期间的延迟更好。GlusterFS仍然比其他存储更好。
顺序读/写
顺序读/写测试显示的结果与随机测试相似,但是Ceph的读性能比GlusterFS高2倍。写入结果几乎都处于同一级别,OpenEBS和Longhorn达到了相同的水平。
混合读/写IOPS
最后一个测试用例验证了混合读写IOPS,在读写方面,OpenEBS交付的速度几乎是PortWorx或Longhorn的两倍。
结论
该博客显示了一个开放源代码项目在一年内可以有多大的变化!作为演示,让我们看一下在完全相同的环境下,OpenEBS cStor和OpenEBS MayaStor的IOPS的比较。
OpenEBS cStor和MayaStor之间的混合读写IOPS比较
在选择存储空间时,请仅将结果作为标准之一,不要仅根据我的博客数据做出最终判断。为了扩展我对2019年的总结,我们可以从测试中得出以下结论:
- Portworx和OpenEBS是AKS最快的容器存储。
- 围绕NVMe的稳健设计,OpenEBS似乎已成为最好的开源容器存储选项之一。
- 对于简单的块存储用例,Longhorn绝对是有效的选择,它与OpenEBS Jiva后端非常相似。
当然,这只是查看容器存储选择的一种方法。有趣的部分还包括缩放和稳定性。我将密切关注CNCF存储领域中其他正在发展的项目,并从性能测试和扩展中带来新的有趣更新。
Reference
本文转自, 可直接浏览英文原文
V1: https://medium.com/volterra-io/kubernetes-storage-performance-comparison-9e993cb27271