【集群】K8S集群解析——大规模能力

【集群】K8S集群解析——大规模能力

Fre5h1nd Lv5

💡简介

  • 好奇Kubernetes(下简称 K8S)中是如何管理节点/Pod状态信息的,以及当规模增大时(尤其是节点规模)会在什么地方出现瓶颈,因此开展相关调研。
  • 本文首先介绍K8S整体组件架构,再定位大规模下的数据面瓶颈,最后细分介绍状态数据瓶颈相关组件架构。

🖼️背景——K8S组件

在K8S官方文档中有对组件情况的相关介绍[1],对象包含资源和业务两方面,组件包含决策组件-控制平面组件执行组件-Node组件其他组件-插件

  • 被管理对象:
    • 1)资源:一组工作机器,被称为节点(Node)。分为Master和Worker。
    • 2)业务:一组应用负载,被称为Pod。Pod是一组关系紧密的容器的集合,是K8S管理的原子单位。
      Kubernetes 集群的组件
  • 管理组件:
    • 1)【决策】控制平面组件(Control Plane Components):为集群做出全局决策,例如调度资源和检测/响应集群事件。
      • 1.1)kube-apiserver:API服务器,是控制平面的前端。负责公开K8S API,负责处理接受请求的工作。
      • 1.2)etcd:一致且高可用的键值存储,是K8S所有集群数据的后台数据库。
      • 1.3)kube-scheduler:调度器,是控制平面的后端之一。负责监视新创建的、未指定运行节点的Pods,并选择节点来让Pod在上面运行。
      • 1.4)kube-controller-manager:控制器管理器,是控制平面的后端之一。负责运行控制器进程(逻辑上有多个控制器,实际上在一个文件中实现并被编译成一个进程),例如:
        • 节点控制器(Node Controller):负责在节点出现故障时进行通知和响应
        • 任务控制器(Job Controller):监测代表一次性任务的 Job 对象,然后创建 Pod 来运行这些任务直至完成
        • 端点分片控制器(EndpointSlice controller):填充端点分片(EndpointSlice)对象(以提供 Service 和 Pod 之间的链接)。
        • 服务账号控制器(ServiceAccount controller):为新的命名空间创建默认的服务账号(ServiceAccount)。
      • 1.5)cloud-controller-manager:云控制管理器,是控制平面的后端之一。负责将集群连接到云提供商的API,嵌入了特定于云平台的控制逻辑,在本地运行集群是不需要该组件。
    • 2)【执行】Node组件:在每个节点上运行,负责维护Pod和提供K8S环境。
      • 2.1)kubelet:节点代理。在每个节点上运行,负责保证容器(containers)都被包装进指定Pod。具体来说,接收PodSpec描述(上面传下来的旨意),确保这些 PodSpec 中描述的容器处于运行状态且健康。
      • 2.2)kube-proxy:节点网络代理。在每个节点上运行,实现K8S服务(Service)。负责维护节点上的一些网络规则,以此允许从集群内外部的网络会话与Pod进行网络通信。
      • 2.3)容器运行时(Container Runtime):容器运行基础组件。负责使K8S能够有效运行容器,负责管理容器的执行和全生命周期。
        • Kubernetes 支持许多容器运行环境,例如 containerd、 CRI-O 以及 Kubernetes CRI (容器运行环境接口) 的其他任何实现。
    • 3)【其他】插件(Addons):提供集群级别的功能,使用 Kubernetes 资源(DaemonSet、 Deployment 等)实现集群功能。
      • 3.1)DNS:域名系统(Domain Name System,DNS)服务器,管理K8S内部域名服务。其他插件都并非严格意义上的必需组件,但几乎所有K8S集群都应该有DNS插件。
      • 3.2)Web 界面(仪表盘):基于Web的用户界面。负责提供可视化界面,使用户可以管理集群中运行的应用程序以及集群本身,并进行故障排除。
      • 3.3)容器资源监控:监控服务器。负责将关于容器的一些常见的时间序列度量值保存到一个集中的数据库中, 并提供浏览这些数据的界面。
      • 3.4)集群层面日志:日志服务器。负责将容器的日志数据保存到一个集中的日志存储中, 这种集中日志存储提供搜索和浏览接口。
      • 3.5)网络插件:实现容器网络接口(CNI)规范的软件组件。它们负责为 Pod 分配 IP 地址,并使这些 Pod 能在集群内部相互通信。

🧠大规模瓶颈

  • 根据K8S官方文档,K8S单个集群支持的最大节点数为5,000[2]。更具体地说:
    • 每个节点的 Pod 数量不超过 110;
    • 节点数不超过 5,000;
    • Pod 总数不超过 150,000;
    • 容器总数不超过 300,000。
  • 自然而然地,产生一个好奇:是什么限制了K8S支持的规模?换句话说,当规模增长时,什么组件会出现瓶颈?
    • 由于本地不具备这么充裕的资源做测试,因此只能通过总结他人经验。好在大佬们已有过相关经验总结:个人博客[3]、阿里巴巴[4]、字节跳动[5-7]

个人博客:《从1k节点增加到5k节点遇到的瓶颈》[3]

  • 简介:K8S自从1.6起便号称可以承载5000个以上的节点,但是在实践中,从10+到5000的路上,还存在许多问题。

1 ~ 500 个节点

