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

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

编者注:本文是关于 Kubernetes 1.6 新功能的一系列深度文章的一部分

去年夏天,我们分享了 Kubernetes 可伸缩性的更新,此后我们一直在努力工作,并自豪地宣布 Kubernetes 1.6 可以处理 5,000 个节点和多达 150,000 个 Pod 的集群。此外,这些集群的端到端 Pod 启动时间甚至优于 1.3 版本中之前的 2,000 节点集群;API 调用的延迟也符合一秒钟的 SLO。

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

X 节点集群——这意味什么?

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

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

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

即将发布的 Kubernetes 版本中,与可伸缩性相关的首要任务是通过以下方式增强我们对支持 X 节点集群的定义:

  • 优化现有 SLO
  • 增加更多 SLO(将涵盖 Kubernetes 的各个领域,包括网络)

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

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

下一张图显示了 5000 节点 Kubernetes 1.6 集群的 API 响应延迟。所有百分位的延迟都小于 500ms,甚至 90 百分位也小于大约 100ms。

我们是如何做到的?

在过去九个月(自上一篇可伸缩性博客文章以来),Kubernetes 中有大量与性能和可伸缩性相关的更改。在这篇文章中,我们将重点介绍其中两个最大的更改,并简要列举其他一些更改。

etcd v3
在 Kubernetes 1.6 中,我们将默认存储后端(存储整个集群状态的键值存储)从 etcd v2 切换到 etcd v3。这项过渡的初步工作始于 1.3 版本周期。您可能会想,既然有以下原因,为什么我们花了这么长时间:

  • etcd 支持 v3 API 的第一个稳定版本于 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 节点集群中,我们需要能够每秒向单个观察者发送至少 500 个 watch 事件,这在 etcd v2 中是不可能实现的。

  • 一旦我们有了实际升级到 etcd v3 的强烈动机,我们就开始对其进行彻底测试。正如您可能预料的那样,我们发现了一些问题。Kubernetes 中有一些小错误,此外我们还要求 etcd v3 的 watch 实现进行性能改进(watch 是 etcd v2 中我们主要瓶颈)。这导致了 3.0.10 etcd 补丁版本。

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

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

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

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

  • 优化调度器(这使调度吞吐量提高了 5-10 倍)
  • 将所有控制器切换到使用共享 informers 的新推荐设计,这降低了 controller-manager 的资源消耗——详情请参阅此文档
  • 优化 API 服务器中的单个操作(转换、深拷贝、补丁)
  • 减少 API 服务器中的内存分配(这显著影响 API 调用的延迟) 我们要强调的是,我们在过去几个版本乃至整个项目历史中完成的优化工作,是来自整个 Kubernetes 社区的众多不同公司和个人共同努力的结果。

下一步是什么?

人们经常问我们将在多大程度上改进 Kubernetes 的可伸缩性。目前,我们没有计划在未来几个版本中将可伸缩性提高到 5000 节点集群(在我们的 SLO 范围内)以上。如果您需要大于 5000 节点的集群,我们建议使用联合来聚合多个 Kubernetes 集群。

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

加入我们的努力
如果您对可伸缩性和性能感兴趣,请加入我们的社区并帮助我们塑造 Kubernetes。有很多参与方式,包括:

  • 在 Kubernetes Slack 的可伸缩性频道与我们聊天: 
  • 加入我们的特殊兴趣小组 SIG-Scalability,该小组每周四太平洋时间上午 9:00 开会。感谢您的支持和贡献!在此阅读更多关于 Kubernetes 1.6 新功能的深入文章。

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