资讯动态

Karpenter NodeOverlays 完全指南:为 AWS 实例类型注入自定义价格与扩展资源的调度模拟微调

发布时间:2026/9/17 22:01:56 来源:尧图企业网站定制
Karpenter NodeOverlays 完全指南为 AWS 实例类型注入自定义价格与扩展资源的调度模拟微调【免费下载链接】karpenter-provider-awsKarpenter is a Kubernetes Node Autoscaler built for flexibility, performance, and simplicity.项目地址: https://gitcode.com/GitHub_Trending/ka/karpenter-provider-awsNodeOverlays 是 Karpenterkarpenter-provider-aws提供的一项 Alpha 级能力允许用户以声明式方式向调度模拟中注入备选实例类型信息——包括覆盖实例价格、追加扩展资源如 fractional GPU、hugepages、自定义设备。本文基于仓库 website/content/en/v1.13/concepts/nodeoverlays.md 系统讲解 NodeOverlay 的配置模型、冲突解决规则、与 Consolidation 的集成、状态可观测性并结合仓库源码CRD 定义、CloudProvider 实现、Offering 定价解析深入其底层原理帮助读者掌握如何用 NodeOverlay 解决实际调度痛点如 EC2 g6f 分数 GPU、预览实例类型定价缺失。什么是 NodeOverlay为什么需要覆盖实例类型信息Karpenter 在做出节点供给决策前会基于云厂商如 AWS上报的实例类型原始数据运行一次调度模拟scheduling simulation评估哪些实例类型能满足待调度 Pod 的需求再结合价格、可用区offering等因子选出最优解。问题在于云厂商的原始数据并不总能反映真实世界价格失真Savings Plans、企业折扣、软件许可成本、自定义合同价都不会出现在 AWS Pricing API 中Karpenter 的最优解可能与真实账单相悖资源缺失某些硬件资源vGPU 切片、FPGA 分片、自定义加速器在DescribeInstanceTypes中上报为Count0导致请求这些资源的 Pod 永远无法被匹配数据空白预览pre-GA实例类型尚未进入 AWS Pricing API没有价格会被 Karpenter 标记为不可用。NodeOverlay 正是为弥补这些差距而设计它通过在调度模拟阶段修改 Karpenter 使用的实例类型信息——调整价格或追加扩展资源——来让调度决策更贴近现实。正如仓库文档所述Karpenter uses NodeOverlays to inject alternative instance type information into the scheduling simulation for more accurate scheduling decisions.从源码角度印证在 pkg/cloudprovider/cloudprovider.go 的Create流程中当NodeOverlayfeature gate 开启时Karpenter 会调用instanceTypeStore.ApplyAll(nodePoolName, instanceTypes)将匹配 NodePool 的 Overlay 应用到待选实例类型集合上之后才交给instanceProvider.Create去真正创建实例。也就是说NodeOverlay 是调度模拟的输入修正器它不影响实例本身的真实规格。启用 NodeOverlayFeature GateNodeOverlay 目前处于Alpha阶段karpenter.sh/v1alpha1默认关闭必须显式开启在 Karpenter controller 启动参数中添加--feature-gates NodeOverlaytrue或在 ConfigMap 中设置环境变量FEATURE_GATESNodeOverlaytrue以 website/content/en/v1.13/reference/settings.md 中的 Feature Gate 表为准NodeOverlay 的默认值为false引入于 v1.7.x 系列。其余可用 gate如NodeRepair、ReservedCapacity、SpotToSpotConsolidation、StaticCapacity与 NodeOverlay 互不影响可独立开关。开启后还需确保 NodeOverlay CRD 已安装——它随 Helm Chart 一起下发CRD 定义见 pkg/apis/crds/karpenter.sh_nodeoverlays.yaml同时该 CRD 也以独立 Chart 形式存在于 charts/karpenter/crds/karpenter.sh_nodeoverlays.yaml。CRD 提供了短名overlays便于kubectl get overlays快速查询。NodeOverlay 配置模型NodeOverlay 是**集群级Cluster-scoped**资源一个典型配置如下取自原文档并补充字段约束apiVersion: karpenter.sh/v1alpha1 kind: NodeOverlay metadata: name: example-overlay spec: # 冲突解决权重值越大优先级越高取值范围 1-10000 weight: 10 # requirements 决定该 overlay 作用于哪些实例类型 requirements: - key: node.kubernetes.io/instance-type operator: In values: [m5.large, m5.xlarge] - key: karpenter.sh/capacity-type operator: In values: [spot] - key: karpenter.k8s.aws/instance-cpu operator: Gte values: [32] # price 与 priceAdjustment 互斥二者只能设置其一 # price 为绝对价格覆盖替换云厂商上报的原价 price: 5.00 # priceAdjustment 为相对调整在现有价格基础上修改 priceAdjustment: 10% # 或 -0.50 这种绝对数值调整 # capacity 用于向匹配的实例类型追加扩展资源不能覆盖标准资源 capacity: hugepages-2Mi: 100Mi hugepages-1Gi: 2Gi custom-device/gpu-slice: 4spec.weight可选的整数字段CRD 中定义范围1-10000决定多个 NodeOverlay 同时匹配同一实例类型时的优先级权重更高的 Overlay 优先权重相等时按名称字母序依次合并未指定时按权重0处理CRD 描述明确 If no weight is specified, the NodeOverlay is treated as having a weight of 0若同权重 Overlay 之间发生冲突冲突会在 status 中标明该 Overlay不会被应用。CRD 中对应校验见 pkg/apis/crds/karpenter.sh_nodeoverlays.yamlformat: int32、maximum: 10000、minimum: 1并且提供了额外的 printer columnWeightkubectl get overlays时可直接查看各 Overlay 的权重。spec.requirements数组类型决定 Overlay 应用于哪些实例类型格式与 NodePool 的 requirements 完全一致支持全部标准 Kubernetes 标签选择算子。空数组表示应用于所有实例类型。算子方面CRD 枚举了In、NotIn、Exists、DoesNotExist、Gt、Lt、Gte、Lte并附带 CEL 校验CRD 定义In/NotIn必须提供非空 valuesGt/Lt/Gte/Lte必须恰好一个值且该值须为非负整数。requirements 的 key 可以引用Kubernetes 的Well-Known Labels如node.kubernetes.io/instance-type、node.kubernetes.io/zone等完整清单见 website/content/en/v1.13/concepts/scheduling.md 中的 Well-Known Labels 小节AWS 专属标签用于更精细的调度控制例如karpenter.k8s.aws/instance-family、karpenter.k8s.aws/instance-cpu、karpenter.k8s.aws/instance-gpu-memory等同一小节中同样列出NodePool 的spec.template.labels中自定义标签CRD 描述明确支持。CRD 对 key 的取值域做了白名单式约束CRD 定义karpenter.sh域仅允许karpenter.sh/capacity-type与karpenter.sh/nodepoolkarpenter.k8s.aws域仅允许文档中列出的实例类型属性标签如instance-family、instance-cpu、instance-gpu-memory等kubernetes.io/hostname被明确禁用。注意NodeOverlay 上的 requirements 总数存在100 条上限CRD 中maxItems: 100规划匹配规则时需留意。spec.price字符串形式的绝对价格覆盖代表以你的币种计的价格。设置后完全替换云厂商上报的原始实例价格。Karpenter 与币种无关currency-agnostic因此任意币种单位均可使用。CRD 对price的正则约束为^\d(\.\d)?$即非负十进制数。典型场景当你与云厂商签订了低于挂牌价的合同价、或购买了 Savings Plans 时可以用price让 Karpenter 在成本计算中使用真实价格从而正确参与 spot/on-demand 选择与 consolidation 决策。spec.priceAdjustment在现有价格基础上的相对修改支持两种写法绝对数值调整5.00涨价 5.00、-2.50降价 2.50百分比调整15%涨价 15%、-10%降价 10%。CRD 对priceAdjustment的正则约束为^(([-]{1}(\d*\.?\d))|(\{1}\d*\.?\d%)|(^(-\d{1,2}(\.\d)?%)$)|(-100%))$即带符号的数值调整或带的百分比上调或不超过两位整数的百分比下调含 -100%。price与priceAdjustment互斥——CRD 通过 CEL 规则!has(self.price) || !has(self.priceAdjustment)强制校验CRD 定义二者同时设置会在创建/更新时被拒绝。spec.capacity扩展资源映射向匹配的实例类型追加这些资源只会新增资源不会替换或修改标准资源CPU、内存、临时存储、Pod 数量等只能指定扩展资源名——CRD 的 CEL 校验明确拒绝cpu、memory、ephemeral-storage、podsCRD 定义资源量支持整数或量化字符串如100Mi、2Gi、4。实际效果调度模拟中的实例类型会同时携带原有标准容量与 Overlay 追加的扩展容量。NodeClaim 创建后其Status.Capacity与Status.Allocatable也会反映这些追加资源见 pkg/cloudprovider/cloudprovider.go 中基于instanceType.Capacity填充 NodeClaim 状态但请注意这仍然只是 Karpenter 视角的模拟值——节点上真实的扩展资源能否被 kubelet 感知取决于节点上的设备插件 / 配置是否真正提供该资源。一个仅为自定义设备配置的例子apiVersion: karpenter.sh/v1alpha1 kind: NodeOverlay metadata: name: custom-devices spec: requirements: - key: node.kubernetes.io/instance-type operator: In values: [m5.large, m5.xlarge, m5.2xlarge] capacity: smarter-devices/fuse: 1 custom-hardware/accelerator: 2冲突解决Conflict Resolution当多个 NodeOverlay 同时匹配同一实例类型时按以下规则处理权重优先weight值高的 Overlay 优先字母序权重相等时按名称字母序依次应用字段级合并高权重 Overlay 会覆盖低权重 Overlay 的特定字段如price/priceAdjustment但capacity 字段会跨 Overlay 合并。文档给出的冲突示例apiVersion: karpenter.sh/v1alpha1 kind: NodeOverlay metadata: name: overlay-a spec: weight: 5 requirements: - key: node.kubernetes.io/instance-type operator: In values: [m5.large] priceAdjustment: -10% capacity: hugepages-2Mi: 50Mi --- apiVersion: karpenter.sh/v1alpha1 kind: NodeOverlay metadata: name: overlay-b spec: weight: 10 # 更高权重 requirements: - key: node.kubernetes.io/instance-type operator: In values: [m5.large] priceAdjustment: -20% # 覆盖 overlay-a 的调整 capacity: custom-device/gpu: 1 # 与 overlay-a 的 hugepages-2Mi 合并m5.large 的最终结果价格调整-20%来自 overlay-b覆盖 overlay-a 的-10%容量hugepages-2Mi: 50Mi来自 overlay-a custom-device/gpu: 1来自 overlay-b。NodeOverlay 与 Consolidation 的集成NodeOverlay 的修改会自动进入 Karpenter 的consolidation整合流程价格调整影响 consolidation 的替换决策——成本计算直接决定当前节点是否值得被替换为更优实例容量追加在评估工作负载能否迁移到其他节点时被纳入考量变更无需 drift 检测或强制替换节点会在下一个 consolidation 评估周期自然生效。当 NodeOverlay 配置发生变化时Karpenter 会在下一次 consolidation 评估中采用新配置如果新配置显著改变了现有工作负载的最优实例选择则可能触发节点替换。这意味着你可以通过调整 Overlay 价格来主动引导consolidation 将工作负载迁移到更经济的实例上而无需手动驱逐。从实现层面看价格注入发生在 offering 解析阶段在 pkg/providers/instancetype/offering/offering.go 的GetOverlayPrice方法中当 feature gate 开启时Karpenter 会列出所有ValidationSucceededTrue的 NodeOverlay只提取恰好一个node.kubernetes.io/instance-typeIn算子 绝对price的条目解析后写入实例类型价格映射并由BaseResolver通过GetOverlayPrice回调在解析 offering 时使用。该映射带缓存与过期时间对应文档所述5 分钟定价缓存缓存过期后修改才会生效ResetOverlayPrice则提供手动清空缓存的能力。使用 NodeOverlay 支持预览实例类型Preview Pricing预览pre-GA实例类型在你的 AWS 账户中已可见DescribeInstanceTypes能查到但尚未进入 AWS Pricing API。没有价格时Karpenter 会把相关 offering 标记为不可用拒绝供给。此时可以用一个形状严格受限的 NodeOverlay 为预览实例显式定价使其可调度。使用前提开启NodeOverlayfeature gate你的 AWS 账户已对预览实例类型白名单放行它才会出现在DescribeInstanceTypes中创建形状完全符合下述规范的 NodeOverlayapiVersion: karpenter.sh/v1alpha1 kind: NodeOverlay metadata: name: preview-instance-pricing spec: requirements: - key: node.kubernetes.io/instance-type operator: In values: # 填入你的预览实例类型 price: # 填入你的预估价格该 Overlay 必须满足恰好一个requirementkey 为node.kubernetes.io/instance-type、operator 为In使用绝对price不能是priceAdjustment不得有其他 requirements如 capacity-type、zone、CPU 等。不符合此精确结构的 Overlay 会被预览定价逻辑忽略。这一限制与源码一一对应GetOverlayPrice只处理len(overlay.Spec.Requirements) 1 key node.kubernetes.io/instance-type operator In的条目pkg/providers/instancetype/offering/offering.go。注意事项全局生效预览定价是集群级的。任何 requirements 匹配到该预览实例类型的 NodePool 都能调度上去无法限定到单个 NodePool价格是估算值官方定价尚未发布需自行提供。该值会影响 Karpenter 的成本型决策consolidation、spot vs on-demand 选择缓存延迟Overlay 价格缓存 5 分钟修改后需等缓存过期才生效必须通过校验Overlay 需达到ValidationSucceededTrue状态才会被用于预览定价源码中同样以overlay.StatusConditions().IsTrue(v1alpha1.ConditionTypeValidationSucceeded)作为过滤条件offering.go。状态与可观测性NodeOverlay 通过 status conditions 暴露当前状态便于排查配置问题。常见状态条件ReadyTrueOverlay 已成功应用到匹配的实例类型ReadyFalse配置冲突、requirements 不匹配或其他错误导致 Overlay 无法应用。状态消息当ReadyFalse时status message 会给出具体原因例如status: conditions: - type: ValidationSucceeded status: False lastTransitionTime: 2024-07-24T18:30:00Z reason: Conflict message: conflict with another overlayCRD 为 NodeOverlay 定义了 printer columnsCRD 定义kubectl get overlays默认展示Ready、Age加-o wide可看到Weight列方便快速巡检多个 Overlay 的状态与优先级。实战为 g6f 分数 GPU 实例启用 nvidia.com/gpu 调度这是 NodeOverlay 最具代表性的真实用例。EC2 的g6f实例家族通过 vGPUGRID技术提供分数级 NVIDIA L4 GPU每个 g6f 实例把一块物理 L4 GPU 的 1/8 到 1/2 切片作为一个逻辑 GPU 设备暴露。但问题在于EC2DescribeInstanceTypesAPI 对 g6f 上报Count0导致 Karpenter无法原生发现其 GPU 容量——请求nvidia.com/gpu的 Pod 永远不会被调度到 g6f 上。用 NodeOverlay 告知 Karpenter g6f 拥有 GPU 资源apiVersion: karpenter.sh/v1alpha1 kind: NodeOverlay metadata: name: g6f-fractional-gpu spec: requirements: - key: karpenter.k8s.aws/instance-family operator: In values: [g6f] capacity: nvidia.com/gpu: 1再创建一个指向 g6f 的 NodePoolapiVersion: karpenter.sh/v1 kind: NodePool metadata: name: fractional-gpu spec: template: spec: nodeClassRef: group: karpenter.k8s.aws kind: EC2NodeClass name: gpu-nodeclass requirements: - key: karpenter.k8s.aws/instance-family operator: In values: [g6f] - key: karpenter.sh/capacity-type operator: In values: [on-demand] limits: nvidia.com/gpu: 4配置生效后的完整流程Karpenter 的调度模拟将 g6f 实例视为拥有nvidia.com/gpu: 1请求nvidia.com/gpu: 1的 Pod 可与 g6f 实例匹配实例启动后NVIDIA device plugin 检测到 vGPU 设备并向 kubelet 上报nvidia.com/gpu: 1Pod 被调度到分数 GPU 实例上正常运行。重要提示g6f 各规格的 GPU 内存不同——g6f.xlarge约 3 GB、g6f.2xlarge约 6 GB、g6f.4xlarge约 12 GB。请使用karpenter.k8s.aws/instance-gpu-memory标签该标签含义为GPU 内存的 MiB 数见 website/content/en/v1.13/concepts/scheduling.md 的 Well-Known Labels 表或实例规格 requirements确保工作负载落在规格合适的实例上。限制与注意事项资源范围NodeOverlay 只能添加扩展资源不能修改或移除标准资源CPU、内存、存储、Pod 数模拟 vs 实际容量修改只影响 Karpenter 的调度模拟节点真实资源必须通过其他手段设备插件、节点配置提供二者必须对齐否则会出现调度上了但 Pod 起不来的假容量问题价格 vs 账单价格调整只影响 Karpenter 的调度决策不改变云厂商的真实计费——它解决的是决策用价与实际账单不一致导致的次优调度Alpha 状态NodeOverlay 目前为v1alpha1API 可能在后续版本中变化作用范围从源码看NodeOverlay 通过nodeClaim.Labels[v1.NodePoolTagKey]关联 NodePool 后才会应用pkg/cloudprovider/cloudprovider.go即独立创建的 NodeClaim未归属 NodePool不支持 NodeOverlay这一点是设计上的取舍。小结NodeOverlay 为 Karpenter 的调度模拟打开了一个可编程修正的窗口用requirements精确圈定实例类型范围用price/priceAdjustment修正成本模型用capacity补齐云厂商数据缺失的扩展资源再用weight与名称字母序处理多 Overlay 冲突。配合 consolidation 的自动生效机制它既能解决 g6f 分数 GPU、预览实例定价这类云数据缺位问题也能让成本优化贴合真实账单。使用时请牢记其 Alpha 状态、模拟与实际的边界以及价格不影响账单这一关键前提。【免费下载链接】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),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价