文档

大规模ACK Pro集群使用建议

更新时间:

ACK集群的性能和可用性与集群资源数量、资源访问频率、访问模式等紧密相关。不同变量组合下,API Server承载的压力和性能差异不同。在大规模的ACK集群Pro版中(通常为超过500个节点或者10,000个Pod的集群)中,集群管理者需要根据业务实际状况合理规划和使用规模化集群,密切关注监控指标,确保集群的稳定性和可用性。

本文使用指引

本文主要面向ACK集群Pro版的集群开发和管理人员,提供规划和使用大规模集群的通用性建议,实际情况仍以您的集群环境和业务需求为准。本文使用建议不区分前后顺序,您可以自行选择。在应用建议前,建议您先在测试环境中小批量验证,观察无异常状态后再分批次完成更新。

说明

根据安全责任共担模型,ACK集群负责集群管控面组件(包括Kubernetes控制面组件和etcd)以及集群服务相关阿里云基础设施的默认安全性;您需要负责部署在云上的业务应用安全防护以及对云上资源的安全配置和更新。更多信息,请参见安全责任共担模型

大规模集群使用须知

相较于使用多个集群,构建一个大规模集群可以有效减少集群管理运维负担,提高资源利用率。但在某些复杂的业务场景中,建议您根据业务逻辑或需求将服务拆分到多个集群中,例如非生产(测试)服务与生产(开发)服务拆分、数据库服务与前端应用拆分等。

如您有以下维度的考量,我们更建议您使用多个集群,而非单一的大规模集群。

分类

说明

隔离性

使用多个集群可以确保不同集群(例如生产集群和测试集群)的隔离性,避免某个集群的问题影响全部业务,降低故障爆炸半径。

位置

某些服务需要部署在离终端用户更近的特定地理位置,以满足可用性、低延时的需求。在此场景下,推荐您在多个地区部署多个集群。

单集群规模上限

ACK托管控制面通过弹性伸缩和集群组件的性能优化来自适应集群规模。但Kubernetes架构存在性能瓶颈,超大的集群规模可能会影响集群的可用性和性能。在使用大规模集群前,您应该了解Kubernetes社区定义的容量限制SLO,并前往配额平台查看并申请提高容器服务 Kubernetes 版的配额上限。如果超出社区和ACK的限制,请拆分业务,使用多个集群。

如您需要多集群管理,例如应用部署、流量管理、作业分发、全局监控等,建议您启用多集群舰队

将ACK集群升级至最新K8s版本

随着Kubernetes版本不断升级,容器服务ACK会定期发布支持的Kubernetes版本,并逐步停止对过期版本的技术支持。对于过期版本,ACK将逐步停止发布新功能特性,停止修复功能缺陷、安全缺陷,且仅提供有限的技术支持。

请您通过帮助文档、控制台信息、站内信等渠道关注版本发布情况,并在集群升级前了解相应版本的升级注意事项,及时完成版本升级,避免潜在的集群安全和稳定性问题。关于集群升级的更多信息,请参见手动升级集群;关于Kubernetes版本支持信息,请参见Kubernetes版本概览及机制

遵循集群限制与解决方案

为保证大规模集群的可用性、稳定性和各项性能,请关注下表列出的限制及对应的推荐解决方案。

限制项

说明

推荐解决方案

etcd数据库大小(DB Size)

etcd数据库大小上限为8 GB。当etcd数据库过大时,会影响其性能,包括数据读取和写入延迟、系统资源占用、选举延时等,也会导致服务和数据恢复过程更加困难和耗时。

控制etcd DB Size的总大小在8 GB以下。

  • 控制集群资源总量,及时清理无需使用的资源。

  • 对于高频修改类资源,建议将单个资源大小控制在100KB以下。在etcd中,每次对键值对的更新都会生成一个新的历史版本。在高频更新大数据对象的场景下,etcd保存其数据的历史版本时会消耗更多的资源。

etcd中每种类型资源的数据总大小

如果资源对象总量过大,客户端全量访问该资源时会导致大量的系统资源消耗,严重时可能会导致API Server或自定义控制器(Controller)无法初始化。

