文档首页/ 云容器引擎 CCE/ 最佳实践/ 弹性伸缩/ 使用Karpenter实现节点弹性伸缩
更新时间:2026-07-10 GMT+08:00
分享

使用Karpenter实现节点弹性伸缩

Karpenter是一个适用于Kubernetes平台的动态、高性能、开源的集群自动扩展解决方案,意在正确的时间使用正确的节点,简化Kubernetes基础设施管理。相较于Cluster AutoScaler,它将资源扩容时间由分钟级降为秒级,显著提高集群上工作负载的运行效率并降低成本。

Karpenter的工作原理如下:

  • 监听:监控被标记为unschedulable状态的Pod。许多场景会导致Pod的不可调度,例如:CPU/内存资源不足、selector条件不满足、Node的taint/toleration条件不匹配、hostport被占用等。
  • 计算:Karpenter分析这些导致Pod无法调度的限制。
  • 扩容:选择满足Pod调度限制条件的Node进行扩容。
  • 缩容:当节点空闲、资源到期等场景下,进行缩容。

核心特性与优势

  • 事件驱动,快速扩容:传统CA(Cluster Autoscaler)依赖周期性轮询与云端弹性伸缩组中转,新节点加入通常耗时 3~5 分钟。Karpenter摒弃了这一模式,持续监听集群内部的 Pod 调度事件,实现毫秒级响应。它直接评估未决(Pending)Pod的资源诉求,并绕过中间层直接调用云服务商 API。快速拉起最匹配的计算节点,从容应对突发激增流量与高并发工作负载。
  • 无组架构(Group-less): Karpenter绕过传统的固定节点池限制,支持通过声明式的NodePool策略灵活配置可用区、实例架构及计费模式。系统会精准解析Pod的CPU/内存需求及亲和性(Affinity/Tolerations)等调度规则。结合深度适配的Flexus X实例,更可实现按需定制的CPU/内存资源灵活配比,确保节点规格与业务真实需求“严丝合缝”,从源头避免资源超分和浪费。
  • 持续智能整合(Consolidation): Karpenter不仅关注扩容速度,更注重集群全生命周期的效能管理。系统会持续评估当前的实时资源利用率,通过启用WhenEmptyOrUnderutilized等节点整合策略,Karpenter能够自动回收完全空闲的节点,并主动将低利用率节点上的Pod进行平滑驱逐与迁移。通过将零散负载聚合至更少或更具成本效益的实例上,最大化压缩集群的闲置成本。
  • 容量与费用感知
    • 对接云服务商计费模型。在扩容时,它能够基于实时的实例价格进行多维度的成本计算,智能挑选满足Pod需求的最低单价实例组合。同时它原生支持按需(On-Demand)与竞价(Spot)实例的灵活混部,将集群算力成本压至极低。
    • 实时感知云服务商库存。一旦首选规格售罄(触发资源不足异常),它能够在毫秒级自动重试并无缝回退(Fallback)至其他可用规格或可用区,彻底消除传统CA因单一节点池缺货导致的扩容阻塞,强力保障业务连续性。

前提条件

  • 已创建一个集群,集群版本满足使用Karpenter的前提条件,且集群中包含可运行Karpenter组件的节点。
  • 安装模板过程中,需要拉取公网镜像,需要节点绑定有EIP。
  • Karpenter容器依赖公网访问能力,普通集群需要Karpenter所在节点绑定EIP,Turbo集群需要Karpenter容器绑定EIP。

约束与限制

  • Karpenter需要配置对应的云服务商权限才能创删节点,目前Karpenter支持使用AK/SK凭据和Pod Identity的鉴权方式。Karpenter使用Pod Identity鉴权时仅支持v1.29.15-r40、v1.30.14-r40、v1.31.14-r0、v1.32.9-r0、v1.33.7-r0、v1.34.2-r0及以上版本集群。
  • Karpenter与CCE集群弹性引擎均为节点的扩缩容插件,因此不能同时安装,避免两者间的相互干扰。
  • Karpenter无法缩容部分CCE系统插件Pod所在节点。
  • Karpenter使用Pod Identity鉴权时,扩容节点不支持设置密钥对登录方式。

部署Karpenter

  1. 获取模板包。

    前往模板发布页面,选择合适的版本并下载tgz格式的Helm Chart包。本文以0.3.1版本的模板包为例,该模板包适用于v1.29及以上的CCE集群。由于不同版本的模板包配置项可能存在差异,本文中的配置适用于0.3.1版本。

  2. 上传模板

    1. 登录CCE控制台,进入集群,在左侧导航栏中选择“应用模板”,在右上角单击“上传模板”。
    2. 单击“添加文件”,选中待上传的模板包后,单击“上传”。

  3. 自定义value.yaml

    您可在本地创建一个value.yaml配置文件用于设置安装工作负载参数,在安装时只需导入此配置文件进行自定义安装,其他未指定的参数将会使用默认配置。

  4. 创建模板实例。

    1. 登录CCE控制台,进入集群,在左侧导航栏中选择“应用模板”。
    2. 在已上传的模板中,单击“安装”。
    3. 填写“实例名称”,选择“命名空间”和“选择版本”。
    4. 单击“配置文件”后的“添加文件”按钮,选择本地创建的YAML配置文件,单击“安装”。

    5. 在“模板实例”页签下可以查看模板实例的安装情况。

