容器服务 tke-karpenter 说明

Karpenter 是一款开源的 Kubernetes 工作节点生命周期动态管理组件,能够根据集群中未调度的 Pod 自动扩展节点。当在 Kubernetes 中创建一个 Pod 时,Kubernetes 调度器负责将该 Pod 调度到集群中的一个节点上;如果没有可用的节点可以容纳该 Pod,它将保持在 Pending 状态。该组件可以监控集群中的 Pending Pod,并通过创建新节点来扩展集群资源以满足 Po。

相关产品
容器服务 产品页,含版本规格、价格与购买入口。

一、组件介绍

与传统 Cluster Autoscaler(CA)相比,Karpenter 通过革命性的动态资源感知架构,解决了企业在云原生环境中长期面临的三大核心痛点:

1. 响应延迟高:CA 复杂的节点组匹配、弹性伸缩组接口调用、节点初始化等环节导致扩容过程耗时较长,在突发流量场景易引发服务中断。

2. 调度精度低:因 CA 依赖静态节点组预设,无法动态感知 Pod 的拓扑约束要求,导致扩容随机性大,资源利用率不足,多可用区调度问题频发。

3. 运维负担重:源于 CA 需为不同机型/AZ 单独维护节点池,千级节点集群常需管理多个节点池,需手动维护多规格节点池,机型售罄、模板不一致等问题导致运维成本高。

Karpenter 作为腾讯云 TKE 新一代弹性引擎,通过动态资源感知 + 声明式 API 架构实现突破性创新:

1. 解决速度慢:Karpenter 绕过节点组和弹性伸缩组,通过实时调用腾讯云 API 直接创建定制化节点,大幅简化扩容流程,秒级完成资源供给。

2. 解决精度低:基于动态资源感知引擎,实时分析库存/成本/拓扑数据,自动选择最优机型与可用区,实现跨 AZ 调度偏差显著降低,资源利用率显著提高。

3. 解决运维重:单 NodePool 声明覆盖全量机型/AZ,无需预定义节点组,运维对象从“节点池数量”降维至“资源策略数量”。

二、使用限制

·该组件要求集群的 Kubernetes 版本 ≥ 1.22。

·该组件目前仅支持管理按量计费的原生节点。

·该组件目前不支持 GPU 相关资源。

·若你的集群已经使用了节点池提供的 Cluster Autoscaler (CA) 弹性伸缩能力,你需要关闭 CA 后再使用本组件,否则会存在功能冲突。

注意:TKE 集群节点的 ENI 网卡辅助 IP 为动态分配,并对应节点的 status.allocatable.tke.cloud.tencent.com/eni-ip 值。当 Pod 因为 ENI IP 不足而处于 Pending 状态时,网络组件会动态调整该值,但该过程中存在一定延迟,导致组件在检测到 Pod Pending 时会迅速启动新节点。强烈建议你在新建集群时开启固定 IP 网络模式(在 Terraform 中需配置 is_non_static_ip_mode = false),这样节点的 status.allocatable.tke.cloud.tencent.com/eni-ip 值会固定,可避免不必要的节点弹出。

三、步骤1:卸载 CA 组件

1. 登录 容器服务控制台,在左侧导航栏中选择集群。

2. 在集群列表中,选择目标集群,进入集群详情页。

3. 选择组件管理,单击 cluster-autoscaler 右侧的删除。

4. 在删除资源弹窗中,单击确定。删除组件后,系统自动冻结所有节点池伸缩能力。

四、步骤2:安装 Karpenter

1. 在组件管理中,单击新建。

2. 在新建组件管理中,勾选 Karpenter。

3. 单击完成。

注意:说明:

注意:Karpenter 安装完成后,系统自动解除 CA 关联,确保互斥生效。

五、步骤3:部署 NodePool 资源

自定义资源 NodePool 可以为创建的节点以及在这些节点上运行的 Pod 设置约束,例如:

1. 定义污点以限制可以在扩容节点上运行的 Pod。

2. 定义节点所在的可用区、实例类型、实例规格和计费模式。

3. 定义所管理节点的资源限制。

