十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Karpenter NodeClaim 深度解析:集群节点生命周期管理的核心抽象

Karpenter NodeClaim 深度解析:集群节点生命周期管理的核心抽象 Karpenter NodeClaim 深度解析集群节点生命周期管理的核心抽象【免费下载链接】karpenter-provider-awsKarpenter is a Kubernetes Node Autoscaler built for flexibility, performance, and simplicity.项目地址: https://gitcode.com/GitHub_Trending/ka/karpenter-provider-aws导读NodeClaim 是 Karpenterkarpenter-provider-aws中连接 Kubernetes Node 与云提供商实例的核心资源对象Karpenter 通过它感知并驱动预启动pre-spin→ 实例启动launch→ 节点注册registration→ 资源就绪initialization的完整生命周期。本文以官方概念文档 nodeclaims.md 为主体结合本仓库中的 CRD 定义pkg/apis/crds/karpenter.sh_nodeclaims.yaml与云提供商实现pkg/cloudprovider/cloudprovider.go系统讲解 NodeClaim 的调度链路、字段语义、状态机与排障方法帮助你掌握如何通过kubectl观测和排查 Karpenter 集群中的节点供给问题。NodeClaim 是什么Karpenter 使用 NodeClaim 来管理与底层云提供商之间的 Kubernetes Node 生命周期。Karpenter 会根据集群中 Pod 的需求创建和删除 NodeClaim它评估待调度 Pod 的需求找到一组兼容的 NodePool 与 NodeClass 组合然后创建一个同时满足双方需求的 NodeClaim。虽然 NodeClaim 是由 Karpenter 管理的不可变immutable资源但你可以通过监控 NodeClaim 来跟踪节点的状态。除了跟踪节点生命周期之外NodeClaim 还充当容量请求requests for capacity。Karpenter 会响应供给provisioning与干扰disruption需求创建 NodeClaim即预启动。每当 Karpenter 创建 NodeClaim 时它会要求云提供商创建实例launch调用云 API 启动底层实例注册并关联registration将创建的 Node 注册进集群并与 NodeClaim 建立关联等待就绪initialization等待 Node 及其资源变为可用状态。NodeClaim 是不可变、集群作用域cluster-scoped的资源与一个云提供商实例和一个 Kubernetes Node 一一对应。每个由 Karpenter 创建的 NodeClaim 归属于且仅归属于一个 NodePool并引用一个 NodeClass。你也可以手动创建 NodeClaim以在标准供给工作流之外请求容量。NodeClaim 与 Node 的观测方式想了解 Karpenter 托管的节点可以分别查看 NodeClaim 或其关联的 Node查看 NodeClaim节点创建过程中一旦出问题NodeClaim 能直接反映失败环节。kubectl get nodeclaims会列出集群中所有 NodeClaim 及其关联节点kubectl describe nodeclaim nodeclaim展示单个 NodeClaim 的详细状态。例如当 Node 处于 NotReady 时你可能看到 NodeClaim 的状态显示其在 launch、register 或 initialize 阶段失败同时 Karpenter controller 也会输出相应的日志。查看 Node使用kubectl get node和kubectl describe node nodename查看节点上的实际资源、标签及其他属性。从 CRD 定义pkg/apis/crds/karpenter.sh_nodeclaims.yaml可以看到nodeclaims.karpenter.sh还配置了丰富的additionalPrinterColumns让kubectl get nodeclaims默认输出 Type实例类型、Capacity容量类型、Zone、Node、Ready、Age 等列并可在高优先级列中展示 ImageID、IDproviderID、NodePool、NodeClass 与 Drifted 状态方便快速巡检。NodeClaim 在节点创建中的角色NodeClaim 在 Karpenter 供给容量的工作流以及节点干扰disruption流程中扮演关键角色。下图展示了 Karpenter 驱动节点创建时NodeClaim 与其他组件的交互关系提示将KARPENTER_NAMESPACE环境变量配置为 Karpenter 的安装命名空间默认为kube-system跟随 Karpenter 日志观察下面的流程export KARPENTER_NAMESPACEkube-system kubectl logs -f -n ${KARPENTER_NAMESPACE} \ -l app.kubernetes.io/namekarpenter另开一个终端启动一些需要 Karpenter 创建节点的 Pod例如按 Scale up deployment 中的描述启动一批 inflate Pod。节点创建六步流程如图中所示Karpenter 在创建节点时与 NodeClaim 及相关组件发生如下交互1. 监听 Pod监控 NodePool 与 NodeClass检查 Pod 的调度约束和资源请求并将需求与现有 NodePool、NodeClass 的要求交叉比对例如 zone、arch、os。示例日志{ level: INFO, time: 2024-06-22T02:24:16.114Z, message: found provisionable pod(s), commit: 490ef94, Pods: default/inflate-66fb68585c-xvs86, default/inflate-66fb68585c-hpcdz, default/inflate-66fb68585c-8xztf,01234567adb205c7e default/inflate-66fb68585c-t29d8, default/inflate-66fb68585c-nxflz, duration: 100.761702ms }2. 计算 NodeClaim 的形态与大小为第 1 步中的 Pod 集合计算要在集群中创建的 NodeClaim或一批 NodeClaim的形状和大小即实例类型与资源规格的右尺寸化right-size。示例日志{ level: INFO, time: 2024-06-22T02:24:16.114Z, message: computed new nodeclaim(s) to fit pod(s), controller: provisioner, nodeclaims: 1, pods: 5 }3. 在集群中创建 NodeClaim 对象示例日志{ level: INFO, time: 2024-06-22T02:24:16.128Z, message: created nodeclaim, controller: provisioner, NodePool: { name:default }, NodeClaim: { name:default-sfpsl }, requests: { cpu:5150m, pods:8 }, instance-types: c3.2xlarge, c4.2xlarge, c4.4xlarge, c5.2xlarge, c5.4xlarge and 55 other(s) }注意instance-types字段Karpenter 在创建 NodeClaim 时并不会立刻锁定唯一实例类型而是保留一个候选实例类型集合55 other(s)把最终选择交给后续的 launch 阶段以提高容量可用性。4. 找到新 NodeClaim 并翻译为云 API 调用Karpenter 发现新的 NodeClaim 后将其翻译为创建云提供商实例的 API 调用并记录 API 响应。在 AWS 实现中这一步对应 pkg/cloudprovider/cloudprovider.go 中CloudProvider.Create()的实例启动逻辑最终经由 pkg/providers/instance/instance.go 的 Launch 流程内部使用 EC2 CreateFleet 等批量 API完成。关键错误处理如果 API 响应是不可恢复的错误例如容量不足 Insufficient Capacity ErrorKarpenter 会删除该 NodeClaim将该实例类型临时标记为不可用并在必要时创建另一个 NodeClaim。从源码看CloudProvider.Create()中解析不到 NodeClass 时同样会包装为cloudprovider.NewInsufficientCapacityError返回见 pkg/cloudprovider/cloudprovider.go这保证了供给循环可以把失败归因到容量问题上并继续尝试其他实例类型。示例日志{ level: INFO, time: 2024-06-22T02:24:19.028Z, message: launched nodeclaim, controller: nodeclaim.lifecycle, NodeClaim: { name: default-sfpsl }, provider-id: aws:///us-west-2b/i-01234567adb205c7e, instance-type: c3.2xlarge, zone: us-west-2b, capacity-type: spot, allocatable: { cpu: 7910m, ephemeral-storage: 17Gi, memory: 13215Mi, pods: 58 } }5. 等待实例注册为节点并同步元数据Karpenter 监听实例是否已作为 Node 注册进集群并将 Node 的 labels、annotations、taints、owner refs 和 finalizer 更新为 NodePool 与 NodeClaim 中定义的值。完成后Karpenter 会移除 Node 上的karpenter.sh/unregistered污点。如果该步骤在15 分钟内未成功Karpenter 会从集群中删除 NodeClaim 并删除底层实例必要时创建另一个 NodeClaim。仓库中的注册钩子实现pkg/cloudprovider/registrationhooks/placementgrouphook.go会利用karpenter.sh/unregistered污点约束注册前节点的调度行为例如在 placement group 场景中控制节点注册顺序。示例日志{ level: INFO, time: 2024-06-22T02:26:19.028Z, message: registered nodeclaim, controller: nodeclaim.lifecycle, NodeClaim: { name: default-sfpsl }, provider-id: aws:///us-west-2b/i-01234567adb205c7e, Node: { name: ip-xxx-xxx-xx-xxx.us-west-2.compute.internal } }6. 持续监听节点直至就绪Karpenter 持续监听节点等待节点变为 Ready、所有 startup taints 被移除、且所有请求的资源都注册到节点上。示例日志{ level: INFO, time: 2024-06-24T02:24:52.642Z, message: initialized nodeclaim, controller: nodeclaim.lifecycle, NodeClaim: { name: default-sfpsl }, provider-id: aws:///us-west-2b/i-01234567adb205c7e, Node: { name: ip-xxx-xxx-xx-xxx.us-west-2.compute.internal }, allocatable: { cpu: 7910m, ephemeral-storage: 18242267924, hugepages-2Mi: 0, memory: 14320468Ki, pods: 58 } }至此NodeClaim 的Launched → Registered → Initialized → Ready条件依次置为 True节点正式进入可调度状态。NodeClaim 实例从 describe 读懂节点状态NodeClaim 一经创建即不可修改。要查看其内容先获取名称再 describekubectl get nodeclaim NAME TYPE ZONE NODE READY AGE default-m6pzn c7i-flex.2xlarge us-west-1a ip-xxx-xxx-xx-xxx.us-west-1.compute.internal True 7m50s kubectl describe nodeclaim default-m6pzn从describe输出的底部即 Status 区域开始看NodeClaim 的关键信息包括Node Nameip-xxx-xxx-xx-xxx.us-west-1.compute.internal与Provider IDaws:///us-west-1a/i-xxxxxxxxxxxxxxxxx标识承担该 NodeClaim 的实例Image ID如ami-0ccbbed159cce4e37表示节点上运行的操作系统镜像Status展示节点可用资源CPU、内存等以及关联的条件conditions。条件反映节点的运行阶段——是否已 launched、registered、initialized。当 Pod 无法调度到该节点时这一步对定位原因尤为关键Spec包含 Karpenter 启动和管理实例所需的元数据调度需求、资源需求、NodeClass 引用、taints以及不可变的干扰字段expireAfter与terminationGracePeriod其他信息包括需要同步到 Node 的 annotations 和 labels、创建元数据、终止 finalizer 与 owner reference。下面是一个完整的kubectl describe nodeclaim输出示例Name: default-x9wxq Namespace: Labels: karpenter.k8s.aws/instance-categoryc karpenter.k8s.aws/instance-cpu8 karpenter.k8s.aws/instance-cpu-manufactureramd karpenter.k8s.aws/instance-ebs-bandwidth3170 karpenter.k8s.aws/instance-encryption-in-transit-supportedtrue karpenter.k8s.aws/instance-familyc5a karpenter.k8s.aws/instance-generation5 karpenter.k8s.aws/instance-hypervisornitro karpenter.k8s.aws/instance-memory16384 karpenter.k8s.aws/instance-network-bandwidth2500 karpenter.k8s.aws/instance-size2xlarge karpenter.sh/capacity-typespot karpenter.sh/nodepooldefault kubernetes.io/archamd64 kubernetes.io/oslinux node.kubernetes.io/instance-typec5a.2xlarge topology.k8s.aws/zone-idusw2-az3 topology.kubernetes.io/regionus-west-2 topology.kubernetes.io/zoneus-west-2c Annotations: compatibility.karpenter.k8s.aws/cluster-name-tagged: true compatibility.karpenter.k8s.aws/kubelet-drift-hash: 15379597991425564585 karpenter.k8s.aws/ec2nodeclass-hash: 5763643673275251833 karpenter.k8s.aws/ec2nodeclass-hash-version: v3 karpenter.k8s.aws/tagged: true karpenter.sh/nodepool-hash: 377058807571762610 karpenter.sh/nodepool-hash-version: v3 API Version: karpenter.sh/v1 Kind: NodeClaim Metadata: Creation Timestamp: 2024-08-07T05:37:30Z Finalizers: karpenter.sh/termination Generate Name: default- Generation: 1 Owner References: API Version: karpenter.sh/v1 Block Owner Deletion: true Kind: NodePool Name: default UID: 6b9c6781-ac05-4a4c-ad6a-7551a07b2ce7 Resource Version: 19600526 UID: 98a2ba32-232d-45c4-b7c0-b183cfb13d93 Spec: Expire After: 720h0m0s Node Class Ref: Group: Kind: EC2NodeClass Name: default 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: spot Key: karpenter.k8s.aws/instance-category Operator: In Values: c m r Key: karpenter.k8s.aws/instance-generation Operator: Gt Values: 2 Key: karpenter.sh/nodepool Operator: In Values: default Key: node.kubernetes.io/instance-type Operator: In Values: c3.xlarge c4.xlarge c5.2xlarge c5.xlarge c5a.xlarge c5ad.2xlarge c5ad.xlarge c5d.2xlarge Resources: Requests: Cpu: 3150m Pods: 6 Startup Taints: Effect: NoSchedule Key: app.dev/example-startup Taints: Effect: NoSchedule Key: app.dev/example Termination Grace Period: 1h0m0s Status: Allocatable: Cpu: 7910m Ephemeral - Storage: 17Gi Memory: 14162Mi Pods: 58 vpc.amazonaws.com/pod-eni: 38 Capacity: Cpu: 8 Ephemeral - Storage: 20Gi Memory: 15155Mi Pods: 58 vpc.amazonaws.com/pod-eni: 38 Conditions: Last Transition Time: 2024-08-07T05:38:08Z Message: Reason: Consolidatable Status: True Type: Consolidatable Last Transition Time: 2024-08-07T05:38:07Z Message: Reason: Initialized Status: True Type: Initialized Last Transition Time: 2024-08-07T05:37:33Z Message: Reason: Launched Status: True Type: Launched Last Transition Time: 2024-08-07T05:38:07Z Message: Reason: Ready Status: True Type: Ready Last Transition Time: 2024-08-07T05:37:55Z Message: Reason: Registered Status: True Type: Registered Image ID: ami-08946d4d49fc3f27b Node Name: ip-xxx-xxx-xxx-xxx.us-west-2.compute.internal Provider ID: aws:///us-west-2c/i-01234567890123 Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Launched 70s karpenter Status condition transitioned, Type: Launched, Status: Unknown - True, Reason: Launched Normal DisruptionBlocked 70s karpenter Cannot disrupt NodeClaim: state node doesnt contain both a node and a nodeclaim Normal Registered 48s karpenter Status condition transitioned, Type: Registered, Status: Unknown - True, Reason: Registered Normal Initialized 36s karpenter Status condition transitioned, Type: Initialized, Status: Unknown - True, Reason: Initialized Normal Ready 36s karpenter Status condition transitioned, Type: Ready, Status: Unknown - True, Reason: Ready这个示例清楚地展示了Events区的价值Launched → Registered → Initialized → Ready的事件顺序与前述六步流程一一对应而DisruptionBlocked事件提示干扰控制器因为节点与 NodeClaim 尚未完全关联而暂时跳过该 NodeClaim 的整合consolidation判断。NodeClaim API 参考以下是带注释的 NodeClaim 资源完整示例字段注释与 CRD 校验规则可在 pkg/apis/crds/karpenter.sh_nodeclaims.yaml 中核对apiVersion: karpenter.sh/v1 kind: NodeClaim metadata: # NodeClaim names are auto-generated by Karpenter using the NodePool name as a prefix name: default-sfpsl # Labels are propagated from the NodePools template and include well-known labels # resolved during scheduling (instance type, capacity type, zone, etc.) labels: billing-team: my-team karpenter.sh/capacity-type: spot karpenter.sh/nodepool: default node.kubernetes.io/instance-type: c5.2xlarge topology.kubernetes.io/zone: us-west-2b kubernetes.io/arch: amd64 kubernetes.io/os: linux # Annotations are propagated from the NodePools template annotations: example.com/owner: my-team # The NodeClaim is owned by the NodePool that created it ownerReferences: - apiVersion: karpenter.sh/v1 kind: NodePool name: default blockOwnerDeletion: true # Karpenter adds a termination finalizer to ensure proper cleanup finalizers: - karpenter.sh/termination spec: # References the Cloud Providers NodeClass resource nodeClassRef: group: karpenter.k8s.aws kind: EC2NodeClass name: default # Taints applied to the node, propagated from the NodePool template taints: - key: example.com/special-taint effect: NoSchedule # Startup taints applied to the node on creation, expected to be removed by an external system startupTaints: - key: example.com/another-taint effect: NoSchedule # The amount of time a Node can live on the cluster before being removed # Inherited from the NodePools spec.template.spec.expireAfter expireAfter: 720h # The maximum duration the controller will wait before forcefully deleting pods on the node # Inherited from the NodePools spec.template.spec.terminationGracePeriod terminationGracePeriod: 48h # Requirements resolved during scheduling, combining NodePool requirements with pod constraints # These are the final, resolved requirements that were used to launch the instance 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: [spot] - key: karpenter.k8s.aws/instance-category operator: In values: [c, m, r] - key: karpenter.k8s.aws/instance-generation operator: Gte values: [3] - key: node.kubernetes.io/instance-type operator: In values: [c3.2xlarge, c4.2xlarge, c5.2xlarge, c5.4xlarge, m5.2xlarge] - key: topology.kubernetes.io/zone operator: In values: [us-west-2a, us-west-2b] # Resource requests represent the minimum resources needed to schedule the pods # that triggered this NodeClaim resources: requests: cpu: 5150m pods: 8 status: # The name of the Kubernetes Node object linked to this NodeClaim nodeName: ip-xxx-xxx-xx-xxx.us-west-2.compute.internal # The cloud provider identifier for the instance providerID: aws:///us-west-2b/i-01234567adb205c7e # The image (AMI) running on the instance imageID: ami-0ccbbed159cce4e37 # Full capacity of the node capacity: cpu: 8 memory: 15155Mi ephemeral-storage: 20Gi pods: 58 # Allocatable resources available for pod scheduling allocatable: cpu: 7910m memory: 14162Mi ephemeral-storage: 17Gi pods: 58 # Conditions track the lifecycle state of the NodeClaim conditions: - type: Launched status: True reason: Launched - type: Registered status: True reason: Registered - type: Initialized status: True reason: Initialized - type: Ready status: True reason: Ready - type: Consolidatable status: True reason: Consolidatablemetadata.labelsNodeClaim 上的标签来自两个来源NodePool 的spec.template.metadata.labels中定义的标签以及调度期间解析出的 well-known 标签如node.kubernetes.io/instance-type、topology.kubernetes.io/zone、karpenter.sh/capacity-type、karpenter.sh/nodepool。这些标签会同步到对应的 Kubernetes Node 上。注意NodePool 与 NodeClaim 上的 requirements 总数目前限制为100CRD 中maxItems: 100见 pkg/apis/crds/karpenter.sh_nodeclaims.yaml。NodePool 的spec.template.metadata.labels会作为 requirements 传播到 NodeClaim因此 NodePool 上设置的 requirements 与 labels 合计不能超过 100。metadata.annotationsNodeClaim 的 annotations 从 NodePool 的spec.template.metadata.annotations传播而来。Karpenter 还会添加内部 annotations 用于跟踪 hash 版本和云提供商相关元数据如示例中的karpenter.sh/nodepool-hash-version: v3、karpenter.k8s.aws/ec2nodeclass-hash-version: v3。这些 annotations 同样会同步到 Kubernetes Node。metadata.ownerReferences每个由 Karpenter 创建的 NodeClaim 都有一个指向创建它的 NodePool 的 owner reference且blockOwnerDeletion: true。这意味着删除 NodePool 会级联删除其下所有 NodeClaim。metadata.finalizersKarpenter 会为每个 NodeClaim 添加karpenter.sh/terminationfinalizer。该 finalizer 确保 NodeClaim 被删除时Karpenter 会先正确地对节点执行 cordon、排空 Pod、终止云提供商实例、清理 Node 对象然后才移除 finalizer避免出现节点没了但云实例还在的泄漏。spec.nodeClassRef该字段引用云提供商的 NodeClass 资源它定义了实例的提供商特定配置。详见 EC2NodeClasses。引用包含三个字段且三个字段在 CRD 中均为必填groupNodeClass 的 API group如karpenter.k8s.awskindNodeClass 的 kind如EC2NodeClassnameNodeClass 资源的名称。spec.taints应用于所供给节点上的 taints继承自 NodePool 的spec.template.spec.taints。不容忍这些 taints 的 Pod 不会被调度到该节点。可参考 Kubernetes 官方的 Taints and Tolerations 概念。spec.startupTaintsStartup taints 在节点创建时应用但预期会在初始化完成后由外部系统如某个容忍该 taint 的 DaemonSet移除。它们继承自 NodePool 的spec.template.spec.startupTaints。Pod 不需要容忍 startup taints 才能被纳入供给考虑——Karpenter 假定它们是临时的CRD 注释明确说明 startupTaints are ignored for provisioning purposes。startupTaints 常用于让 DaemonSet 先完成初始化、强制启动顺序。spec.expireAfter节点在集群中可存活的时间超过后 Karpenter 将删除该节点继承自 NodePool 的spec.template.spec.expireAfter。一旦到达过期时间节点开始排空。默认值为720h30 天可设置为Never以禁用过期CRD pattern 为^(([0-9](s|m|h))|Never)$。该特性可用于实现最终一致的节点升级、内存泄漏防护与干扰测试。在 NodePool 上修改expireAfter会导致现有 NodeClaim 发生 drift因为 NodeClaim 是不可变的期望值变化只能通过重建来对齐。spec.terminationGracePeriodKarpenter 在排空节点时等待 Pod 被强制删除前的最长时长继承自 NodePool 的spec.template.spec.terminationGracePeriod。一旦到达该期限Karpenter 将无视 PodDisruptionBudgets 或karpenter.sh/do-not-disrupt注解强制删除 PodCRD 中明确警告该特性优先于 Pod 的terminationGracePeriodSeconds并会绕过被阻塞的 PDB。Karpenter 会主动删除 Pod使其terminationGracePeriodSeconds与节点的terminationGracePeriod对齐如果某个 Pod 在节点超时前无法获得完整的终止宽限期该 Pod 将在T node timeout - pod terminationGracePeriodSeconds时被删除。如果未定义控制器将无限期等待 Pod 排空。在 NodePool 上修改terminationGracePeriod同样会导致现有 NodeClaim 发生 drift。spec.requirementsNodeClaim 的已解析调度需求。它结合了 NodePool 的spec.template.spec.requirements与触发供给的 Pod 的调度约束nodeSelector、nodeAffinity 等。支持的运算符与 NodePool 一致In、NotIn、Exists、DoesNotExist、Gt、Lt、Gte、LteCRD 中枚举定义见 karpenter.sh_nodeclaims.yaml。这些 requirements 表示选择实例类型并启动节点时使用的最终约束包含node.kubernetes.io/instance-type、topology.kubernetes.io/zone、kubernetes.io/arch、karpenter.sh/capacity-type等 well-known 标签。CRD 对 key 做了域名限制karpenter.sh域下仅允许capacity-type与nodepoolkarpenter.k8s.aws域下仅允许一组预定义的实例属性标签其余 key 不允许使用这些保留域名。spec.resources资源请求表示调度触发该 NodeClaim 的 Pod 所需的最小资源Karpenter 据此对实例进行右尺寸化right-sizespec.resources.requests被调度到该 NodeClaim 上的 Pod 的聚合资源请求如cpu、memory、pods。status.nodeName与该 NodeClaim 关联的 Kubernetes Node 对象的名称在实例注册进集群后被填充。status.providerID实例的云提供商标识如aws:///us-west-2b/i-01234567adb205c7e在实例启动后被填充。status.imageID实例上运行的镜像标识如 AMI IDami-0ccbbed159cce4e37。status.capacity节点的预估完整容量包含系统预留的资源涵盖cpu、memory、ephemeral-storage、pods以及扩展资源如vpc.amazonaws.com/pod-eni。status.allocatable节点的预估可分配容量——扣除系统预留后真正可用于 Pod 调度的资源通常小于status.capacity。status.conditionsConditions 跟踪 NodeClaim 的生命周期状态。每个 condition 包含type、statusTrue/False/Unknown、reason、message与lastTransitionTimeCondition Type描述Launched云提供商实例已成功创建Registered实例已作为 Kubernetes Node 加入集群且 Karpenter 已同步 labels、taints 与 owner refsInitialized节点已就绪、startup taints 已移除、所有请求的资源均已注册Ready顶层条件表示 NodeClaim 完全可用。仅当 Launched、Registered、Initialized 全部为 True 时才为 TrueConsolidatable该节点是整合consolidation的候选空置或利用率不足DriftedNodeClaim 已偏离其期望规格例如 NodePool 或 NodeClass 发生变化Drained终止期间节点上的 Pod 已全部排空VolumesDetached终止期间所有卷已从实例上分离InstanceTerminating云提供商实例正在被终止ConsistentStateFoundKarpenter 已确认实例状态与 NodeClaim 一致结合源码理解 NodeClaim 的底层实现CRD 不可变校验在 pkg/apis/crds/karpenter.sh_nodeclaims.yaml 中spec通过 CEL 规则self oldSelf强制不可变从 API 层面保证了 NodeClaim 一旦创建便无法修改。这也是为什么所有期望值变更如修改 NodePool 的expireAfter、terminationGracePeriod都必须通过 drift 检测与重建节点来完成。云提供商 Create 流程pkg/cloudprovider/cloudprovider.go 的CloudProvider.Create()会先通过resolveNodeClassFromNodeClaim解析 NodeClass若 NodeClass 不存在则发布NodeClaimFailedToResolveNodeClass事件并返回 Insufficient Capacity 错误视为无容量可能若 NodeClass 未就绪则返回NodeClassNotReadyError。这与文档中不可恢复错误会删除 NodeClaim 并另建的行为相互印证。注册钩子pkg/cloudprovider/registrationhooks/placementgrouphook.go 展示了注册阶段第 5 步如何利用karpenter.sh/unregistered污点与注册钩子机制控制节点的调度准入例如 placement group 场景下的节点注册顺序。供给/干扰两侧共用NodeClaim 既服务于 Pod 驱动的供给provisioning也服务于整合、过期、drift 等干扰disruption驱动的容量回收。文档第 2 步日志中的controller: provisioner与第 46 步的controller: nodeclaim.lifecycle分别对应这两类控制回路对 NodeClaim 的驱动。总结NodeClaim 是理解 Karpenter 工作方式的核心抽象它以不可变、集群级资源的形式把云实例生命周期与Kubernetes Node 生命周期一一绑定并通过Launched / Registered / Initialized / Ready等条件把复杂的供给流程拆解为可观测、可排障的清晰状态机。无论是日常巡检kubectl get nodeclaims、kubectl describe nodeclaim还是深入源码排查cloudprovider.go、CRD 定义NodeClaim 都是定位节点供给、注册与干扰问题的最佳切入点。【免费下载链接】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),仅供参考
返回列表