控制每种资源类型的对象总大小在800 MB以下。

  • 定义新类型的CRD时,请提前规划最终期望存在的CR数,确保每种CRD资源的总大小可控。

  • 使用Helm部署Chart时,Helm会创建版本(Release)用于跟踪部署状态。默认情况下,Helm使用Secret来存储版本信息。在大规模集群中,将大量的版本信息存储在Secret中可能超出Kubernetes对Secret总大小的限制。请改为使用Helm的SQL存储后端

API Server CLB的连接数和带宽

目前,ACK集群API Server使用的负载均衡类型为CLB,其连接数与带宽有最大容量限制。CLB最大连接数可参见CLB实例概述,最大带宽为5120Mbps。

超出CLB连接数或者带宽限制可能会造成节点Not Ready。

对于1,000节点以上的集群,建议选择按使用量计费的CLB实例。

说明

为提升网络连接速度和带宽,大规模集群访问Default命名空间中的Kubernetes服务时,应使用ENI直连模式。在2023年02月以后新建的,v1.20以上的集群中,新建集群已默认使用ENI直连;存量集群的切换提交工单更多信息,请参见Kube API Server

每个命名空间的Service数量

kubelet会把集群中定义的Service的相关信息以环境变量的形式注入到运行在该节点上的Pod中,让Pod能够通过环境变量来发现Service,并与之通信。

每个命名空间中的服务数量过多会导致为Pod注入的环境变量过多,继而可能导致Pod启动缓慢甚至失败

将每个命名空间的Service数量控制在5,000以下。

您可以选择不填充这些环境变量,将podSpec中的enableServiceLinks设置为false。更多信息,请参见Accessing the Service

集群的总Service数量

Service数量过多会导致kube-proxy需要处理的网络规则增多,继而影响kube-proxy的性能。

对于LoadBalancer类型的Service,Service数量过多会导致Service同步到SLB的时延增加,延迟可能达到分钟级别。

将所有Service的总数量控制在10,000以下。

对LoadBalancer类型的Service,建议将Service总数控制在500以下。

单个Service的Endpoint最大数量

每个节点上运行着kube-proxy组件,用于监视(Watch)Service的相关更新,以便及时更新节点上的网络规则。当某个Service存在很多Endpoint时,Service相应的Endpoints资源也会很大,每次对Endpoints对象的更新都会导致控制面kube-apiserver和节点kube-proxy之间传递大量流量。集群规模越大,需要更新的相关数据越多,风暴效应越明显。

说明

为了解决此问题,kube-proxy在v1.19以上的集群中默认使用EndpointSlices来提高性能。

将单个Service的Endpoints的后端Pod数量控制在3,000以下。

  • 在大规模集群中,应使用EndpointSlices而非Endpoints进行网络端点的拆分和管理。拆分后,每次资源变更时传输的数据量会有效减少。

  • 如果您有自定义Controller依赖Endpoints资源进行路由决策,您仍可以使用Endpoints对象,但请确保单个Endpoints的后端Pod数量不超过1,000。超过时,Pod的Endpoints对象会自动被截断。更多信息,请参见Over-capacity endpoints

所有Service Endpoint的总数量

集群中Endpoint数量过多可能会造成API Server负载压力过大,并导致网络性能降低。

将所有Service关联的Endpoint的总数量控制在64,000以下。

Pending Pod的数量

Pending Pod数量过多时,新提交的Pod可能会长时间处于等待状态,无法被调度到合适的节点上。在此过程中,如果Pod无法被调度,调度器会周期性地产生事件(event),继而可能导致事件泛滥(event storm)。

将Pending Pod的总数量控制在10,000以下。

启用了使用阿里云KMS进行Secret的落盘加密的集群中的Secret数量

使用KMS v1加密数据时,每次加密都会生成一个新的数据加密密钥(DEK)。Kubernetes集群启动时,需要访问并解密存储在etcd中的Secret。如果集群存储的Secret过多,集群在启动或升级时需要解密大量的数据,影响集群性能。

将开启KMS V1加密的集群中存储的Secret数量控制在2,000以下。

合理设置管控组件参数

