本文发表于一年多前。旧文章可能包含过时内容。请检查页面中的信息自发布以来是否已变得不正确。

Kubernetes 1.3 的性能和可扩展性更新——2000 节点 60000 Pod 集群

我们很荣幸地宣布,随着1.3 版本的发布,Kubernetes 现在支持 2000 节点集群,并具有更好的端到端 Pod 启动时间。我们的 API 调用延迟在我们的“一秒”服务水平目标 (SLO) 范围内,其中大多数甚至比这好一个数量级。可以运行比 2,000 节点集群更大的部署,但性能可能会下降,并且可能无法满足我们严格的 SLO。

在这篇博客文章中,我们将讨论 Kubernetes 1.3 的详细性能结果以及我们从 1.2 版本到 1.3 版本为实现这些结果所做的更改。我们还将描述 Kubemark,这是一种性能测试工具,我们已将其集成到我们的持续测试框架中,以检测性能和可伸缩性回归。

评估方法

我们已经在之前的博客文章中描述了我们的测试场景。自 1.2 版本以来最大的变化是,在我们的 API 响应测试中,我们现在创建并使用多个命名空间。特别是对于 2000 节点/60000 Pod 集群测试,我们创建了 8 个命名空间。之所以进行此更改,是因为我们相信此类超大型集群的用户可能会使用许多命名空间,至少集群中总共有 8 个命名空间。

Kubernetes 1.3 的指标

那么,Kubernetes 1.3 版本的性能如何?下图显示了 2000 和 1000 节点集群的端到端 Pod 启动延迟。为了进行比较,我们显示了 Kubernetes 1.2 在 1000 节点集群中的相同指标。

下图显示了 v1.3 2000 节点集群的 API 响应延迟。

我们是如何实现这些改进的?

我们在 Kubernetes 1.3 中为可伸缩性所做的最大改变是为 API 添加了一种高效的基于 Protocol Buffer 的序列化格式,作为 JSON 的替代方案。它主要用于 Kubernetes 控制平面组件之间的通信,但所有 API 服务器客户端都可以使用此格式。所有 Kubernetes 控制平面组件现在都使用它进行通信,但系统继续支持 JSON 以实现向后兼容性。

我们尚未将 etcd 中存储集群状态的格式更改为 Protocol Buffers,因为我们仍在研究升级机制。但我们非常接近完成这项工作,预计将在 Kubernetes 1.4 中将存储格式切换到 Protocol Buffers。我们的实验表明,这应该会将 Pod 启动端到端延迟再降低 30%。

我们如何大规模测试 Kubernetes?

启动具有 2000 个节点的集群既昂贵又耗时。虽然我们每个版本至少需要这样做一次以收集真实世界的性能和可伸缩性数据,但我们还需要一种更轻量级的机制,可以让我们快速评估不同性能改进的想法,并且我们可以持续运行以检测性能回归。为了解决这一需求,我们创建了一个名为“Kubemark”的工具。

什么是“Kubemark”?

Kubemark 是一种性能测试工具,允许用户在模拟集群上运行实验。我们用它来衡量大型集群的性能。

Kubemark 集群由两部分组成:一个运行正常主组件的真实主节点,以及一组“空心”节点。“空心”前缀表示对组件的实现/实例化,其中一些“移动部件”被模拟出来。最好的例子是 hollow-kubelet,它假装是一个普通的 Kubelet,但不会启动任何容器或挂载任何卷。它只是声称它会这样做,因此从主组件的角度来看,它的行为就像一个真实的 Kubelet。

由于我们希望 Kubemark 集群尽可能接近真实集群,我们使用注入了假 Docker 客户端的真实 Kubelet 代码。同样,hollow-proxy(KubeProxy 等效)通过注入无操作 Proxier 接口(以避免修改 iptables)来重用真实的 KubeProxy 代码。

多亏了这些更改

  • 许多空心节点可以在一台机器上运行,因为它们不会修改它们运行的环境
  • 在没有真实容器运行且不需要容器运行时(例如 Docker)的情况下,我们可以在一台单核机器上运行多达 14 个空心节点。
  • 然而,空心节点对 API 服务器产生的负载与它们的“完整”对应物大致相同,因此它们为性能测试提供了真实的负载 [唯一的根本区别是我们没有模拟现实中可能发生的任何错误(例如,失败的容器)——未来框架中添加对此的支持是一个潜在的扩展]

我们如何设置 Kubemark 集群?

为了创建 Kubemark 集群,我们利用 Kubernetes 本身提供的强大功能——我们在 Kubernetes 上运行 Kubemark 集群。让我们详细描述一下。

为了创建 N 节点 Kubemark 集群,我们

  • 创建一个常规的 Kubernetes 集群,我们可以在其中运行 N 个空心节点 [例如,要创建 2000 节点 Kubemark 集群,我们创建一个包含 22 个 8 核节点的常规 Kubernetes 集群]
  • 创建一个专用虚拟机,我们将在其中启动 Kubemark 集群的所有主组件 (etcd、apiserver、controllers、scheduler 等)。
  • 在基础 Kubernetes 集群上调度 N 个“空心节点”Pod。这些空心节点配置为与在专用虚拟机上运行的 Kubemark API 服务器通信
  • 最后,我们通过在基础集群上调度插件 Pod(目前只有 Heapster)并配置它们与 Kubemark API 服务器通信来创建它们。完成此操作后,您将拥有一个可用的 Kubemark 集群,您可以在其上运行您的(性能)测试。我们有在 Google Compute Engine (GCE) 上完成所有这些的脚本。有关更多详细信息,请查看我们的指南

这里值得一提的是,在运行 Kubemark 的同时,我们也在测试 Kubernetes 的正确性。显然,如果其下的基础 Kubernetes 集群无法正常工作,您的 Kubemark 集群也无法正常工作。

真实集群与 Kubemark 中测量的性能

至关重要的是,Kubemark 集群的性能与真实集群的性能大多相似。对于 Pod 启动端到端延迟,如下图所示,差异可以忽略不计

对于 API 响应,差异更大,但通常小于 2 倍。但是,趋势完全相同:真实集群中的改进/回归在 Kubemark 的指标中显示为相似的百分比下降/增加。

结论

我们将继续改进 Kubernetes 的性能和可伸缩性。在这篇博客文章中,我们
展示了 1.3 版本可扩展到 2000 个节点,同时满足了我们的响应 SLO
解释了我们为改进 1.2 版本的可伸缩性所做的主要更改,以及
描述了 Kubemark,我们的仿真框架,它允许我们快速评估代码更改对性能的影响,无论是在试验性能改进想法时,还是作为我们持续测试基础设施的一部分来检测回归。

请加入我们的社区,帮助我们构建 Kubernetes 的未来!如果您对可伸缩性特别感兴趣,请通过以下方式参与:

有关 Kubernetes 项目的更多信息,请访问 kubernetes.io 并在 Twitter 上关注我们 @Kubernetesio