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

使用Karpenter实现节点弹性伸缩

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

Karpenter的工作原理如下:

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

前提条件

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

约束与限制

  • Karpenter需要配置对应的云服务商权限才能创删节点,目前Karpenter暂时使用AK/SK凭据。后续Karpenter将作为CCE插件市场系统插件,支持自定义插件委托或Pod Identity的鉴权方式。
  • Karpenter与CCE集群弹性引擎均为节点的扩缩容插件,因此不能同时安装,避免两者间的相互干扰。
  • Karpenter无法缩容部分CCE系统插件Pod所在节点。

部署Karpenter

  1. 获取模板包。

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

  2. 上传模板

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

  3. 自定义value.yaml

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

    默认配置内容如下:
    # Default values for karpenter-provider-huawei
    # -- Number of controller replicas
    replicaCount: 1
    # Controller image configuration
    image:
      # -- Controller image repository
      repository: swr.ap-southeast-3.myhuaweicloud.com/huaweiclouddeveloper/cce/karpenter/controller
      # -- Controller image tag
      tag: "latest"
      # -- Image pull policy
      pullPolicy: IfNotPresent
    # kube-rbac-proxy sidecar configuration
    rbacProxy:
      image:
        # -- kube-rbac-proxy image repository
        repository: quay.io/brancz/kube-rbac-proxy
        # -- kube-rbac-proxy image tag
        tag: "v0.16.0"
        # -- Image pull policy
        pullPolicy: IfNotPresent
    # -- Image pull secrets for controller pods
    imagePullSecrets: []
    # - name: registry-credentials
    # -- Name prefix for all resources
    namePrefix: "karpenter-provider-huawei-"
    serviceAccount:
      # -- Create ServiceAccount
      create: true
      # -- ServiceAccount name
      name: controller-manager
    # Controller arguments
    controller:
      # -- Metrics port
      metricsPort: 8080
      # -- Health probe port
      healthProbePort: 8081
    # Huawei Cloud credentials
    credentials:
      # -- Create a Secret for credentials
      create: true
      # -- Secret name for Huawei Cloud credentials
      name: "huawei-credentials"
      # -- Use an existing Secret when credentials.create is false
      existingSecret: ""
      # -- Huawei Cloud access key
      accessKey: "your-access-key"
      # -- Huawei Cloud secret key
      secretKey: "your-secret-key"
      # -- Huawei Cloud region ID
      region: "your-region-id"
      # -- Huawei Cloud CCE cluster ID
      clusterID: "your-cluster-id"
    clusterInfo:
      # -- Cluster category: Optional. Enter "eni" for Turbo network types.
      # For other network types (vpc-router or overlay_l2), enter other values.
      category: ""
    # -- yangtseEipInfo: Supports user-defined EIPs (Elastic IPs) bound to Karpenter pods.
    # This only takes effect when clusterInfo.category is set to "eni".
    yangtseEipInfo:
      yangtse.io/pod-with-eip: "true"
    # Controller resources
    resources:
      limits:
        cpu: "1"
        memory: 512Mi
      requests:
        cpu: 200m
        memory: 256Mi
    # -- Pod security context
    podSecurityContext:
      runAsNonRoot: true
      seccompProfile:
        type: RuntimeDefault
    # -- Container security context for manager
    securityContext:
      readOnlyRootFilesystem: true
      allowPrivilegeEscalation: false
      capabilities:
        drop:
          - "ALL"
    # -- Node selector for controller pods
    nodeSelector: {}
    # -- Tolerations for controller pods
    tolerations: []
    # -- Affinity for controller pods
    affinity: {}
    • clusterInfo.category指定为eni时,会自动为Karpenter Pod绑定EIP,建议在Turbo集群开启,更多EIP参数可在yangtseEipInfo字段中配置,参数配置请参见在CCE Turbo集群中为Pod配置EIP
    • credentials.clusterID、credentials.accessKey、credentials.secretKey、credentials.region等字段为必填字段,其他参数请根据业务实际所需调整。

  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:
      # Add one subnet per target AZ if you want this demo NodePool to launch
      # across multiple zones.
      subnetSelectorTerms:
        - id: "30abcb7b-ddeb-4a93-9e83-0b21f59b07a3"
      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:
        # Allow enough headroom for the 600-replica GSS validation to scale past 4 x 12c nodes.
        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
            # Keep zone unconstrained so Karpenter can use every AZ exposed by the
            # selected ECSNodeClass subnets. Re-add a topology.kubernetes.io/zone
            # requirement if you need to pin this demo to specific AZs.
            - 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

    参数解释:

    节点登录方式配置对象

    约束限制:

    不涉及

    表7 UserPassword

    参数

    是否必选

    参数类型

    描述

    username

    String

    参数解释:

    节点登录名称

    约束限制:

    不涉及

    取值范围:

    不涉及

    默认取值:

    不涉及

    password

    String

    参数解释:

    节点登录密码

    约束限制:

    不涉及

    取值范围:

    不涉及

    默认取值:

    不涉及

    表8 RuntimeConfiguration

    参数

    是否必选

    参数类型

    描述

    type

    String

    参数解释:

    容器运行时

    约束限制:

    不涉及

    取值范围:

    不涉及

    默认取值:

    容器运行时, 默认场景:

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

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

相关文档