ACK集群Pro版提供自定义Pro版集群的控制面组件参数功能,支持修改kube-apiserver、kube-controller-manager、kube-scheduler等核心托管组件的参数。在大规模集群中,您需要合理调整管控组件限流的相关参数。

kube-apiserver

为了避免大量并发请求导致控制面超载,kube-apiserver限制了它在特定时间内可以处理的并发请求数。一旦超出此限制,API Server将开始限流请求,向客户端返回429 HTTP响应码,即请求过多,并让客户端稍后再试。如果服务端没有任何限流措施,可能导致控制面因处理超出其承载能力的请求而过载,严重影响整个服务或集群的稳定性以及可用性。因此,推荐您在服务端配置限流机制,避免因控制面崩溃而带来更加广泛的问题。

限流分类

kube-apiserver的限流分为两种。

  • v1.18以下:kube-apiserver仅支持最大并发度限流,将请求区分为读类型和写类型,通过启动参数--max-requests-inflight--max-mutating-requests-inflight限制读写请求的最大并发度。该方式不区分请求优先级。某些低优先级的慢请求可能占用大量资源,造成API Server请求堆积,导致一些更高优先级或更紧急的请求无法及时处理。

    ACK集群Pro版支持自定义kube-apiserver的max-requests-inflight和max-mutating-requests-inflight的参数配置。更多信息,请参见自定义Pro版集群的控制面组件参数

  • v1.18及以上:引入APF(API优先级和公平性)机制来进行更细粒度的流量管理,支持根据预设的规则和优先级来分类和隔离请求,从而确保更重要和紧急的请求优先处理,同时遵循一定的公平性策略,保证不同类型的请求都能够得到合理的处理机会。该特性于v1.20进入Beta阶段,默认开启。

    展开查看APF特性说明

    在v1.20及以上的Kubernetes集群中,kube-apiserver通过--max-requests-inflight--max-mutating-requests-inflight两个参数的总和来配置可以并发处理的请求总数;通过FlowSchema和PriorityLevelConfiguration两种自定义资源对象(CRD)来控制总请求数在不同类型请求之间分配的并发数,更精细地控制请求的流量。

    • PriorityLevelConfiguration:优先级配置,决定某个优先级可以分配到全部并发度的比例。

    • FlowSchema:决定某个请求属于哪个PriorityLevelConfiguration。

    PriorityLevelConfiguration和FlowSchema由API Server自动维护,Kubernetes集群中会自动生成当前集群版本的默认配置。您可以执行以下命令来查看。

    展开查看PriorityLevelConfiguration查询命令与预期输出

    kubectl get PriorityLevelConfiguration
    # 预期输出
    NAME              TYPE      ASSUREDCONCURRENCYSHARES   QUEUES   HANDSIZE   QUEUELENGTHLIMIT   AGE
    catch-all         Limited   5                          <none>   <none>     <none>             4m20s
    exempt            Exempt    <none>                     <none>   <none>     <none>             4m20s
    global-default    Limited   20                         128      6          50                 4m20s
    leader-election   Limited   10                         16       4          50                 4m20s
    node-high         Limited   40                         64       6          50                 4m20s
    system            Limited   30                         64       6          50                 4m20s
    workload-high     Limited   40                         128      6          50                 4m20s
    workload-low      Limited   100                        128      6          50                 4m20s

    展开查看FlowSchema查询命令与预期输出

    说明

    ACK在FlowSchema中添加了ACK核心组件相关的分类ack-system-leader-election和ack-default。其余与社区保持一致。

    kubectl get flowschemas
    # 预期输出
    NAME                           PRIORITYLEVEL     MATCHINGPRECEDENCE   DISTINGUISHERMETHOD   AGE     MISSINGPL
    exempt                         exempt            1                    <none>                4d18h   False
    probes                         exempt            2                    <none>                4d18h   False
    system-leader-election         leader-election   100                  ByUser                4d18h   False
    endpoint-controller            workload-high     150                  ByUser                4d18h   False
    workload-leader-election       leader-election   200                  ByUser                4d18h   False
    system-node-high               node-high         400                  ByUser                4d18h   False
    system-nodes                   system            500                  ByUser                4d18h   False
    ack-system-leader-election     leader-election   700                  ByNamespace           4d18h   False
    ack-default                    workload-high     800                  ByNamespace           4d18h   False
    kube-controller-manager        workload-high     800                  ByNamespace           4d18h   False
    kube-scheduler                 workload-high     800                  ByNamespace           4d18h   False
    kube-system-service-accounts   workload-high     900                  ByNamespace           4d18h   False
    service-accounts               workload-low      9000                 ByUser                4d18h   False
    global-default                 global-default    9900                 ByUser                4d18h   False
    catch-all                      catch-all         10000                ByUser                4d18h   False