apiVersion: karpenter.sh/v1kind: NodePoolmetadata: name: test annotations: kubernetes.io/description: "NodePool to restrict the number of cpus provisioned to 10"spec: # Disruption section which describes the ways in which Karpenter can disrupt and replace Nodes # Configuration in this section constrains how aggressive Karpenter can be with performing operations # like rolling Nodes due to them hitting their maximum lifetime (expiry) or scaling down nodes to reduce cluster cost disruption: consolidationPolicy: WhenEmptyOrUnderutilized consolidateAfter: 5m budgets: – nodes: 10% template: metadata: annotations: # node.tke.cloud.tencent.com/automation-service 节点自动化服务(TAT登录能力) # node.tke.cloud.tencent.com/security-agent 节点安全加固 # node.tke.cloud.tencent.com/monitor-service 云监控 beta.karpenter.k8s.tke.machine.meta/annotations: node.tke.cloud.tencent.com/automation-service=true,node.tke.cloud.tencent.com/security-agent=true,node.tke.cloud.tencent.com/monitor-service=true # node.tke.cloud.tencent.com/image-label 指定节点镜像,ts4-public对应tencentos server 4 beta.karpenter.k8s.tke.machine.spec/annotations: node.tke.cloud.tencent.com/image-label=ts4-public # 自定义 kubelet 参数功能,xxx 为 kubelet 参数名,yyy 为设定的值 # beta.karpenter.k8s.tke.kubelet.arg/xxx: "yyy" # 自定义内核参数功能,xxx 为内核参数名,yyy 为设定的值 # beta.karpenter.k8s.tke.kernel.arg/xxx: "yyy" spec: # Requirements that constrain the parameters of provisioned nodes. # These requirements are combined with pod.spec.topologySpreadConstraints, pod.spec.affinity.nodeAffinity, pod.spec.affinity.podAffinity, and pod.spec.nodeSelector rules. # Operators { In, NotIn, Exists, DoesNotExist, Gt, and Lt } are supported. # https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#operators requirements: – key: kubernetes.io/arch operator: In values: ["amd64"] – key: kubernetes.io/os operator: In values: ["linux"] – key: karpenter.k8s.tke/instance-family operator: In values: ["S5","SA2"] – key: karpenter.sh/capacity-type operator: In values: ["on-demand"] # – key: node.kubernetes.io/instance-type # operator: In # values: ["S5.MEDIUM2", "S5.MEDIUM4"] – key: "karpenter.k8s.tke/instance-cpu" operator: Gt values: ["1"] # – key: "karpenter.k8s.tke/instance-memory-gb" # operator: Gt # values: ["3"] # References the Cloud Provider's NodeClass resource nodeClassRef: group: karpenter.k8s.tke kind: TKEMachineNodeClass name: default # Resource limits constrain the total size of the pool. # Limits prevent Karpenter from creating new instances once the limit is exceeded. limits: cpu: 10

说明:

1. 常用标签选择器。

Selector Description
topology.kubernetes.io/zone 实例所在可用区,如 "900001"
kubernetes.io/arch 实例架构,支持 "amd64" 和 "arm64"
kubernetes.io/os 操作系统,目前仅支持 "linux"
karpenter.k8s.tke/instance-family 机型实例族,如 "S5","SA2"
karpenter.sh/capacity-type 实例计费模式,如 "on-demand"
node.kubernetes.io/instance-type 实例规格,如 "S5.MEDIUM2"
karpenter.k8s.tke/instance-cpu 实例的 CPU 数量,如 4
karpenter.k8s.tke/instance-memory-gb 实例的 Memory 大小,如 8

2. 如何设置 Topology Label?

tke-karpenter 通过 ID 方式设置 Topology Label,如 topology.kubernetes.io/zone: "900001",同时使用 topology.com.tencent.cloud.csi.cbs/zone 的标签值(如 topology.com.tencent.cloud.csi.cbs/zone: ap-singapore-1)和实际可用区描述做对应。你可以使用命令 describe tmnc Namexxx 查看你子网的 zone 和 zone ID。

3. 禁用 Drift 能力。

我们认为这是一个危险的功能,因此 tke-karpenter 尚未实现 drift 能力。如果你修改了 TKEMachineNodeClass,则不会替换现有的旧节点(nodeclaim)。你的修改只会影响新节点的创建;如果你修改了 nodepool,并且现有 nodeclaim 的标签与 nodepool 要求不兼容,则将替换旧节点。例如,旧节点声明的标签为:karpenter.k8s.tke/instance-cpu: 2。但 nodepool 的要求已修改为:

