Karpenter 监控 Amazon EC2 API 用量与节流实践指南
【免费下载链接】karpenter-provider-awsKarpenter is a Kubernetes Node Autoscaler built for flexibility, performance, and simplicity.项目地址: https://gitcode.com/GitHub_Trending/ka/karpenter-provider-aws
本文围绕 Karpenter(karpenter-provider-aws)与 Amazon EC2 API 之间的交互,系统梳理 Karpenter 会调用哪些 EC2 操作、如何通过 Prometheus 指标与 CloudTrail 观测调用量和RequestLimitExceeded(HTTP 503)节流,如何对照账户级请求速率配额评估风险,以及降低被节流概率的工程化实践。读完本文,你将掌握一套可落地的 EC2 API 用量监控与容量规划方案。
Karpenter 的核心能力建立在 Amazon EC2 API 之上:它需要调用 EC2 来发现基础设施、启动和终止节点。而 AWS 对 EC2 API 请求实施按账户、按区域的速率限制,一旦请求速率超出配额,超出的请求会被拒绝并返回RequestLimitExceeded错误(HTTP 503),直接影响 Karpenter 管理集群的能力。因此,监控 EC2 API 调用量是运行 Karpenter 集群的必要运维动作。
为什么需要监控:节流如何影响 Karpenter
EC2 API 请求速率限制按账户、按区域分别生效,并且不同操作分组相互独立(例如非变更类的Describe*操作与变更类操作分开限流)。Karpenter 的调用量不是固定的,它随以下因素动态伸缩:
- 集群中
EC2NodeClass的数量; - 账户内运行的集群数量;
- 集群扩缩容的频率;
- 运行的 Karpenter 版本(不同版本对 API 的调用策略不同)。
当集群规模足够大时,请求量完全可能触达配额上限而被节流。被节流的直接后果是启动、终止、发现等关键路径上的 API 调用失败或重试,进而拖慢节点供给(provisioning)与干扰处理(disruption),最终表现为 Pod 长时间 Pending。
Karpenter 调用哪些 Amazon EC2 API
下表完整列出 Karpenter 会调用的 EC2 API、所属类别及触发时机(出自本文档源文件 monitoring-ec2-api-usage.md):
| API | 类别 | 调用时机 |
|---|---|---|
CreateFleet | 启动(热路径) | 为满足 Pending Pod 启动节点 |
CreateLaunchTemplate | 启动(热路径) | 为新节点准备启动配置 |
RunInstances | 启动(热路径) | 启动节点 |
CreateTags | 启动(热路径) | 在实例、Fleet 和启动模板创建时打标签 |
TerminateInstances | 终止 | 在 consolidation、drift 或过期(expiration)时移除节点 |
DeleteLaunchTemplate | 清理 | 移除 Karpenter 托管的启动模板 |
DescribeSubnets | 发现 / 刷新 | 为每个EC2NodeClass解析subnetSelectorTerms |
DescribeSecurityGroups | 发现 / 刷新 | 为每个EC2NodeClass解析securityGroupSelectorTerms |
DescribeImages | 发现 / 刷新 | 为每个EC2NodeClass解析amiSelectorTerms |
DescribeInstanceTypes、DescribeInstanceTypeOfferings | 发现 / 刷新 | 解析可用实例类型及其 offering |
DescribeSpotPriceHistory | 发现 / 刷新 | 确定 Spot 定价以辅助实例类型选择 |
DescribeInstances | 发现 | 调和(reconcile)已启动实例的状态 |
DescribeLaunchTemplates | 发现 | 调和 Karpenter 托管的启动模板 |
从调用时机可以看出,流量大头集中在启动热路径(CreateFleet、CreateLaunchTemplate、CreateTags)和发现/刷新路径(各类Describe*)。其中Describe*类操作是典型的非变更类(non-mutating)请求,与变更类操作分属不同的速率配额分组。
源码印证:Karpenter 对高频调用的批处理优化
为了降低外部 API 的节流压力,Karpenter 在 pkg/batcher/batcher.go 中实现了一套通用批处理库,其包注释明确指出目的:"batcher implements a generic batching lib for API calls so that load can be reduced to external APIs that excessively throttle"(实现通用 API 调用批处理库,以降低对过度节流的外部 API 的负载)。
批处理器通过IdleTimeout(空闲超时)、MaxTimeout(最大超时)、MaxItems(单批最大条目数)等参数控制批处理窗口,并使用RequestHasher对请求参数哈希分桶,把参数相同的请求合并为单次调用。实际应用中:
- pkg/batcher/createfleet.go 将多个单实例的
CreateFleet请求合并为一次调用(IdleTimeout: 35ms、MaxTimeout: 1s、MaxItems: 1000),并在返回结果时把 Fleet 返回的实例 ID 拆分回各个请求方; - pkg/batcher/describeinstances.go 合并
DescribeInstances发现请求; - pkg/batcher/terminateinstances.go 合并
TerminateInstances终止请求(IdleTimeout: 100ms)。
此外,实例类型发现通过分页器(paginator)完成,例如 pkg/providers/instancetype/instancetype.go 使用DescribeInstanceTypeOfferingsPaginator分页拉取 offering(MaxResults上限为 1000),避免单次请求超限。这些机制说明:即使 Karpenter 已经内置了节流缓解手段,大规模集群下仍可能出现节流,监控依然必要。
如何观测调用量与节流
Karpenter 以 Prometheus 格式暴露指标,默认地址为:8080/metrics,可通过METRICS_PORT环境变量修改(见 Metrics 参考文档)。AWS SDK 请求指标是衡量 Karpenter 的 EC2 调用量与节流情况最直接的途径,它们带有以下标签:
service:服务名,例如EC2;action:API 操作名,例如DescribeSubnets、CreateFleet;code:HTTP 状态码——200表示成功,503表示RequestLimitExceeded节流响应。
三个核心指标如下:
aws_sdk_go_request_total—— AWS SDK 请求总数,按service、action、code标签区分;aws_sdk_go_request_attempt_total—— 请求尝试总数(单个请求在重试时可能产生多次尝试);aws_sdk_go_request_retry_count—— 每个请求的重试次数。持续出现的重试是节流的早期信号,因为 AWS SDK 在被节流的请求报错之前会先进行重试。
对应指标定义可参见 Metrics 参考文档 中的 "AWS SDK Go Metrics" 小节,除上述三个指标外还包含aws_sdk_go_request_duration_seconds、aws_sdk_go_request_attempt_duration_seconds等辅助指标,用于观测请求延迟。
示例:按操作统计 EC2 请求速率
用以下 PromQL 绘制 Karpenter 的 EC2 请求速率(按操作分组):
sum by (action) (rate(aws_sdk_go_request_total{service="EC2"}[5m]))示例:统计被节流的请求占比
用以下 PromQL 计算 EC2 请求中被节流(HTTP 503)的比例:
sum(rate(aws_sdk_go_request_total{service="EC2", code="503"}[5m])) / sum(rate(aws_sdk_go_request_total{service="EC2"}[5m]))建议为该比例设置告警(例如接近或超过某个阈值时告警),并结合aws_sdk_go_request_retry_count观察重试趋势,以便在节流演变为可见错误前提前介入。
通过 CloudTrail 归因 Karpenter 的 API 调用
Karpenter 会为其 AWS SDK 客户端设置karpenter.sh-<version>形式的 User-Agent(实现见 pkg/operator/operator.go,其中WithUserAgent通过awsmiddleware.AddUserAgentKey注入 User-Agent)。因此你可以在 AWS CloudTrail 中按userAgent过滤出以karpenter.sh-开头的记录,将 EC2 API 事件准确归因到 Karpenter,从而:
- 核对某个时段内 Karpenter 实际发起的 API 调用明细;
- 结合 CloudTrail 与上述 Prometheus 指标交叉验证调用量与节流情况;
- 排查 Karpenter 之外(如其他工具或人工操作)是否也占用了同一账户的配额。
如何对照账户的 EC2 API 请求速率配额
Amazon EC2 API 请求速率限制按账户、按区域生效,并且不同操作分组相互独立(例如非变更的Describe*操作与变更类操作分属不同配额组)。因此:
- 在 Karpenter 运行的每个区域,通过 AWS Service Quotas 查看该账户已应用的 Amazon EC2 配额;
- 将配额与上文指标观测到的稳态请求速率进行对比;
- 若稳态请求速率接近或超过配额,及时申请提高配额(request an increase)。
需要特别注意的是:同一账户内所有集群的请求量会竞争同一份配额。因为限额按账户和区域计,账户里每多一个集群,都在为这份共享配额增加负担。评估时应以账户(而非单个集群)为单位汇总请求速率。
最佳实践:用多账户架构隔离集群
这是官方文档给出的核心建议:由于请求速率配额按账户、按区域生效,把大量集群集中在一个账户中,等于把所有集群的 EC2 请求量集中到该账户的配额上。采用按账户隔离集群的多账户架构,可以将请求量分散到多个账户各自的配额中,显著降低单账户被节流的概率。具体架构设计可参考 AWS Well-Architected Framework 中的多账户指引。
其他可配合的实践要点
- 持续监控:将上文两条 PromQL 做成长期面板与告警,覆盖启动热路径(
CreateFleet等)与发现路径(Describe*等)的分组视图; - 善用批处理内置优化:确认运行的是较新的 Karpenter 版本,以享受 pkg/batcher 中
CreateFleet、DescribeInstances、TerminateInstances等批处理带来的调用量削减; - 关注
EC2NodeClass规模:DescribeSubnets、DescribeSecurityGroups、DescribeImages等发现类调用随EC2NodeClass数量线性增长,精简选择器(selectorTerms)数量可减少不必要的发现请求; - 按区域核对配额:在多区域部署时,逐个区域检查 Service Quotas,因为配额不跨区域共享。
小结
Karpenter 对 Amazon EC2 API 的依赖是刚性的,而 AWS 的请求速率配额是硬性的。通过本文介绍的指标观测(aws_sdk_go_request_total等)、CloudTrail User-Agent 归因、Service Quotas 对照和多账户隔离,你可以系统性地评估并管理 EC2 API 用量,将RequestLimitExceeded对集群供给能力的影响控制在可接受范围。相关原始文档位于 website/content/en/v1.0/tasks/monitoring-ec2-api-usage.md,同一主题在 v1.12、v1.13、v1.14 及 preview 文档树中均有对应版本,可作为跨版本运维参考。
【免费下载链接】karpenter-provider-awsKarpenter is a Kubernetes Node Autoscaler built for flexibility, performance, and simplicity.项目地址: https://gitcode.com/GitHub_Trending/ka/karpenter-provider-aws
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考