限流监测与推荐解决方案

客户端可以通过返回状态码429或通过监控指标apiserver_flowcontrol_rejected_requests_total来判断服务端是否有限流行为。当观测到有限流行为时,可以通过以下方式解决。

  • 监控API Server资源水位:当水位较低时,可调整max-requests-inflightmax-mutating-requests-inflight参数总和提高总的限流值。

    对于500个节点以上的集群,建议参数总和配置为2000~3000之间;对于3000个节点以上的集群,建议参数总和配置在3000~5000之间。

  • 重新配置PriorityLevelConfiguration:

    • 高优先级请求:为不期望限流的请求划分新的FlowSchema,匹配高优先级的PriorityLevelConfiguration,例如workload-highexempt。但exempt的请求不会被APF限流,请谨慎配置。您也可以为高优先级的请求配置新的PriorityLevelConfiguration,给予更高的并发度。

    • 低优先级请求:当的确存在某些客户端慢请求导致API Server水位高或响应慢时,可以为该类请求新增一个FlowSchema,并为该FlowSchema匹配低并发度的PriorityLevelConfiguration。

重要
  • ACK集群Pro版会为您托管kube-apiserver组件。kube-apiserver默认为多AZ高可用,会保证至少2个副本,并随着控制面资源使用率增大而逐渐调整至最大6个副本。kube-apiserver可并发的总实际请求值 = 副本数 * 单个副本总请求量

  • 修改kube-apiserver的自定义参数会触发API Server的滚动更新,可能导致客户端Controller重新进行List-Watch操作。在大规模集群下,这可能会造成API Server负载过高,导致其服务暂时不可用。执行此操作时,请确保API Server的内存水位低于80%。

kube-controller-manager和kube-scheduler

kube-controller-manager和kube-scheduler分别通过kubeAPIQPS/kubeAPIBurst、connectionQPS/connectionBurst参数控制与API Server通信的QPS。更多信息,请参见自定义Pro版集群的控制面组件参数使用调度器自定义参数

  • kube-controller-manager:对于1000个节点以上的集群,建议将kubeAPIQPS/kubeAPIBurst调整为300/500以上。

  • kube-scheduler:一般无需调整。Pod速率超过300/s时建议将connectionQPS/connectionBurst调整为800/1000。

kubelet

kubelet组件的kube-api-burst/qps默认值为5/10,一般无需调整。当您的集群出现Pod状态更新缓慢、调度延迟、存储卷挂载缓慢等显著性能问题时,建议您调大参数。操作步骤及说明,请参见自定义节点池kubelet配置

重要
  • 调大kubelet该参数会增大kubelet与API Server的通信QPS。如果kubelet发送的请求数量过多,可能会增大API Server的负载。建议您逐步增加取值,并关注API Server的性能和资源水位,确保控制面稳定性。

  • 对节点kubelet执行变更操作时,需合理控制更新频率。为保证变更过程中控制面的稳定性,ACK限制单节点池每批次的最大并行数不超过10。

规划集群资源弹性速率

在大规模集群中,当集群处于稳定运行状态时,通常不会给控制面带来太大的压力。但当集群进行大规模变更操作时,例如快速创建或删除大量资源,或大规模扩缩集群节点数时,可能会造成控制面压力过大,导致集群性能下降、响应延迟,甚至服务中断。