template: spec: requirements: – key: "karpenter.k8s.tke/instance-cpu" operator: Gt values: ["2"]

由于 karpenter.k8s.tke/instance-cpu: 2 不是 Gt 2,因此 nodeclaim 将被替换。如果你想忽略 Drifted 中断,你应该在节点池中添加以下中断设置:

disruption: consolidationPolicy: WhenEmptyOrUnderutilized consolidateAfter: 5m budgets: – nodes: "0" reasons: [Drifted] – nodes: 10%

你可参考 社区介绍 获取更多操作说明。

4. 建议 expireAfter 设置为 Never。

expireAfter: 720h | Never

spec.template.spec.expireAfter 字段定义了节点在被移除之前可以在集群中存活的时间,减少长时间运行的节点会产生的如文件碎片或系统进程的内存泄漏等问题。由于该参数会导致节点定期销毁重建,为避免重建过程中对业务产生影响,你可以选择设置字符串值 “Never” 来完全禁用过期。

六、步骤4:部署 TKEMachineNodeClass 资源

NodeClass 支持配置 TKE 节点的相关参数,如子网、系统盘、安全组、节点登录方式 SSH 密钥等。每个 NodePool 必须通过 spec.template.spec.nodeClassRef 引用 TKEMachineNodeClass,多个 NodePool 可能指向同一个 TKEMachineNodeClass。

apiVersion: karpenter.k8s.tke/v1beta1kind: TKEMachineNodeClassmetadata: name: default annotations: kubernetes.io/description: "General purpose TKEMachineNodeClass" # 开启系统盘加密 # beta.karpenter.k8s.tke.systemdisk/encrypt: "ENCRYPT" # 开启数据盘加密,下面的例子为配置的第一块盘和第二块盘进行加密 # beta.karpenter.k8s.tke.datadisks/encrypt: "0=ENCRYPT,1=ENCRYPT"spec: ## using kubectl explain tmnc.spec.internetAccessible to check how to use internetAccessible filed. # internetAccessible: # chargeType: TrafficPostpaidByHour # maxBandwidthOut: 2 ## using kubectl explain tmnc.spec.systemDisk to check how to use systemDisk filed. # systemDisk: # size: 60 # type: CloudSSD ## using kubectl explain tmnc.spec.dataDisks to check how to use systemDisk filed. # dataDisks: # – mountTarget: /var/lib/container # size: 100 # type: CloudPremium # fileSystem: ext4 # lifecycleScript: # preInitScript: echo "running before node joins cluster" # postInitScript: echo "running after node joins cluster" subnetSelectorTerms: # replace your tag which is already existed in https://console.cloud.tencent.com/tag/taglist – tags: karpenter.sh/discovery: cls-xxx # – id: subnet-xxx securityGroupSelectorTerms: – tags: karpenter.sh/discovery: cls-xxx # – id: sg-xxx sshKeySelectorTerms: – tags: karpenter.sh/discovery: cls-xxx # – id: skey-xxx

七、步骤5:部署工作负载

你可以通过扩展应用程序 Pod 的数量,并观察它们处于 Pending 状态时 Karpenter 如何创建新节点。常用命令如下:

# Get nodepoolkubectl get nodepool# Get nodeclaimkubectl get nodeclaim# Get TKEMachineNodeClasskubectl get tmnc# Check your cloud resources has been synced to nodeclasskubectl describe tmnc default

以下是 kubectl describe tmnc default 命令的示例输出:

Status: Conditions: Last Transition Time: 2024-08-21T09:17:26Z Message: Reason: Ready Status: True Type: Ready Security Groups: Id: sg-xxx Ssh Keys: Id: skey-xxx Id: skey-xxx Id: skey-xxx Subnets: Id: subnet-xxx Zone: ap-singapore-1 Zone ID: 900001 Id: subnet-xxx Zone: ap-singapore-4 Zone ID: 900004

八、增量集群安装方案

1. 登录 容器服务控制台,在左侧导航栏中选择集群。

2. 单击新建。新建集群步骤请参见 创建集群。

3. 在创建集群 > 组件配置,勾选 Karpenter。

注意:如果选择部署了 Karpenter,CA 将不会被部署。

4. 集群创建完成后,请参考 存量集群迁移方案中步骤3-5 部署 NodePool 资源、TKEMachineNodeClass 资源及工作负载。

赞 (0)
上一篇 4天前
下一篇 4天前