news 2026/9/16 16:21:20

Karpenter for AWS 核心概念详解:NodePool 约束、节点干扰策略与分层调度模型

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Karpenter for AWS 核心概念详解:NodePool 约束、节点干扰策略与分层调度模型

Karpenter for AWS 核心概念详解:NodePool 约束、节点干扰策略与分层调度模型

【免费下载链接】karpenter-provider-awsKarpenter is a Kubernetes Node Autoscaler built for flexibility, performance, and simplicity.项目地址: https://gitcode.com/GitHub_Trending/ka/karpenter-provider-aws

Karpenter 是面向 AWS 的 Kubernetes 节点自动扩缩容器(Node Autoscaler)。本篇技术文章基于仓库中 Karpenter 概念文档(website/content/en/preview/concepts/),以集群管理员与应用开发者两类角色为主线,完整讲解 Karpenter 的安装与 IRSA 权限模型、NodePool 约束配置、节点干扰(Disruption)的五种机制、分层约束调度模型,以及它与 Kubernetes Cluster Autoscaler 的设计差异。读完后,你将能够独立配置 NodePool、理解 Pod 约束如何转化为节点需求,并借助仓库中的示例 YAML 与源码实现完成生产环境的容量管理。

两类使用者:集群管理员与应用开发者

Karpenter 的概念体系围绕两类角色展开:

  • Kubernetes 集群管理员:负责安装 Karpenter、通过 NodePool 配置节点管理约束、执行节点干扰操作;
  • 应用开发者:部署 Pod,并通过调度约束(nodeAffinity、nodeSelector 等)向 Karpenter 声明计算资源需求。

两者的交汇点在于分层约束(Layered Constraints):管理员在 NodePool 中定义约束的“上界”,开发者在 Pod spec 中进一步收紧约束,Karpenter 在两者交集内选择最优实例。

集群管理员视角

安装 Karpenter:Helm Chart 与 IRSA 权限

Karpenter 被设计为运行在你自己的 Kubernetes 集群节点上(而非独立集群外部)。由于添加/删除节点、调度 Pod 的请求都通过 Kubernetes 发起,集群需要AWS IAM Roles for Service Accounts(IRSA)来让 Karpenter 以特权身份访问 AWS API——例如查询 EC2 实例规格、创建 EC2 实例等。

安装流程(详见 Getting Started 文档):

  1. 创建 Kubernetes ServiceAccount 与 AWS IAM Role,通过 IRSA 关联,授权 Karpenter 启动实例所需的最小权限集;
  2. 使用 Helm Chart 部署 Karpenter。仓库中维护的 chart 位于 charts/karpenter。

从 charts/karpenter/values.yaml 可以看到 chart 的关键默认值:

  • serviceAccount.create: true:默认创建 ServiceAccount,你可以在serviceAccount.annotations中写入eks.amazonaws.com/role-arn完成 IRSA 绑定;
  • replicas: 2:控制器默认双副本高可用;
  • podDisruptionBudget(name: karpenter, maxUnavailable: 1):保证滚动升级期间至少一个控制器在线;
  • priorityClassName: system-cluster-criticaltolerations: CriticalAddonsOnly:确保 Karpenter Pod 优先调度并容忍关键节点污点;
  • 通过topologySpreadConstraints(按topology.kubernetes.io/zone打散)与节点亲和(要求karpenter.sh/nodepool标签不存在)保证控制器避开 Karpenter 自己创建的节点、跨可用区分布。

权限就绪后,Karpenter 即开始监听集群中不可调度的 Pod 并自动供给节点。

配置 NodePool:约束、标签与行为

Karpenter 的职责是:为不可调度的 Pod 添加节点、在其上调度 Pod,并在节点不再需要时移除它们。配置 Karpenter 的核心对象是NodePool——每个 NodePool 管理一组独立的节点,但 Pod 可以被调度到任何满足其调度约束的 NodePool 上。

