本文已超过一年。较旧的文章可能包含过时内容。请检查页面中的信息自发布以来是否已失效。

Kubernetes 1.6 中的可扩展性更新:支持 5000 节点和 150000 Pod 的集群

编者按:本文是 一系列深入文章 的一部分,介绍了 Kubernetes 1.6 中的新特性

去年夏天,我们分享了关于 Kubernetes 可扩展性的更新,从那时起,我们一直在努力工作,并自豪地宣布Kubernetes 1.6 可以处理多达 5000 个节点和 150000 个 Pod 的集群。此外,这些集群的端到端 Pod 启动时间比之前 1.3 版本中的 2000 节点集群甚至更好;并且 API 调用的延迟都在一秒钟的 SLO 范围内。

在这篇博文中,我们将回顾我们在测试中监控了哪些指标,并描述 Kubernetes 1.6 的性能结果。我们还将讨论为了实现这些改进所做的更改,以及我们在系统可扩展性领域未来版本中的计划。

X 节点集群 - 这是什么意思?

既然 Kubernetes 1.6 已经发布,现在是回顾我们所说的“支持” X 节点集群意味着什么的好时机。正如一篇之前的博文中详细描述的那样,我们目前有两个与性能相关的服务等级目标 (SLO)

  • API 响应能力:所有 API 调用中有 99% 在不到 1 秒内返回
  • Pod 启动时间:99% 的 Pod 及其容器(使用预拉取镜像)在 5 秒内启动。与之前一样,可以运行比声明支持的 5000 节点集群更大的部署(用户也已经这样做了),但性能可能会下降,并且可能无法满足我们上面定义的严格 SLO。

我们知道这些 SLO 的范围有限。系统中有许多方面它们没有涵盖。例如,我们不衡量作为 Service 一部分的新 Pod 在启动后多久可以通过 Service IP 地址访问。如果你正考虑使用大型 Kubernetes 集群,并且有超出我们 SLO 覆盖范围的性能要求,请联系 Kubernetes 可扩展性 SIG,以便我们帮助你了解 Kubernetes 是否已准备好处理你的工作负载。

未来 Kubernetes 版本中与可扩展性相关的首要任务是通过以下方式增强我们对支持 X 节点集群的定义:

  • 完善当前现有的 SLO
  • 添加更多 SLO(将涵盖 Kubernetes 的各个领域,包括网络)

Kubernetes 1.6 在大规模场景下的性能指标

那么 Kubernetes 1.6 在大型集群中的性能如何呢?下图显示了 2000 节点和 5000 节点集群的端到端 Pod 启动延迟。作为对比,我们还展示了 Kubernetes 1.3 的相同指标,该指标发布在我们之前描述支持 2000 节点集群的可扩展性博文中。正如你所见,与支持 2000 节点的 Kubernetes 1.3 相比,Kubernetes 1.6 在 2000 和 5000 节点下都具有更好的 Pod 启动延迟 [1]。

下图显示了 5000 节点 Kubernetes 1.6 集群的 API 响应延迟。所有百分位数的延迟均小于 500 毫秒,甚至 90th 百分位数也小于约 100 毫秒。

我们是如何实现这些的?

在过去的九个月里(自上一篇可扩展性博文以来),Kubernetes 中进行了大量的性能和可扩展性相关更改。本文中我们将重点介绍其中两项最重要的更改,并简要列举其他一些更改。

