关于Kubernetes中的数据库,大家最关心的第一个问题是性能。由于这种担心的存在,许多使用Kubernetes进行生产应用程序工作的客户正在Kubernetes之外的裸机或VM上运行数据库。因此,我们致力于深入研究Kubernetes抽象层,确定值得测试的关键领域,并设计有用的基准。
我们从网络入手,因为由于需要在大多数Kubernetes环境中利用网络存储来提高弹性,因此网络对性能的影响很大。此外,我们知道联网一直是容器化领域不断挑战和改进的领域。最后,对于考虑将其数据库工作负载迁移到Kubernetes的人们来说,我们通常将性能视为网络采用的主要障碍,而将网络性能视为特定的主要障碍。拥有一个数据库到Kubernetes的桥梁是很有价值的,这使在这里运行生产工作负载更加可行。最后,我们想了解在Kubernetes中运行数据库所需的一切。
这篇博客文章直接基于这些努力的结果。
基准方法
为了进行此基准测试,我们试图建立一种方法来专门隔离尽可能多的变量,以专门研究网络如何影响性能。为此,我们确保使用的数据集适合内存,在执行运行之前预热所有缓存,在Kubernetes中利用本地存储,并执行足够的基准测试运行以消除可变性。我们还希望数据能够进行真正的比较,因此我们确保通过基础架构拓扑进行比较。
我们的测试数据中心内机柜中的五台物理服务器中的每台都连接到机架式10GbE和机架式1GbE交换机,该交换机包括位于单独IP子网中的两个单独的物理网络。五台服务器中的一台充当sysbench客户端,用于模拟工作负载,其余四台由Kubernetes和Database角色组成。在裸机测试期间,这三台服务器作为Kubernetes节点按原样运行,在Kubernetes测试期间,这三台服务器被部署为托管数据库Pod的节点,而第四台服务器被预留为仅充当Kubernetes Master。
为了部署Kubernetes环境,我们使用了kubeadm并尝试尽可能保持基本默认设置,以确保我们在测试中不会产生混杂因素。我们使用了Kubernetes 1.16。在Percona XtraDB群集5.7.27-31.39的基础上,使用Percona XtraDB群集的Percona Kubernetes Operator 1.2.0版本部署了Percona XtraDB群集。为了部署裸机环境,使用来自我们公共仓库的Percona XtraDB Cluster 5.7.27-31.39的Percona装运包手动执行安装。在这两种情况下,我们都禁用ProxySQL并将Percona XtraDB Cluster群集成员直接暴露给网络,并配置了sysbench客户端,以便所有流量仅定向到Percona XtraDB Cluster群集的单个成员。对于裸机测试和基于Kubernetes的测试,主机操作系统都是Ubuntu 16.04 LTS,该内核运行的内核版本为4.15.0-66(与Ubuntu 16.04 LTS一起提供)。
服务器中包含的硬件如下:
对于环境设置,我们按照提供的说明将每个CNI插件安装在Kubernetes的全新部署中,以确保它通过10GbE网络发送流量。我们使用sysbench和oltp读写工作负载运行数据库基准测试。此外,我们使用iPerf3捕获了网络吞吐量数据。为了确保数据库本身不是瓶颈,我们利用了经过优化的MySQL配置,该配置作为ConfigMap提供给Kubernetes Operator。最后,对于本地存储,我们利用Kubernetes中的HostPath方法来确保我们可以为数据库提供卷而不会越过网络边界,从而只有事务和复制工作负载会接触到网络。
我们调整的my.cnf如下:
[mysqld]table_open_cache = 200000table_open_cache_instances=64back_log=3500max_connections=4000innodb_file_per_tableinnodb_log_file_size=10Ginnodb_log_files_in_group=2innodb_open_files=4000innodb_buffer_pool_size=100Ginnodb_buffer_pool_instances=8innodb_log_buffer_size=64Minnodb_flush_log_at_trx_commit = 1innodb_doublewrite=1innodb_flush_method = O_DIRECTinnodb_file_per_table = 1innodb_autoinc_lock_mode=2innodb_io_capacity=2000innodb_io_capacity_max=4000wsrep_slave_threads=16wsrep_provider_options="gcs.fc_limit=16;evs.send_window=4;evs.user_send_window=2"
我们对Kubernetes中资源的调整设置如下:
resources:requests:memory: 150Gcpu: "55"limits:memory: 150Gcpu: "55"
我们这样做是因为Kubernetes中的Pod资源服务质量(QoS)。Kubernetes根据Pod的请求和限制设置为Pod提供不同级别的QoS。在典型情况下,您仅指定请求块而不指定限制,Kubernetes使用“尽力而为QoS”,但是当为所有容器中的所有资源设置请求和限制并且它们相等时,Kubernetes将改为使用“保证的QoS”。这可能会对性能差异产生重大影响。
此外,您需要了解以下用于运行测试的sysbench命令行:
./sysbench --test=tests/db/oltp.lua --oltp_tables_count=10 -- oltp_table_size=10000000 --num-threads=64 --mysql-host=172.16.0.4 -- mysql-port=30444 --mysql-user=root --mysql-password=root_password --mysql-db=sbtest10t --oltp-read-only=off --max-time=1800 --max- requests=0 --report-interval=1 --rand-type=pareto --rand-init=on run
我们测试了哪些CNI插件
我们选择了CNI插件来进行测试,基于我们与客户和合作伙伴以及一些由于性能原因而特别有趣的参与者的经验。该列表没有特别的顺序,我们的目标不是总结使用哪个插件的具体建议。所有CNI插件的项目目标都不同,这导致它们进行不同的设计和工程折衷,这可能会对性能产生影响,但是根据您的环境,这些折衷可能是合理的。
Project Calico
由于其简单性,您可以将可路由IP分配给Pods并将其与您现有的机架式网络设备集成在一起,因此,Project Calico是许多进行内部部署的企业的热门选择。因此,我们测试了启用(默认)和禁用IP-in-IP的Calico。
Flannel
Flannel是带有Kubernetes的网络结构,支持可插入后端。默认后端基于UDP,但它也支持vxlan和host-gw后端。我们无法使host-gw正常工作,但是我们能够使用UDP和vxlan进行测试。
Cilium
Cilium是使用BPF和XDP的API感知网络和安全性。主要侧重于网络安全政策用例。它的安装非常简单,但是在可用的基准测试时间内,我们无法使其跨10GbE网络进行路由,这显然影响了性能结果。否则测试成功了,但请记住,我们仍在报告这些结果。
Weave (weave-net)
Weave是一个紧密集成且易于部署的多主机容器联网系统。尽管显示Pods已在我们的10GbE网络块中分配了IP,但流量仍在1GbE网络中路由。我们花费了大量时间来解决此问题,但在可用时间内无法解决。我们仍在报告这些结果。
Intel SR-IOV and Multus
Multus是一个CNI插件,可将多个网络接口附加到Pod。这是必需的,因为SR-IOV CNI插件不能是您唯一的Pod网络,它是默认Pod网络之外的附加接口。我们将Kube-Router用于默认的Pod网络,并为此测试分配了另一个10GbE网络上的SR-IOV接口。SR-IOV具有复杂的设置过程,但允许将大部分网络卸载到硬件,并有效地将硬件(VF)中的虚拟NIC分配给作为网络设备的主机上的每个Pod。从理论上讲,它应该具有接近线速的性能,因此值得尝试的复杂性。
Kube-Router
Kube-Router是Kubernetes网络的简单交钥匙解决方案。它也是kubeadm部署的默认插件,因此部署非常简单。最小的功能集所产生的开销很少,您将在结果中看到这一点。
结论
作为基准,我们首先在裸机上进行了测试,并表明我们的基准仅受网络性能的限制。在这些测试中,我们在1GbE上达到了2700 tps,在10GbE上达到了7302 tps。
一个非常有趣的结果是,由iPerf3衡量的网络吞吐量与由sysbench衡量的数据库吞吐量之间的相关性强。SR-IOV打破了这种相关性,我们期望它是性能最好的。它具有接近裸机的网络吞吐量,但是大约是预期数据库吞吐量的一半。我们怀疑此结果与事务大小有关,这是由于SR-IOV固有的硬件虚拟化层内部发生延迟导致的,因此我们计划在将来的基准测试中验证这种怀疑。
我们发现的另一个关键问题是,即使在使用Kube-Router的最佳情况下,与在Kubernetes中运行裸机相比,我们也看到数据库性能下降了约13%。这说明在Kubernetes中仍需要对容器网络的性能进行改进。
网友评论