关于 NodePool,有几个关键事实(与 NodePools 文档一致):

  • 只处理不可调度 Pod:Karpenter 只尝试调度status condition Unschedulable=True的 Pod,这是 kube-scheduler 在无法将 Pod 放置到现有容量上时设置的标记;
  • 无 NodePool 则完全静止:如果没有配置至少一个 NodePool,Karpenter 不做任何事情;
  • 污点过滤:如果 NodePool 中有 Pod 未容忍的 taint,Karpenter 不会用该 NodePool 为该 Pod 供给节点;startup taint 则被视为临时性污点,Pod 无需容忍;
  • 推荐互斥:建议创建互斥的 NodePool,使一个 Pod 最多匹配一个 NodePool;若匹配多个,Karpenter 会选择spec.weight最高的那个。

一个完整的、可直接复制运行的 NodePool + EC2NodeClass 示例见 examples/v1/general-purpose.yaml:

apiVersion: karpenter.sh/v1 kind: NodePool metadata: name: general-purpose annotations: kubernetes.io/description: "General purpose NodePool for generic workloads" spec: template: spec: requirements: - key: kubernetes.io/arch operator: In values: ["amd64"] - key: kubernetes.io/os operator: In values: ["linux"] - key: karpenter.sh/capacity-type operator: In values: ["on-demand"] - key: karpenter.k8s.aws/instance-category operator: In values: ["c", "m", "r"] - key: karpenter.k8s.aws/instance-generation operator: Gt values: ["2"] nodeClassRef: group: karpenter.k8s.aws kind: EC2NodeClass name: default --- apiVersion: karpenter.k8s.aws/v1 kind: EC2NodeClass metadata: name: default spec: role: "KarpenterNodeRole-${CLUSTER_NAME}" # 替换为你的集群名 subnetSelectorTerms: - tags: karpenter.sh/discovery: "${CLUSTER_NAME}" securityGroupSelectorTerms: - tags: karpenter.sh/discovery: "${CLUSTER_NAME}" amiSelectorTerms: - alias: al2023@latest # Amazon Linux 2023