例如,在一个5,000个节点的集群中,如果存在大量固定数量的Pod且保持稳定运行状态,那么它对控制面的压力通常不会太大。但在一个1,000个节点的集群中,如果需要在一分钟内创建10,000个短暂运行的Job,或并发扩容2,000个节点,那么控制面的压力会激增。

因此,在大规模集群中进行资源变更操作时,需根据集群运行状态谨慎规划弹性操作的变更速率,以确保集群和控制面的稳定性。

推荐操作如下。

重要

由于集群控制面影响因素较多,以下数字仅供参考。实际操作时,请遵循变更速率由小到大的操作顺序,观察控制面响应正常后再适当提高弹性速率。

  • 节点扩缩容:对于2000个节点以上的集群,建议在通过节点池手动扩缩容节点时,单个节点池单次操作的节点数不超过100,多个节点池单次操作的总节点数不超过300。

  • 应用Pod扩缩容:若您的应用关联了Service,扩缩容过程中Endpoint、EndpointSlice的更新会推送到所有节点。在节点数量多的场景下,需要更新的相关数据也很多,可能导致集群风暴效应。对5000节点以上的集群,建议非Endpoint关联的Pod更新QPS不超过300/s;Endpoints关联的Pod更新QPS不超过10/s。例如,在Deployment中声明Pod滚动更新(Rolling Update)策略时,推荐您先设置较小的maxUnavailablemaxSurge取值,以降低Pod更新速率。

关注集群控制面指标

您可以查看控制面组件监控大盘,获取控制面核心组件的指标清单、异常指标问题解析等。在大规模集群中,请重点关注以下指标。关于指标的使用说明、详细说明,请参见控制面组件监控

管控资源水位

目前管控组件所有资源水位均可以查看,相关指标和介绍如下:

指标

类型

说明

cpu_utilization_ratio

Gauge

CPU使用率=CPU使用量/CPU资源上限,百分比形式。

memory_utilization_ratio

Gauge

内存使用率=内存使用量/内存资源上限,百分比形式。

kube-apiserver

关于如何查看指标及指标的完整说明,请参见kube-apiserver组件监控

  • 资源数,保证资源不出现泄漏

    名称

    PromQL

    说明

    资源对象数量

    • max by(resource)(apiserver_storage_objects)

    • max by(resource)(etcd_object_counts)

    Kubernetes管理资源数量。不同ACK版本指标名称不同:

    • 当ACK为1.22及以上版本时, 指标名字为apiserver_storage_objects

    • 当ACK为1.22及以下版本时,指标名字为etcd_object_counts。

    说明

    由于兼容性问题,1.22版本中apiserver_storage_objects名称和etcd_object_counts名称均存在。

  • 请求时延

    名称

    PromQL

    说明

    GET读请求时延

    histogram_quantile($quantile, sum(irate(apiserver_request_duration_seconds_bucket{verb="GET",resource!="",subresource!~"log|proxy"}[$interval])) by (pod, verb, resource, subresource, scope, le))

    展示GET请求的响应时间,维度包括API Server Pod、Verb(GET)、Resources(例如Configmaps、Pods、Leases等)、Scope(范围例如Namespace级别、Cluster级别)。

    LIST读请求时延

    histogram_quantile($quantile, sum(irate(apiserver_request_duration_seconds_bucket{verb="LIST"}[$interval])) by (pod_name, verb, resource, scope, le))

    展示LIST请求的响应时间,维度包括API Server Pod、Verb(GET)、Resources(例如Configmaps、Pods、Leases等)、Scope(范围例如Namespace级别、Cluster级别)。

    写请求时延

    histogram_quantile($quantile, sum(irate(apiserver_request_duration_seconds_bucket{verb!~"GET|WATCH|LIST|CONNECT"}[$interval])) by (cluster, pod_name, verb, resource, scope, le))

    展示Mutating请求的响应时间,维度包括API Server Pod、Verb(GET)、Resources(例如Configmaps、Pods、Leases等)、Scope(范围例如Namespace级别、Cluster级别)。

  • 请求限流

    名称

    PromQL

    说明

    请求限流速率

    sum(irate(apiserver_dropped_requests_total{request_kind="readOnly"}[$interval])) by (name)

    sum(irate(apiserver_dropped_requests_total{request_kind="mutating"}[$interval])) by (name)

    API Server限流速率,No data或者0表示没有限流。

