贝宝如何将Kubernetes扩展到超过4k个节点和200k个Pod?


在 PayPal,我们最近开始使用 Kubernetes 试水。我们的大部分工作负载都在 Apache Mesos 上运行,作为迁移的一部分,我们需要了解运行 Kubernetes 和 PayPal 特定控制平面的集群的几个性能方面。这些方面的主要内容是了解平台的可扩展性以及通过调整集群来确定改进的机会。
与 Apache Mesos 可以开箱即用地扩展至 10,000 个节点不同,扩展 Kubernetes 具有挑战性。Kubernetes 的可扩展性不仅限于节点和 pod 的数量,还包括创建的资源数量、每个 pod 的容器数量、服务总数和 pod 部署吞吐量等几个方面。这篇文章描述了我们在扩展时面临的一些挑战以及我们如何解决这些挑战。
 
API 服务器
当与 API 服务器的多个连接返回 504 网关超时以及本地客户端级别限制(指数退避)时,API 服务器被证明是一个瓶颈。
通过max-mutating-requests-inflight和max-requests-inflight更新了管理API服务器上速率限制的队列大小。这两个标志在API服务器上控制着1.20版本中作为测试版引入的优先级和公平性功能如何在其队列类别中划分总队列大小。例如,领导选举的请求比pod请求更优先。在每个优先级中,都有可配置的队列的公平性。在未来,通过PriorityLevelConfiguration和FlowSchema API对象,还有进一步微调的空间。
 
控制器管理器
控制器管理器负责为本地资源提供控制器,如复制集、命名空间等,其部署数量较多(由复制集管理)。控制器管理器与API服务器同步其状态的速度是有限的。多个旋钮被用来调整这一行为。

  • kube-api-qps —控制器管理器在给定秒内可以对 API 服务器进行的查询数。
  • kube-api-burst —控制器管理器突发,这是kube-api-qps之上的额外并发调用。
  • concurrent-deployment-syncs并发部署同步 — 同步调用中的并发调用对象,如部署、副本集等。

 
调度器
当作为一个独立的组件进行测试时,调度器可以支持每秒高达1000个pod的高吞吐率。然而,在将调度器部署到一个实时集群中时,我们注意到实际的吞吐量减少。一个缓慢的etcd实例导致调度器的绑定延迟增加,导致待处理队列的大小增加到数千个pod的程度。我们的想法是在测试运行期间将这个数字保持在100以下,因为更多的计数会影响到pod的启动延迟。我们也最终调整了领导者选举参数,以适应短暂的网络分区或网络拥堵时的虚假重启。
 
etcd
etcd是Kubernetes集群中最关键的一个部分。这一点从etcd在整个集群中以不同方式表现出来的大量问题可以看出。我们需要仔细调查,找出根本原因,并扩大etcd的规模,以处理我们的预期规模。
通过调查和分析,我们确定GCP将PD-SSD的磁盘吞吐量扼杀在每秒100MB左右,我们的磁盘大小为100G。GCP没有提供增加吞吐量限制的方法--它只随着磁盘的大小增加。
尽管etcd节点只需要<10G的空间,我们首先尝试使用1TB的PD-SSD。然而,当所有4k节点同时加入Kubernetes控制平面时,即使是更大的磁盘也成为了一个瓶颈。我们决定使用本地SSD,它的吞吐量非常高,代价是在故障情况下数据丢失的几率略高,因为它不是持久的。
在转移到本地SSD后,我们没有看到最快的SSD的预期性能。一些基准测试是直接在磁盘上用FIO完成的,这些数字是预期的。然而,etcd基准测试显示了一个不同的故事,即并发的所有成员写入。
本地固态硬盘的表现更差!
经过深入调查,这归因于ext4文件系统的写屏障缓存提交。由于etcd使用写前日志,并在每次提交到raft日志时调用fsync,所以禁用写屏障是可以的。此外,我们在文件系统级和用于DR应用程序级都有DB备份工作,。
在这个改变之后,使用本地SSD的数字提高了,与PD-SSD相当。这一改进的效果体现在etcd的WAL同步持续时间和后端提交延迟上,在15:55左右的时间点上,WAL同步持续时间和后端提交延迟减少了90%以上。
 
etcd中默认的MVCC数据库大小为2GB。在触发DB空间不足的警报后,这个大小被增加到最大8GB。由于这个数据库的利用率约为60%,我们能够扩展到20万个无状态荚。
通过上述所有的优化,集群在我们的预期规模下更加稳定,然而,我们在API延迟的SLI方面远远落后。
etcd服务器仍然会偶尔重启,仅仅一次重启就会破坏基准测试结果,特别是P99的数字。仔细观察发现,在v1.20版的etcd YAML中存在一个失效探测的错误。为了解决这个问题,我们采用了一个变通办法,即增加失败阈值的数量。
在用尽所有途径垂直扩展etcd后,主要是在资源方面(CPU、内存、磁盘),我们发现etcd的性能受到范围查询的影响。
当有很多范围查询时,etcd的表现并不好,对Raft日志的写入受到影响,从而减慢了集群的延迟。
由于这些耗时的查询,etcd的后端延迟受到了很大影响。
在事件资源上的etcd服务器分片后,我们看到在pod高度竞争的情况下,集群的稳定性有所提高。
在未来,还有进一步将etcd集群分片到pods资源上的空间。配置API服务器来联系相关的etcd以与分片的资源进行交互是很容易的。
 
结论
Kubernetes 是一个复杂的系统,必须深入了解控制平面才能知道如何扩展每个组件。我们通过这次练习学到了很多东西,并将继续优化我们的集群。