etcd v3
在 Kubernetes 1.6 中,我们将默认存储后端(存储整个集群状态的键值存储)从 etcd v2 切换到 etcd v3。这项过渡的初步工作始于 1.3 发布周期。你可能想知道为什么花了这么长时间,考虑到:

  • 支持 v3 API 的 etcd 第一个稳定版本于 2016 年 6 月 30 日发布

  • 新 API 是与 Kubernetes 团队共同设计的,以满足我们的需求(从特性和可扩展性两方面考虑)

  • etcd v3 与 Kubernetes 的集成在 etcd v3 发布时已基本完成(事实上,CoreOS 使用 Kubernetes 作为新 etcd v3 API 的概念验证)事实证明,有很多原因。我们将在下面描述最重要的一些原因。

  • 以向后不兼容的方式更改存储,就像 etcd v2 到 v3 的迁移那样,是一项重大更改,因此我们需要强有力的理由来支持。我们在 9 月份找到了这个理由,当时我们确定如果继续使用 etcd v2,将无法扩展到 5000 节点集群 (kubernetes/32361 包含一些相关讨论)。特别是,etcd v2 中的 watch 实现无法扩展。在 5000 节点集群中,我们需要能够每秒向单个 watcher 发送至少 500 个 watch 事件,这在 etcd v2 中是不可能的。

  • 一旦我们有了实际更新到 etcd v3 的强大动力,我们就开始对其进行彻底测试。正如你可能预料到的,我们发现了一些问题。Kubernetes 中有一些小 bug,此外,我们还要求改进 etcd v3 的 watch 实现性能(watch 是 etcd v2 对我们来说的主要瓶颈)。这促成了 etcd 3.0.10 补丁版本的发布。

  • 一旦这些更改完成,我们就相信新的 Kubernetes 集群可以在 etcd v3 上工作。但是,迁移现有集群的巨大挑战依然存在。为此,我们需要自动化迁移过程,彻底测试底层的 CoreOS etcd 升级工具,并制定从 v3 回滚到 v2 的应急计划。但最终,我们确信它应该可以工作。

将存储数据格式切换到 protobuf
在 Kubernetes 1.3 版本中,我们启用了protobuf 作为 Kubernetes 组件与 API 服务器通信的数据格式(同时保留了对 JSON 的支持)。这给我们带来了巨大的性能提升。

然而,尽管技术上我们已准备好更改,但我们仍然使用 JSON 作为在 etcd 中存储数据的格式。延迟此迁移的原因与我们计划迁移到 etcd v3 相关。你现在可能想知道此更改如何依赖于迁移到 etcd v3。原因是使用 etcd v2 时,我们无法真正以二进制格式存储数据(为了解决这个问题,我们额外对数据进行了 base64 编码),而使用 etcd v3 则可以直接工作。因此,为了简化过渡到 etcd v3,并避免在迁移期间对 etcd 中存储的数据进行一些复杂的转换,我们决定等到 etcd v3 存储后端迁移完成后再切换存储数据格式到 protobuf。

其他优化
在过去三个版本中,我们在 Kubernetes 代码库中进行了数十项优化,包括:

  • 优化调度器(使调度吞吐量提高 5-10 倍)
  • 将所有控制器切换到使用共享 informer 的新推荐设计,这降低了 controller-manager 的资源消耗 - 参考此文档
  • 优化 API 服务器中的独立操作(转换、深拷贝、patch)
  • 减少 API 服务器中的内存分配(这显著影响 API 调用的延迟) 我们想强调,我们在过去几个版本中,以及实际上在项目整个历史中,所做的优化工作是来自整个 Kubernetes 社区许多不同公司和个人的共同努力成果。

下一步是什么?

人们经常问我们将在提高 Kubernetes 可扩展性方面走多远。目前,在未来几个版本中,我们没有计划将可扩展性(在我们 SLO 范围内)提高到 5000 节点集群以上。如果你需要大于 5000 节点的集群,我们建议使用联邦来聚合多个 Kubernetes 集群。

然而,这并不意味着我们将停止致力于可扩展性和性能。正如我们在本文开头提到的,我们的首要任务是完善我们现有的两个 SLO 并引入新的 SLO,以涵盖系统的更多部分,例如网络。这项工作已经在可扩展性 SIG 内启动。我们在如何定义性能 SLO 方面取得了显著进展,这项工作应该在下个月完成。

加入我们
如果你对可扩展性和性能感兴趣,请加入我们的社区,帮助我们塑造 Kubernetes。有很多参与方式,包括:

  • 在 Kubernetes Slack 的 可扩展性频道与我们交流: 
  • 加入我们的特别兴趣小组 SIG-Scalability,该小组每周四太平洋标准时间上午 9:00 开会。感谢你的支持和贡献!请在此阅读更多关于 Kubernetes 1.6 新特性的深入文章。

[1] 我们正在调查为什么 5000 节点集群的启动时间比 2000 节点集群更好。目前的理论认为这与使用 64 核主节点运行 5000 节点实验,而使用 32 核主节点运行 2000 节点实验有关。