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

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-awsKarpenter 是面向 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 在两者交集内选择最优实例。集群管理员视角安装 KarpenterHelm Chart 与 IRSA 权限Karpenter 被设计为运行在你自己的 Kubernetes 集群节点上而非独立集群外部。由于添加/删除节点、调度 Pod 的请求都通过 Kubernetes 发起集群需要AWS IAM Roles for Service AccountsIRSA来让 Karpenter 以特权身份访问 AWS API——例如查询 EC2 实例规格、创建 EC2 实例等。安装流程详见 Getting Started 文档创建 Kubernetes ServiceAccount 与 AWS IAM Role通过 IRSA 关联授权 Karpenter 启动实例所需的最小权限集使用 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控制器默认双副本高可用podDisruptionBudgetname: karpenter, maxUnavailable: 1保证滚动升级期间至少一个控制器在线priorityClassName: system-cluster-critical与tolerations: 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 文档一致只处理不可调度 PodKarpenter 只尝试调度status condition UnschedulableTrue的 Pod这是 kube-scheduler 在无法将 Pod 放置到现有容量上时设置的标记无 NodePool 则完全静止如果没有配置至少一个 NodePoolKarpenter 不做任何事情污点过滤如果 NodePool 中有 Pod 未容忍的 taintKarpenter 不会用该 NodePool 为该 Pod 供给节点startup taint 则被视为临时性污点Pod 无需容忍推荐互斥建议创建互斥的 NodePool使一个 Pod 最多匹配一个 NodePool若匹配多个Karpenter 会选择spec.weight最高的那个。一个完整的、可直接复制运行的 NodePool EC2NodeClass 示例见 examples/v1/general-purpose.yamlapiVersion: 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: al2023latest # Amazon Linux 2023其中requirements支持In、NotIn、Exists、DoesNotExist、Gt、Lt、Gte、Lte等运算符。注意 Kubernetes 原生的node.kubernetes.io/instance-type标签在 Karpenter v1 中已被扩展标签取代——AWS 特定的实例属性使用karpenter.k8s.aws/*前缀如karpenter.k8s.aws/instance-category、karpenter.k8s.aws/instance-family、karpenter.k8s.aws/instance-cpu、karpenter.k8s.aws/instance-memory、karpenter.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、consolidateAfter与budgets按百分比/时间窗控制缩容速度spec.weight多 NodePool 竞争时的优先级权重。多 NodePool 场景同一集群可配置多个 NodePool。典型用途包括为不同团队隔离计费、为特定团队禁止 GPU 节点、使用不同干扰策略或不同镜像族例如一个团队用 Bottlerocket另一个用 AL2023/EKS 优化 AMI。虽然多数场景单 NodePool 即可覆盖多团队但多 NodePool 是隔离与差异化治理的标准手段。节点干扰Disruption五种机制Karpenter 会在节点不再需要时删除节点具体包括五种机制完整细节见 Disruption 文档Finalizer终结器Karpenter 为它创建的每个节点添加 finalizer。当删除请求到来如 TTL 到期或手动kubectl delete nodeKarpenter 会 cordon 节点、排空所有 Pod、终止 EC2 实例并删除节点对象全程接管清理工作。AWS 侧的终结器常量为 pkg/apis/v1/labels.go 中定义的TerminationFinalizerkarpenter.k8s.aws/termination其挂载与摘除逻辑可参考 pkg/controllers/nodeclass/controller.go 中对TerminationFinalizer的添加/移除处理。Expiration到期根据 NodePool 的spec.template.spec.expireAfter值节点存活超过设定秒数后会被标记为过期并干扰替换。常用于出于安全考虑周期性轮换节点。Consolidation整合Karpenter 主动降低成本识别以下时机空节点可以直接移除节点上的工作负载能迁移到集群内其他节点则该节点可移除因工作负载变化节点可被更便宜的实例规格替换。Drift漂移当节点偏离其期望规格例如 NodePool/EC2NodeClass 的模板字段变更导致节点与新模板不一致时Karpenter 会将其标记为漂移并替换。Drift 检测实现 与漂移测试套件 pkg/cloudprovider/suite_test.go 描述了被比较的字段集合。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 与 nodeSelectorPodDisruptionBudgetPDB干扰操作整合、漂移替换会尊重 PDB避免违反 Pod 的可用性承诺topologySpreadConstraintsPod 间亲和/反亲和inter-pod affinity and anti-affinity。在标签层面来自 Kubernetes well-known labels 体系、且实际在 Karpenter 中实现的包括kubernetes.io/arch如kubernetes.io/archamd64topology.kubernetes.io/zone如topology.kubernetes.io/zoneus-east-1c实例规格相关约束在 v1 中通过 Karpenter 扩展标签表达例如karpenter.k8s.aws/instance-category类别、karpenter.k8s.aws/instance-family如m5、karpenter.k8s.aws/instance-cpu、karpenter.k8s.aws/instance-memory、karpenter.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.large、m5.2xlarge在 v1 中推荐直接使用karpenter.k8s.aws/instance-family/karpenter.k8s.aws/instance-size等组合标签来表达同类约束。与 Kubernetes Cluster Autoscaler 的对比与 Karpenter 类似Kubernetes Cluster AutoscalerK8s 项目组件各主要云厂商均有实现也在现有容量无法满足 Pod 请求时添加节点。Karpenter 对节点供给方式做了重新审视文档中列出的改进点为为云的全部灵活性而设计Karpenter 能够高效覆盖 AWS 全量实例规格空间。Cluster Autoscaler 最初并非为处理数百种实例规格、可用区与购买方式的组合而构建更快的节点供给Karpenter 直接管理每个实例不依赖 node groups 这类额外编排机制。容量不可用时它可以毫秒级重试而非分钟级并能在不创建数百个 node group 的前提下利用多样化的实例规格、可用区与购买选项。从仓库结构也能印证这一点供给路径通过 pkg/batcherCreateFleet 批处理、pkg/providers/instancetype/offering按 spot/on-demand/reserved 解析 offering、pkg/providers/launchtemplate/launchtemplate.goLaunch Template 生成等模块直接编排 EC2 API 调用全程没有 node group 抽象层。关键概念对照速查概念说明参考位置NodePool定义节点约束与干扰行为的 CRDNodePools 文档EC2NodeClassAWS 特定的节点模板role、subnet、SG、AMINodeClasses 文档NodeClaimKarpenter 内部对每个节点的抽象NodeClaims 文档DisruptionFinalizer / Expiration / Consolidation / Drift / InterruptionDisruption 文档约束标签Karpenter 支持的 well-known 标签全集Scheduling 文档、pkg/apis/v1/labels.goHelm ChartIRSA ServiceAccount、双副本、PDB、跨区打散charts/karpenter示例清单general-purpose、spot、多架构、Windows 等examples/v1适用前提与限制本文基于当前仓库的 preview 版概念文档karpenter.sh/v1与karpenter.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),仅供参考