测试验证

  1. 创建NodePool、CCENodeClass资源。关于该资源配置参数的说明请参见配置参数说明

    apiVersion: karpenter.k8s.huawei/v1alpha1
    kind: CCENodeClass
    metadata:
      name: demo-cce-elastic-cpu
    spec:
      subnetSelectorTerms:
        - id: "30abcb7b-ddeb-4a93-9e83-0b21f59b07a3"  # 节点子网的网络ID
      imsSelector:
        imsFamily: "Huawei Cloud EulerOS 2.0"   # 镜像名称
      blockDeviceMappings:
        root:
          volumeSize: 40
          volumeType: SSD
        k8s:
          volumeSize: 100
          volumeType: SSD
      runtimeConfiguration:
        type: containerd
      login:
        userPassword:
          username: root
          password: "JDYk*****"   # 加盐加密后的密码
    ---
    apiVersion: karpenter.sh/v1
    kind: NodePool
    metadata:
      name: demo-cce-elastic-cpu
    spec:
      disruption:
        budgets:
          - nodes: "1"
        consolidationPolicy: WhenEmptyOrUnderutilized
        consolidateAfter: 30s
      limits:
        cpu: "100"
        memory: 384Gi
      template:
        metadata:
          labels:
            demo.huawei.com/scenario: cpu-elastic
            demo.huawei.com/nodepool-profile: shared-burst-and-consolidation
        spec:
          nodeClassRef:
            group: karpenter.k8s.huawei
            kind: CCENodeClass
            name: demo-cce-elastic-cpu
          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: node.kubernetes.io/instance-type
              operator: In
              values:
                - c9.large.4
                - c9.xlarge.4
                - c9.2xlarge.4
                - c9.4xlarge.4

  2. 创建一个工作负载,验证Karpenter扩容节点。

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: cpu-burst
      namespace: default
    spec:
      replicas: 0
      selector:
        matchLabels:
          app: cpu-burst
      template:
        metadata:
          labels:
            app: cpu-burst
        spec:
          terminationGracePeriodSeconds: 10
          nodeSelector:
            demo.huawei.com/scenario: cpu-elastic
          containers:
            - name: web
              image: nginx:1.27-alpine
              imagePullPolicy: IfNotPresent
              ports:
                - containerPort: 80
                  name: http
              resources:
                requests:
                  cpu: "1400m"
                  memory: "1200Mi"
                limits:
                  cpu: "1400m"
                  memory: "1200Mi"

  3. 扩容工作负载。

    kubectl scale deployment cpu-burst --replicas=10

    Deployment部署后可以看到新拉起的Pod无法在已有节点调度,一段时间后新的节点被创建,Pod能够被正常调度到新节点上:

    $ kubectl get node
    NAME            STATUS   ROLES    AGE     VERSION
    192.168.1.15    Ready    <none>   3h28m   v1.33.5-r20-33.0.4.9
    192.168.1.158   Ready    <none>   42m     v1.33.5-r20-33.0.4.9
    192.168.1.168   Ready    <none>   4m7s    v1.33.5-r20-33.0.4.9
    $ kubectl get pod -l app=cpu-burst
    NAME                         READY   STATUS    RESTARTS   AGE
    cpu-burst-5d84f5647c-697j2   1/1     Running   0          9m35s
    cpu-burst-5d84f5647c-9r9rs   1/1     Running   0          9m35s
    cpu-burst-5d84f5647c-9swmq   1/1     Running   0          9m35s
    cpu-burst-5d84f5647c-bqrmw   1/1     Running   0          9m35s
    cpu-burst-5d84f5647c-jc7f9   1/1     Running   0          9m35s
    cpu-burst-5d84f5647c-pshpx   1/1     Running   0          9m35s
    cpu-burst-5d84f5647c-qkzfm   1/1     Running   0          9m36s
    cpu-burst-5d84f5647c-rl7mk   1/1     Running   0          9m35s
    cpu-burst-5d84f5647c-tnt92   1/1     Running   0          9m35s
    cpu-burst-5d84f5647c-w728l   1/1     Running   0          9m35s

  4. 缩容工作负载

    kubectl scale deployment cpu-burst --replicas=5

    当工作负载被缩容后,新的小核节点先创建,而后老节点被回收。

    $ kubectl get node
    NAME            STATUS   ROLES    AGE     VERSION
    192.168.1.15    Ready    <none>   3h30m   v1.33.5-r20-33.0.4.9
    192.168.1.168   Ready    <none>   6m25s   v1.33.5-r20-33.0.4.9
    192.168.1.71    Ready    <none>   2m14s   v1.33.5-r20-33.0.4.9

模板实例回收

  1. 登录CCE控制台,进入集群,在左侧导航栏中选择“应用模板”。
  2. 在“模板实例”中,选择安装的实例,单击“更多”后的“卸载”。