kube-scheduler

关于如何查看指标及指标的完整说明,请参见kube-scheduler组件监控

  • Pending Pod数

    名称

    PromQL

    说明

    Scheduler Pending Pods

    scheduler_pending_pods{job="ack-scheduler"}

    Pending Pod的数量。队列种类如下:

    • unschedulable:表示不可调度的Pod数量。

    • backoff:表示backoffQ的Pod数量。

    • active:表示activeQ的Pod数量。

  • 请求时延

    名称

    PromQL

    说明

    Kube API请求时延

    histogram_quantile($quantile, sum(rate(rest_client_request_duration_seconds_bucket{job="ack-scheduler"}[$interval])) by (verb,url,le))

    调度器对kube-apiserver发起的HTTP请求时延,从方法(Verb)和请求URL维度进行分析。

kube-controller-manager

关于如何查看指标及指标的完整说明,请参见kube-controller-manager组件监控

  • workqueue depth

    名称

    PromQL

    说明

    Workqueue深度

    sum(rate(workqueue_depth{job="ack-kube-controller-manager"}[$interval])) by (name)

    Workqueue各资源当前队列深度。

  • workqueue latency

    名称

    PromQL

    说明

    Workqueue处理时延

    histogram_quantile($quantile, sum(rate(workqueue_queue_duration_seconds_bucket{job="ack-kube-controller-manager"}[5m])) by (name, le))

    记录Workqueue中任务从加入队列到开始处理所经历的时间。

etcd

关于如何查看指标及指标的完整说明,请参见etcd组件监控

  • kv总数

    名称

    PromQL

    说明

    kv总数

    etcd_debugging_mvcc_keys_total

    etcd集群kv对总数。

  • 数据库大小(DB Size)

    名称

    PromQL

    说明

    磁盘大小

    • etcd_mvcc_db_total_size_in_bytes

    • etcd_mvcc_db_total_size_in_use_in_bytes

    • etcd backend db总大小。

    • etcd backend db实际使用大小。

优化客户端访问集群模式

在Kubernetes集群中,客户端(客户业务应用程序或kubectl等)通过API Server来获取集群资源信息。随着集群中的资源数量的增加,如果客户端以相同的频率进行请求,这些请求可能会给集群控制面带来更大的负载,导致控制面响应延迟缓慢,甚至导致管控面雪崩。在访问集群资源时,需了解并规划访问资源的大小和频率。大规模集群使用建议如下。

优先使用informer访问本地缓存数据

优先使用client-go的informer获取资源,通过本地缓存(Cache)查询数据,避免List请求直接访问API Server,以减少API Server的负载压力。

优化通过API Server获取资源的方式

对于未访问过的本地缓存,仍需直接通过API Server获取资源。但可以遵循以下建议。

  • 在List请求中设置resourceVersion=0

    resourceVersion表示资源状态的版本。设置为0时,请求会获取 API Server的缓存数据,而非直接访问etcd,减少API Server与etcd之间的内部交互次数,更快地响应客户端List请求。示例如下。

    k8sClient.CoreV1().Pods("").List(metav1.ListOptions{ResourceVersion: "0"})
  • 避免全量List资源,防止数据检索量过大。

    为了减少请求返回的数据量,应使用过滤条件(Filter)来限定List请求的范围,例如lable-selector(基于资源标签筛选)或field-selector(基于资源字段筛选)。

    说明

    etcd是一个键值(KV)存储系统,本身不具备按label或field过滤数据的功能,请求带有的过滤条件实际由API Server处理。因此,当使用Filter功能时,建议同时将List请求的resourceVersion设置为0。请求数据将从API Server的缓存中获取,而不会直接访问etcd,减少对etcd的压力。

  • 使用Protobuf(而非JSON)访问非CRD资源。

    API Server可以以不同的数据格式向客户端返回资源对象,包括JSON和Protobuf。默认情况下,当客户端请求Kubernetes API时,Kubernetes返回序列化为JSON的对象,其内容类型(Content-Type)为application/json。 客户端可以指定请求使用Protobuf格式的数据,Protobuf在内存使用和网络传输流量方面相较JSON更有优势。

    但并非所有API资源类型都支持Protobuf。发送请求时,可以在Accept请求头中指定多种内容类型(例如 application/jsonapplication/vnd.kubernetes.protobuf),从而支持在无法使用Protobuf时回退到默认的JSON格式。更多信息,请参见Alternate representations of resources 。示例如下。

    Accept: application/vnd.kubernetes.protobuf, application/json

