Karpenter 监控 Amazon EC2 API 调用量与请求限流(Throttling)完整指南
【免费下载链接】karpenter-provider-awsKarpenter is a Kubernetes Node Autoscaler built for flexibility, performance, and simplicity.项目地址: https://gitcode.com/GitHub_Trending/ka/karpenter-provider-aws
AWS 会对每个账户、每个区域的 Amazon EC2 API 请求速率设置配额,当 Karpenter 的请求速率超过该配额时,多余的请求会被拒绝并返回RequestLimitExceeded错误(HTTP 503),进而影响 Karpenter 发现基础设施、启动和终止节点的能力。本指南以 karpenter-provider-aws 项目在 v1.12 版本的任务文档为骨架,系统梳理 Karpenter 会调用哪些 EC2 API、如何通过 Prometheus 指标观测调用量与限流、如何将观测值与账户配额对比,以及降低调用量的最佳实践与临时缓解手段。读完本文,你将能够建立一套完整的"调用量观测 → 配额对比 → 容量规划"监控闭环,提前发现并规避限流风险。
为什么需要监控 EC2 API 调用量
Karpenter 的工作机制决定了它天然是 Amazon EC2 API 的"高频调用方":
- 它需要通过 EC2 API发现基础设施(子网、安全组、AMI、实例类型、竞价价格等);
- 它需要通过 EC2 API启动和终止节点(
CreateFleet、RunInstances、TerminateInstances等)。
而 AWS 对 EC2 API 的请求速率限制是按账户(per-account)、按区域(per-Region)强制执行的,并非按集群或按 Karpenter 实例。因此,只要某个账户在一个区域内运行着足够大的集群规模,产生足够多的请求,就存在被限流的可能。
更关键的一点是:Karpenter 的 EC2 API 调用量并不是固定的,它会随以下因素动态伸缩:
- 运行的
EC2NodeClass数量与集群数量; - 集群扩缩容的频率(scale up / scale down 越频繁,Launch/Terminate 类的请求越多);
- Karpenter 自身的版本(不同版本对缓存、刷新与重试策略的实现不同)。
由于调用量具备这种可伸缩性,单靠"想当然地认为流量不大"是不够的,必须将其纳入持续监控。
Karpenter 会调用哪些 Amazon EC2 API
Karpenter 对 EC2 API 的调用可以划分为三大类:Launch(热路径)、Terminate(终止)、Cleanup(清理),以及大量的Discovery(发现/刷新)类调用。下表完整列出 v1.12 文档所声明的 API 及其调用时机:
| API | 类别 | Karpenter 何时调用 |
|---|---|---|
CreateFleet | Launch(热路径) | 为满足待调度 Pod 而启动节点 |
CreateLaunchTemplate | Launch(热路径) | 为新节点准备启动配置 |
RunInstances | Launch(热路径) | 启动节点 |
CreateTags | Launch(热路径) | 在创建实例、车队与启动模板时打标签 |
TerminateInstances | Terminate | 在 consolidation、drift 或过期(expiration)期间移除节点 |
DeleteLaunchTemplate | Cleanup | 清理 Karpenter 托管的启动模板 |
DescribeSubnets | Discovery / refresh | 为每个EC2NodeClass解析subnetSelectorTerms |
DescribeSecurityGroups | Discovery / refresh | 为每个EC2NodeClass解析securityGroupSelectorTerms |
DescribeImages | Discovery / refresh | 为每个EC2NodeClass解析amiSelectorTerms |
DescribeCapacityReservations | Discovery / refresh | 解析capacityReservationSelectorTerms(On-Demand Capacity Reservations) |
DescribeInstanceTypes、DescribeInstanceTypeOfferings | Discovery / refresh | 解析可用的实例类型及其 offerings |
DescribeSpotPriceHistory | Discovery / refresh | 为实例类型选择确定 Spot 定价 |
DescribePlacementGroups | Discovery | 解析EC2NodeClass引用的 placement groups |
DescribeInstances、DescribeInstanceStatus | Discovery | 对账(reconcile)已启动实例的状态 |
DescribeLaunchTemplates | Discovery | 对账 Karpenter 托管的启动模板 |
从源码结构看,Karpenter 在架构上为 EC2 API 调用做了若干收敛设计,这直接关系到你的调用量观测:
- 热路径的批量合并:
pkg/batcher/目录实现了针对CreateFleet、DescribeInstances、TerminateInstances等调用的批处理器(batcher),例如 pkg/batcher/createfleet.go 中的CreateFleetBatcher会把一段时间窗口内的多个CreateFleetInput合并后一次性调用底层 EC2 API,其对应的测试 pkg/batcher/createfleet_test.go 验证了"多个请求只产生一次底层调用"的行为。这意味着你在指标里看到的请求总数已经是批量合并后的结果。 - User-Agent 打标:Karpenter 在创建 AWS SDK 客户端时会追加
karpenter.sh-<version>形式的 User-Agent(见 pkg/operator/operator.go#L296-L303 的WithUserAgent),这为后续在 CloudTrail 中归因流量提供了依据。
如何观测调用量与限流
指标端点与三个核心指标
Karpenter 默认在:8080/metrics暴露 Prometheus 指标,端口可通过环境变量/启动参数METRICS_PORT修改(默认值为 8080,见 v1.12 Settings 参考 中的METRICS_PORT行)。
观测 EC2 调用量最直接的指标是AWS SDK Go 请求指标,它们在 v1.12 Metrics 参考 中被列为 STABLE 稳定性等级,分别带有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_go_request_retry_count的预警价值:AWS SDK 在被限流的请求以错误形式暴露出来之前,会先对其进行重试。因此,持续上升的重试计数是限流的最早期信号——当你看到 retry 指标抬头时,说明限流可能已经在发生,只是尚未体现为 503 错误。
推荐 PromQL 查询
按操作维度绘制 Karpenter 的 EC2 请求速率:
sum by (action) (rate(aws_sdk_go_request_total{service="EC2"}[5m]))绘制 Karpenter EC2 请求中被限流(503)的占比:
sum(rate(aws_sdk_go_request_total{service="EC2", code="503"}[5m])) / sum(rate(aws_sdk_go_request_total{service="EC2"}[5m]))第二个查询尤其适合作为告警规则:当该比例在较长周期内持续非零或明显上升时,就应该触发告警并着手处理。
通过 CloudTrail 归因流量
指标能告诉你"Karpenter 调用了多少",而如果需要进一步做审计级归因(例如确认某批 EC2 API 事件确实来自 Karpenter),可以借助 AWS CloudTrail:
- Karpenter 在其 AWS SDK 客户端上设置
karpenter.sh-<version>形式的 User-Agent(源码实现见 pkg/operator/operator.go#L296-L303); - 因此,在 CloudTrail 事件中按
userAgent过滤,筛选出以karpenter.sh-开头的值,即可把 EC2 API 事件归因到 Karpenter 及其版本。
如何对比账户的 EC2 API 请求速率限额
观测到调用量之后,下一步是判断"是否接近或超过配额"。要点如下:
- 限额是按账户、按区域独立生效的:同一账户内不同区域的限额彼此独立,需要在每个运行 Karpenter 的区域分别核查。
- 不同动作组独立限额:非变更类(non-mutating)的
Describe*动作与变更类(mutating)动作的限额是分别计算的,例如DescribeSubnets的配额与CreateFleet的配额互不影响。因此对比限额时,应将观测到的Describe*请求速率与对应的 Describe 配额对比,将 Launch/Terminate 类请求速率与对应的变更类配额对比。 - 使用 Service Quotas 核查已应用的限额:在 Service Quotas 控制台中查看 Amazon EC2 在每个区域已应用的请求速率限额,与上文从指标观测到的稳态请求速率进行对比。
- 接近或超过即申请提升:如果稳态请求速率接近甚至超过限额,应及时通过 Service Quotas 申请提高配额。
- 注意账户内多集群的叠加效应:由于限额按账户生效,一个账户内所有集群的 EC2 请求量会竞争同一份限额。这意味着即使单个集群的调用量不大,多个集群叠加后也可能触及配额。
最佳实践:用多账户架构隔离集群
限额的"按账户、按区域"特性直接推导出一条架构层面的最佳实践:
将大量集群集中在一个账户中,等于把所有这些集群的 EC2 请求量全部压向该账户的同一份限额。
因此,建议采用多账户架构(multi-account architecture),按账户隔离集群,从而把请求量分散到多个账户各自的限额上。这与 AWS Well-Architected Framework 中的多账户指引思路一致:账户不仅是安全与成本边界,在这里也成为API 速率限额的天然扩容单元。
临时缓解手段:调大刷新间隔(workaround)
重要警告
调大刷新间隔是一个临时缓解手段(workaround),而不是推荐的长期配置,官方文档明确警告不要依赖它:
- 它只能通过牺牲数据新鲜度来降低
Describe*调用量; - 间隔越大,Karpenter 观察到变化(如子网的可用 IP 容量变化、新的 AMI 发布)就越慢,可能基于陈旧数据做出决策;
- 因此它只应作为短期措施,在根本问题(底层调用量过大或配额不足)被解决之前临时使用。
正确做法仍是:优先采用上文的多账户架构等最佳实践,并申请与调用量匹配的限额。
可配置的刷新间隔
Karpenter 会按固定间隔刷新每个EC2NodeClass缓存的子网、安全组与 AMI 数据。这些间隔是可配置的,相关参数定义于 pkg/operator/options/options.go#L72-L73,对应 v1.12 的 Settings 体系:
| 参数(环境变量) | 作用 | 默认值 | 源码约束 |
|---|---|---|---|
SUBNET_REFRESH_INTERVAL | 子网数据刷新频率(约束DescribeSubnets调用量) | 1m | 最小1m |
AMI_REFRESH_INTERVAL | AMI 数据刷新频率(约束DescribeImages调用量) | 1m | 最小1m |
从源码实现看,这两个选项同时支持环境变量与 CLI 参数两种注入方式(fs.DurationVar与env.WithDefaultDuration组合),并明确校验"必须至少为 1m"。
效果量化
由于Describe*请求的稳态速率与刷新间隔近似成反比,把间隔从1m调大到5m,可将对应调用的速率大致降低约 5 倍。这种线性关系使你可以根据观测到的调用量反推所需的间隔,但务必在"降低速率"与"数据新鲜度"之间权衡,并尽快回到正式的容量规划路径上。
小结
围绕"EC2 API 调用量监控",可以形成一套完整的操作闭环:
- 了解调用面:Karpenter 的 Launch/Terminate/Cleanup 调用驱动扩缩容,Discovery 调用随
EC2NodeClass数量与刷新节奏持续发生; - 持续观测:通过
:8080/metrics上的aws_sdk_go_request_total、aws_sdk_go_request_attempt_total、aws_sdk_go_request_retry_count三个指标跟踪请求速率、尝试次数与重试趋势,用code="503"识别限流,用karpenter.sh-前缀的 User-Agent 在 CloudTrail 中归因; - 对比配额:按账户、按区域、按动作组分别比对 Service Quotas 与观测速率,接近或超过即申请提升;
- 架构治理:优先采用多账户架构分散请求量;
- 临时兜底:仅在必要时临时调大
SUBNET_REFRESH_INTERVAL/AMI_REFRESH_INTERVAL,并尽快回归正式方案。
【免费下载链接】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),仅供参考