配置参数说明

  • NodePool资源参数说明:请参见Karpenter官方说明
  • CCENodeClass资源参数说明
    表1 CCENodeClass资源参数

    参数

    是否必选

    参数类型

    描述

    subnetSelectorTerms

    SubnetSelectorTerm object

    参数解释:

    配置节点子网信息的列表

    约束限制:

    不涉及

    ecsGroupId

    String

    参数解释:

    云服务器组ID,若指定,将节点创建在该云服务器组下

    约束限制:

    不涉及

    取值范围:

    不涉及

    默认取值:

    imsSelector

    IMSSelector object

    参数解释:

    节点操作系统与镜像的配置对象

    约束限制:

    不涉及

    blockDeviceMappings

    BlockDeviceMappings Object

    参数解释:

    节点磁盘设备的配置对象

    约束限制:

    不涉及

    login

    Login Object

    参数解释:

    节点的登录方式

    约束限制:

    不涉及

    runtimeConfiguration

    RuntimeConfiguration Object

    参数解释:

    运行时配置对象

    约束限制:

    不涉及

    表2 SubnetSelectorTerm

    参数

    是否必选

    参数类型

    描述

    id

    String

    参数解释:

    网卡所在子网的网络ID

    约束限制:

    不涉及

    取值范围:

    登录VPC控制台,在左侧导航栏选择“子网”,单击子网名称,在“基本信息”页签下找到“网络ID”字段复制即可。

    默认取值:

    不涉及

    表3 IMSSelector

    参数

    是否必选

    参数类型

    描述

    imsFamily

    String

    参数解释:

    节点的操作系统类型。具体支持的操作系统请参见节点操作系统说明

    约束限制:

    不涉及

    取值范围:

    不涉及

    默认取值:

    不涉及

    表4 BlockDeviceMappings

    参数

    是否必选

    参数类型

    描述

    root

    BlockDevice Object

    参数解释:

    系统磁盘

    约束限制:

    不涉及

    k8s

    BlockDevice Object

    参数解释:

    runtime及K8s使用数据盘

    约束限制:

    不涉及

    users

    Array of BlockDevice Objects

    参数解释:

    用户数据卷

    约束限制:

    不涉及

    表5 BlockDevice

    参数

    是否必选

    参数类型

    描述

    volumeSize

    Int

    参数解释:

    磁盘大小,单位为GiB

    约束限制:

    不涉及

    取值范围:

    • root卷取值范围:20-1024
    • k8s卷取值范围:20-32768
    • 用户卷取值范围:10-32768

    默认取值:

    不涉及

    volumeType

    String

    参数解释:

    磁盘类型

    约束限制:

    不涉及

    取值范围:

    • SAS:高IO,是指由SAS存储提供资源的磁盘类型。
    • SSD:超高IO,是指由SSD存储提供资源的磁盘类型。
    • SATA:普通IO,是指由SATA存储提供资源的磁盘类型。EVS已下线SATA磁盘,仅存量节点有此类型的磁盘。
    • ESSD:极速型SSD云硬盘,是指由极速型SSD存储提供资源的磁盘类型。
    • GPSSD:通用型SSD云硬盘,是指由通用型SSD存储提供资源的磁盘类型。
    • ESSD2:极速型SSD V2云硬盘,是指由极速型SSD V2存储提供资源的磁盘类型。
    • GPSSD2:通用型SSD V2云硬盘,是指由通用型SSD V2存储提供资源的磁盘类型。

    默认取值:

    不涉及

    表6 Login

    参数

    是否必选

    参数类型

    描述

    userPassword

    UserPassword Object

    参数解释:

    节点登录方式配置对象

    约束限制:

    不涉及

    sshKey

    String

    参数解释:

    选择密钥对方式登录时的密钥对名称。

    约束限制:

    不涉及

    取值范围:

    不涉及

    默认取值:

    不涉及

    表7 UserPassword

    参数

    是否必选

    参数类型

    描述

    username

    String

    参数解释:

    节点登录名称

    约束限制:

    不涉及

    取值范围:

    不涉及

    默认取值:

    不涉及

    password

    String

    参数解释:

    登录密码,若创建节点通过用户名密码方式,即使用该字段,则响应体中该字段作屏蔽展示。

    约束限制:

    创建节点时password字段需要加盐加密,具体方法请参见创建节点时password字段加盐加密

    取值范围:

    密码复杂度要求:

    • 长度为8-26位。
    • 密码至少必须包含大写字母、小写字母、数字和特殊字符(!@$%^-_=+[{}]:,./?)中的三种。
    • 密码不能包含用户名或用户名的逆序。

    默认取值:

    不涉及

    表8 RuntimeConfiguration

    参数

    是否必选

    参数类型

    描述

    type

    String

    参数解释:

    容器运行时

    约束限制:

    不涉及

    取值范围:

    不涉及

    默认取值:

    容器运行时, 默认场景:

    • 1.25以下集群:默认为"docker"
    • 1.25及以上集群,随操作系统变化,默认的容器运行时不同

      操作系统为欧拉2.5、欧拉2.8的节点仅支持"docker",其余操作系统的节点默认为"containerd"

相关文档