使用中心化控制器

避免在每个节点上都创建独立的控制器用于Watch集群的全量数据。在这种情况下,控制器启动时,将几乎同时向API Server发送大量的List请求以同步当前的集群状态,对控制面造成巨大压力,继而导致服务不稳定或崩溃。

为了避免此问题,建议采用中心化的控制器设计,为整个集群创建一个或一组集中管理的控制器实例,运行在单个节点或少数几个节点上。中心化的控制器会负责监听和处理所需的集群数据,仅启动一次(或少数几次)List请求,并仅维护必要数量的Watch连接,大大减少了对API Server的压力。

合理规划大规模工作负载

停用自动挂载默认的Service Account

为了确保Pod中的Secret的同步更新,kubelet会为Pod配置的每个Secret建立一个Watch长连接。Watch机制可以让kubelet实时接收Secret的更新通知。但当所有节点创建的Watch数量总和过多时,大量Watch连接可能会影响集群控制面的性能。

  • Kubernetes 1.22版本以前:创建Pod时,如果未指定ServiceAccount,Kubernetes会自动挂载默认的ServiceAccount作为Pod的Secret,使得Pod内部的应用能够与API Server安全通信。

    对于批处理系统和无需访问API Server的业务Pod,建议您显式声明禁止自动挂载ServiceAccount Token,以避免创建相关的Secret和Watch(更多信息,请参见automountServiceAccountToken)。在大规模集群中,该操作可以避免创建不必要的Secret和与API Server的Watch连接,减轻集群控制面的负担。

  • Kubernetes 1.22及之后:使用TokenRequest API来获取一个短期的、自动轮换的令牌,并以投射卷的形式进行挂载此令牌。在提高Secret安全性的同时,该操作还能减少kubelet为每个ServiceAccount的Secret建立的Watch连接,降低集群的性能开销。

    关于如何启用ServiceAccount Token投射卷功能,请参见部署服务账户令牌卷投影

控制Kubernetes Object数量和大小

请及时清理无需使用的Kubernetes资源,例如ConfigMap、Secret、PVC等,减少系统资源的占用,保持集群健康、高效运转。有以下使用建议。

  • 限制Deployment历史记录数:revisionHistoryLimit声明了要为Deployment保留多少个旧的ReplicaSet。如果取值太高,Kubernetes会保留很多历史版本的ReplicaSet,增加kube-controller-manager的管理负担。在大规模集群中,如果Deployment较多且更新频繁,您可以调低Deployment的revisionHistoryLimit的取值,清理旧的ReplicaSet。Deployment的revisionHistoryLimit默认取值为10。

  • 清理无需使用的Job和相关的Pod:如果集群中通过CronJob或其他机制创建了大量的作业(Job)对象,请使用ttlSecondsAfterFinished来自动清理集群中较旧的Pod,指定在某个时间周期后Job和相关的Pod将完成自动清理(删除)。

合理配置Informer类型组件的资源配置

Informer类型的组件主要用于监控和同步Kubernetes集群的资源状态。Informer类组件会建立对集群API Server资源状态的Watch连接,并在本地维护一个资源对象的缓存,以便快速响应资源状态的变化。

对于Informer类型的组件,例如Controller组件、kube-scheduler等,组件内存占用与其Watch的资源大小相关。大规模集群下,请关注该类组件的内存资源消耗,避免组件OOM。组件频繁OOM会导致组件持续资源监听出现问题。组件频繁重启时,每次执行的List-Watch操作也会对集群控制面(尤其是API Server)造成额外的压力。

相关文档

  • 本页导读 (1)
文档反馈