问题:(集群)kubectl 有时会出现 timeout ( p.s. kubectl -v=6 可以显示所有 API 细节指令)
原因:ETCD吞吐异常——网络存储写入效率低,需使用每台机器本地临时存储(local temp drive,猜测起到类似于cache的作用)。(从100ms优化至200us)
追问:但本地存储带来的问题是什么?全局一致性问题如何解决?

500 ~ 1000 个节点

问题:(业务)出现 kube-apiserver 每秒从 etcd 上读取过多数据(高达500mb)情况
原因:数据处理业务(如Fluentd、Datadog)抓取数据频率过高

1000 ~ 2000 个节点

问题1:(业务)默认调度策略下,无法再写入数据,报错 cascading failure
原因1:业务分散导致网络瓶颈,引发连锁错误

问题2:(业务)解决问题1的集聚调度策略下,经常出现 DNS 查询不到的情况(随机发生)
原因2:KubeDNS被集中在单台服务器,请求量过大

问题3:(业务)每次新节点建立起来,docker image pull 都要花 30 分钟
原因3:某个大镜像造成堵塞,其他镜像排队时间长

问题4:(业务)业务需要的节点间网络流量,可以达到 10-15GBit/s,但是由于 Flannel 所以导致流量会降到 2GBit/s
原因4:Flannel存在性能限制

总结

主要出现性能瓶颈的原因还是“业务的巨大网络流量需求”与“有限集群网络”的冲突,这部分与IaaS层集群管理的关系不大,与PaaS层业务管理的关系较大。
在IaaS层集群管理方面,可以看到仅仅在500节点时就出现Etcd性能瓶颈,在本文中主要是由于网络传输导致的。本文未细化说明具体解决方案与带来的问题,例如时效性和一致性的权衡。

阿里巴巴:《万级规模K8S集群全局高可用体系之美》[4]

  • 简介:介绍K8S单集群规模不断增大带来的“如何持续保障SLO”。ASI 单集群规模支撑能够超过K8S社区的 5000 台,是非常有意思且具备极大挑战的,本文总结了ASI单集群规模从100到10,000的发展之路。

    ASI:Alibaba Serverless infrastructure,阿里巴巴针对云原生应用设计的统一基础设施,ASI 是阿里公共云服务 ACK 的阿里集团企业版。

性能瓶颈分析

  1. Etcd出现大量读写延迟
  2. 控制器无法及时感知数据变化
  3. kube-apiserver查询pods/nodes延迟高,甚至导致oom(Out Of Memory,指系统内存已用完)

当集群节点超过5000时会发生什么?

能力列举

  1. 【100->4,000节点】Apiserver性能优化:客户端cache优先;服务端watch优化+cache索引优化。Etcd性能优化:并发读优化;存储上限优化;多备灾能力优化。
  2. 【4,000->8,000节点】
  3. 【8,000->10,000节点】

字节跳动《》[5-7]

🔨状态信息管理组件

  • 根据上述组件介绍,初步分析1.2、2.1、3.3负责核心数据的获取和存储,其它控制组件都或多或少需要依赖数据进行相关管理功能的实现。
    • 1)特别地,状态信息存取方面完全由Etcd负责,因此第一个问题是“数据通过Etcd存取的全过程如何?还涉及哪些组件?以什么样的模式进行状态同步(批次同步or增量同步)?”
    • 2)在上述多篇博客中都提到过Etcd存在性能瓶颈,第二个问题是“Etcd的瓶颈出现在哪个过程?具体量化值为多少?”
    • 3)更进一步地,由于字节已经提出了相应方案解决Etcd的性能瓶颈,第三个问题是“新解决方案/其它组件的代价是什么?是否在解决效率的另一面带来了新的质量问题?”

状态信息存取全过程解析

ETCD瓶颈解析

硬币另一面:代价解析

🔨解决

🏥反思

🧠疑问

  1. K8S组件中,为什么将“DNS”、“网络插件”归为“插件”?难道不是必须的吗?
  2. 看到字节跳动关注一些多集群协同[8]、集群监控[9]的工作,这些场景下的难点是什么?
  3. 看到阿里巴巴对 apiserver 和 Etcd 进行了大量优化,难点是否可以归纳为两个:读写慢;数据多。


  • 希望这篇博客对你有帮助!如果你有任何问题或需要进一步的帮助,请随时提问。
  • 如果你喜欢这篇文章,欢迎动动小手 给我一个follow或star。

🗺参考文献

[1] Kubernetes 组件

[2] 大规模集群的注意事项

[3] k8s集群从一千节点增加到五千台节点遇到的瓶颈

[4] 【深度】阿里巴巴万级规模 K8s 集群全局高可用体系之美

[5] 字节跳动大规模K8s集群管理实践

[6] 字节跳动高性能 Kubernetes 元信息存储方案探索与实践

[7] SoCC 论文解读:字节跳动如何在大规模集群中进行统一资源调度

[8] 字节跳动开源KubeAdmiral:基于 K8s 的新一代多集群编排调度引擎

[9] 字节跳动容器化场景下的性能优化实践

  • 标题: 【集群】K8S集群解析——大规模能力
  • 作者: Fre5h1nd
  • 创建于 : 2024-07-23 11:26:29
  • 更新于 : 2024-08-11 18:41:33
  • 链接: https://freshwlnd.github.io/2024/07/23/k8s/k8s-DataPlane/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
评论