其中requirements支持InNotInExistsDoesNotExistGtLtGteLte等运算符。注意 Kubernetes 原生的node.kubernetes.io/instance-type标签在 Karpenter v1 中已被扩展标签取代——AWS 特定的实例属性使用karpenter.k8s.aws/*前缀(如karpenter.k8s.aws/instance-categorykarpenter.k8s.aws/instance-familykarpenter.k8s.aws/instance-cpukarpenter.k8s.aws/instance-memorykarpenter.sh/capacity-type),这些标签常量在源码 pkg/apis/v1/labels.go 中集中定义并通过karpv1.WellKnownLabels注册为 Karpenter 认可的“已知标签”,Pod 与 NodePool 只能用这一受控集合进行约束匹配。

NodePool 还定义行为配置(详见 NodePools 文档):

  • spec.template.spec.expireAfter:节点最大存活时间(如720h,可设Never禁用);
  • spec.template.spec.terminationGracePeriod:节点进入驱逐流程后允许排空的最长时间;
  • spec.disruption.consolidationPolicyWhenEmptyOrUnderutilized/Balanced/WhenEmpty)、consolidateAfterbudgets(按百分比/时间窗控制缩容速度);
  • spec.weight:多 NodePool 竞争时的优先级权重。

多 NodePool 场景:同一集群可配置多个 NodePool。典型用途包括:为不同团队隔离计费、为特定团队禁止 GPU 节点、使用不同干扰策略,或不同镜像族(例如一个团队用 Bottlerocket,另一个用 AL2023/EKS 优化 AMI)。虽然多数场景单 NodePool 即可覆盖多团队,但多 NodePool 是隔离与差异化治理的标准手段。

节点干扰(Disruption):五种机制

Karpenter 会在节点不再需要时删除节点,具体包括五种机制(完整细节见 Disruption 文档):

  1. Finalizer(终结器):Karpenter 为它创建的每个节点添加 finalizer。当删除请求到来(如 TTL 到期或手动kubectl delete node),Karpenter 会 cordon 节点、排空所有 Pod、终止 EC2 实例并删除节点对象,全程接管清理工作。AWS 侧的终结器常量为 pkg/apis/v1/labels.go 中定义的TerminationFinalizerkarpenter.k8s.aws/termination),其挂载与摘除逻辑可参考 pkg/controllers/nodeclass/controller.go 中对TerminationFinalizer的添加/移除处理。
  2. Expiration(到期):根据 NodePool 的spec.template.spec.expireAfter值,节点存活超过设定秒数后会被标记为过期并干扰替换。常用于出于安全考虑周期性轮换节点。
  3. Consolidation(整合):Karpenter 主动降低成本,识别以下时机:
    • 空节点可以直接移除;
    • 节点上的工作负载能迁移到集群内其他节点,则该节点可移除;
    • 因工作负载变化,节点可被更便宜的实例规格替换。
  4. Drift(漂移):当节点偏离其期望规格(例如 NodePool/EC2NodeClass 的模板字段变更导致节点与新模板不一致)时,Karpenter 会将其标记为漂移并替换。Drift 检测实现 与漂移测试套件 pkg/cloudprovider/suite_test.go 描述了被比较的字段集合。
  5. Interruption(中断事件):Karpenter 监听即将影响节点的中断事件(健康事件、Spot 回收通知等),并提前 cordon、drain、终止节点,以减小对业务的影响。这一能力由 pkg/controllers/interruption 控制器族实现:通过 SQS 消费 Spot 中断、计划变更、再平衡建议等消息(见 messages 目录),在事件真正生效前完成节点替换。

调度模型:分层约束如何工作

Karpenter 在 Kubernetes 调度器标记 Pod 为不可调度后介入:解析调度约束、求解后在云端启动匹配的节点。节点起来后,kube-scheduler 即可正常在其上调度 Pod。

分层约束是使用 Karpenter 的核心概念

  • 若 NodePool 未定义约束、Pod 也未请求特定属性,Karpenter 从云厂商提供的“全量特性空间”中任选——任意实例规格、任意可用区;
  • 应用开发者可通过 Pod spec 进一步收紧管理员在 NodePool 中定义的约束;
  • 只要请求不超出 NodePool 约束范围,Karpenter 会尽力匹配请求,用与 Pod 调度约束相同的一组 well-known labels 做比对;若约束组合无解,Pod 将保持未调度状态。

应用开发者视角

作为部署 Pod 的开发者,你应当知道如何声明 Pod 对计算资源的诉求。Karpenter 会在现有容量无法满足请求时评估并选择计算资源。Pod 可使用的约束包括:

  • nodeAffinity:指定可用区或实例规格;
  • topologySpreadConstraints:使一组 Pod 在多个节点/拓扑域间均衡分布;
  • nodeSelector:只在带特定标签的节点上运行;
  • resource.requests:确保节点有足够的内存等可用资源。

Kubernetes 调度器先尝试用现有节点满足这些约束;若 Pod 不可调度,Karpenter 会创建匹配其需求的计算资源,并在创建节点前分析全部调度约束。

Karpenter 支持的 Kubernetes 调度特性包括:

  • nodeAffinity 与 nodeSelector
  • PodDisruptionBudget(PDB):干扰操作(整合、漂移替换)会尊重 PDB,避免违反 Pod 的可用性承诺;
  • topologySpreadConstraints
  • Pod 间亲和/反亲和(inter-pod affinity and anti-affinity)

在标签层面,来自 Kubernetes well-known labels 体系、且实际在 Karpenter 中实现的包括:

  • kubernetes.io/arch:如kubernetes.io/arch=amd64
  • topology.kubernetes.io/zone:如topology.kubernetes.io/zone=us-east-1c
  • 实例规格相关约束在 v1 中通过 Karpenter 扩展标签表达,例如karpenter.k8s.aws/instance-category(类别)、karpenter.k8s.aws/instance-family(如m5)、karpenter.k8s.aws/instance-cpukarpenter.k8s.aws/instance-memorykarpenter.k8s.aws/instance-gpu-name等,以及 Karpenter 自有标签karpenter.sh/capacity-type(取值spot/on-demand/reserved)。

完整的约束标签清单及其取值语义见 Scheduling 文档;仓库examples/下还配有 多架构示例、Spot 容量示例、最大节点存活时间示例、Windows 节点示例 等可直接参考的清单文件。

Cloud Provider 抽象:AWS 是第一个提供商

Karpenter 向“关联的云厂商”发起节点供给请求。第一个受支持的云厂商是 AWS,但架构上 Karpenter 被设计为可对接其他云厂商——把 Kubernetes 通用配置与 AWS 特定配置分离(前者在 NodePool,后者在 EC2NodeClass,见 EC2NodeClass 文档)是这条演进路径的关键:云无关字段留在核心 API,云厂商字段下沉到 provider 特定的 NodeClass 资源中。

使用 Kubernetes well-known labels 的同时,NodePool 可以设置一些云厂商特定的值。例如,要包含某个实例规格,可以用标签node.kubernetes.io/instance-type的思想,但把取值设为 AWS 实例规格(如m5.largem5.2xlarge);在 v1 中推荐直接使用karpenter.k8s.aws/instance-family/karpenter.k8s.aws/instance-size等组合标签来表达同类约束。

与 Kubernetes Cluster Autoscaler 的对比

与 Karpenter 类似,Kubernetes Cluster Autoscaler(K8s 项目组件,各主要云厂商均有实现)也在现有容量无法满足 Pod 请求时添加节点。Karpenter 对节点供给方式做了重新审视,文档中列出的改进点为:

  • 为云的全部灵活性而设计:Karpenter 能够高效覆盖 AWS 全量实例规格空间。Cluster Autoscaler 最初并非为处理数百种实例规格、可用区与购买方式的组合而构建;
  • 更快的节点供给:Karpenter 直接管理每个实例,不依赖 node groups 这类额外编排机制。容量不可用时它可以毫秒级重试而非分钟级,并能在不创建数百个 node group 的前提下利用多样化的实例规格、可用区与购买选项。

从仓库结构也能印证这一点:供给路径通过 pkg/batcher(CreateFleet 批处理)、pkg/providers/instancetype/offering(按 spot/on-demand/reserved 解析 offering)、pkg/providers/launchtemplate/launchtemplate.go(Launch Template 生成)等模块直接编排 EC2 API 调用,全程没有 node group 抽象层。

关键概念对照速查

概念说明参考位置
NodePool定义节点约束与干扰行为的 CRDNodePools 文档
EC2NodeClassAWS 特定的节点模板(role、subnet、SG、AMI)NodeClasses 文档
NodeClaimKarpenter 内部对每个节点的抽象NodeClaims 文档
DisruptionFinalizer / Expiration / Consolidation / Drift / InterruptionDisruption 文档
约束标签Karpenter 支持的 well-known 标签全集Scheduling 文档、pkg/apis/v1/labels.go
Helm ChartIRSA ServiceAccount、双副本、PDB、跨区打散charts/karpenter
示例清单general-purpose、spot、多架构、Windows 等examples/v1

适用前提与限制:本文基于当前仓库的 preview 版概念文档(karpenter.sh/v1karpenter.k8s.aws/v1API),标签与字段名以本仓库 API 定义为准;Kubelet 相关配置已从 NodePool 移至 EC2NodeClass spec,配置时请以仓库内 NodePools 文档 的最新字段说明为准。

【免费下载链接】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),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/16 16:20:28

Django实现视频点播:MTV架构、ORM模型与部署实战

简介:基于Django框架的视频点播网站完整源码包,主要面向计算机、数学、电子信息等专业的学生,适合用作课程设计、期末大作业或毕业设计参考资料。项目实现了视频播放、收藏、后台管理等核心功能,页面与后端逻辑均打包在内&#xf…

作者头像 李华
网站建设 2026/9/16 16:18:33

基于多智能体大语言模型的中文金融分析框架解析

1. 项目背景与核心价值这个名为TradingAgents-CN的开源项目,本质上是一个基于多智能体大语言模型的中文金融分析框架。它最吸引人的地方在于,将前沿的AI技术与传统金融分析进行了深度融合,打造了一个专门面向中文市场的股票研究平台。从技术架…

作者头像 李华