All Products
Search
Document Center

Container Service for Kubernetes:Configure an eci-profile

Last Updated:Mar 26, 2026

The eci-profile ConfigMap lets you control how pods are scheduled to Elastic Container Instance (ECI) and what annotations and labels get injected—all at the cluster level, without modifying individual workload YAML files.

When a pod is created, ACK reads the eci-profile ConfigMap from the kube-system namespace and applies its settings to the pod.

How it works

eci-profile provides three capabilities:

  • ECI Scheduler — Automatically schedules pods to ECI based on pod labels or namespace labels, using a mutating webhook. No manual toleration or node-selector changes are needed in your workload YAML.

  • ECI Effect — Automatically injects annotations and labels into pods that match your selector criteria. Use this to enable ECI features such as specifying ECS instance types, enabling image caches, or configuring Network Time Protocol (NTP)—without modifying each workload.

  • Hot updates — Changes to cluster-level parameters (such as vpcId and vSwitchIds) take effect immediately for newly created ECI pods. You do not need to restart the ack-virtual-node component. Existing ECI pods pick up the new settings only after rolling updates are performed.

Prerequisites

Before you begin, make sure that:

  • The ack-virtual-node component in your cluster is updated to the latest version. See Manage components.

  • Mutating webhooks are enabled in your cluster (required for ECI Scheduler). Pods in ACK Serverless clusters are automatically scheduled to ECI and do not need ECI Scheduler.

View the eci-profile

Run the following command to inspect the current eci-profile ConfigMap:

kubectl get cm -n kube-system eci-profile -o yaml

The output includes a data section similar to this:

apiVersion: v1
data:
  enableClusterIp: "true"
  enableHybridMode: "false"
  enableLinuxArm64Node: "false"
  enableLogController: "false"
  enablePVCController: "false"
  enablePrivateZone: "false"
  enableReuseSSLKey: "false"
  featureGates: "WaitForFirstConsumer=false"
  securityGroupId: sg-2zeeyaaxlkq9sppl****
  selectors: ""
  slsMachineGroup: ""
  vSwitchIds: vsw-2ze23nqzig8inprou****,vsw-2ze94pjtfuj9vaymf****
  vpcId: vpc-2zeghwzptn5zii0w7****
kind: ConfigMap
metadata:
  creationTimestamp: "2023-01-11T08:28:14Z"
  name: eci-profile
  namespace: kube-system
  resourceVersion: "356"
  uid: b345fa8c-919e-41fc-a981-57864b1a****

The data section contains two types of parameters:

ParameterPurposeConfiguration guide
selectorsDefines which pods get scheduled to ECI and which annotations and labels get injectedConfigure selectors
Other parameters (vpcId, vSwitchIds, etc.)Cluster-level network and feature settings; support hot updatesUpdate cluster-level parameters

Edit the eci-profile

Choose one of the following methods:

kubectl:

kubectl edit configmap eci-profile -n kube-system

ACK console:

  1. Log on to the Container Service ACK console.

  2. On the Clusters page, click the name of the target cluster.

  3. In the left navigation pane, choose Configurations > ConfigMaps.

  4. Select kube-system from the namespace drop-down list.

  5. Find eci-profile and click Edit YAML in the Actions column.

Configure selectors

The selectors parameter controls both scheduling (ECI Scheduler) and annotation or label injection (ECI Effect).

How selectors work

Before you write a selector configuration, understand the matching and application rules:

Matching logic (within a selector):

  • If both namespaceSelector and objectSelector are set, the pod must satisfy both conditions (AND logic).

  • If only one of them is set, the pod needs to match only that condition.

  • If neither is set but effect is configured, the effect applies to all pods scheduled to ECI.

Application logic (across selectors):

  • When a pod matches multiple selectors, the effects of all matching selectors are applied in descending order of selector position. The first matching selector has the highest priority.

  • Effects never overwrite existing annotations or labels already on the pod. Among matched selectors, earlier selectors take higher priority over later ones.

Changes to selectors take effect immediately for new pods. No restart of ack-virtual-node is required.

Selector components

Each selector is a JSON object with the following fields:

FieldRequiredDescription
nameYesUnique identifier for the selector
namespaceSelectorNoMatches pods whose namespace has the specified labels (matchLabels). Multiple labels use AND logic.
objectSelectorNoMatches pods that have the specified labels (matchLabels). Multiple labels use AND logic.
effectNoAnnotations and labels to inject into matched pods. Does not overwrite existing annotations or labels on the pod.

Selector template

Note

Remove all comments (# ...) before applying the configuration.

data:
  selectors: |
    [
      {
        "name": "selector-demo1",         # required
        "namespaceSelector": {            # optional; filters by namespace labels
          "matchLabels": {                # AND logic among multiple labels
            "eci": "true"
          }
        },
        "objectSelector": {               # optional; filters by pod labels
          "matchLabels": {                # AND logic among multiple labels
            "eci": "true"
          }
        },
        "effect": {                       # optional; annotations and labels to inject
          "annotations": {
            "k8s.aliyun.com/eci-use-specs": "ecs.c6.xlarge"
          },
          "labels": {
            "created-by-eci": "true"
          }
        }
      },
      {
        "name": "selector-demo2",
        "objectSelector": {
          "matchLabels": {
            "eci": "test"
          }
        }
      }
    ]

In the example above, selector-demo1 matches pods that have the eci: true label and belong to a namespace with the eci: true label. Those pods are scheduled to ECI and receive the k8s.aliyun.com/eci-use-specs: ecs.c6.xlarge annotation and the created-by-eci: true label.

Verify selectors

After saving the configuration, run this command to confirm the selectors are active:

kubectl get mutatingwebhookconfigurations -o yaml vk-webhook

If the returned YAML contains your configured selectors, the configuration is applied. If not, check whether the selector JSON is correctly formatted.

Example 1: Schedule specific pods to ECI

Pods with the created-by-eci: true label that belong to a namespace with the type: eci label are automatically scheduled to ECI.

data:
  selectors: |
    [
      {
        "name":"eci-selector",
        "namespaceSelector":{
          "matchLabels":{
            "type":"eci"
          }
        },
        "objectSelector":{
          "matchLabels":{
            "created-by-eci":"true"
          }
        }
      }
    ]

Example 2: Schedule pods to ECI with a GPU instance type

Pods in namespaces labeled gpu: true are scheduled to ECI using the ecs.gn6v-c8g1.2xlarge GPU-accelerated instance type, and receive the gpu: test label.

data:
  selectors: |
    [
      {
        "name":"gpu-namespace-selector",
        "namespaceSelector":{
          "matchLabels":{
            "gpu":"true"
          }
        },
        "effect": {
          "annotations": {
            "k8s.aliyun.com/eci-use-specs":"ecs.gn6v-c8g1.2xlarge"
          },
          "labels":{
            "gpu":"test"
          }
        }
      }
    ]

Example 3: Schedule pods to ECI with automatic image cache matching

Pods with the imc: auto label are scheduled to ECI with automatic image cache matching enabled.

data:
  selectors: |
    [
      {
        "name":"autoimc-object-selector",
        "objectSelector":{
          "matchLabels":{
            "imc":"auto"
          }
        },
        "effect": {
          "annotations": {
            "k8s.aliyun.com/eci-auto-imc": "true"
          }
        }
      }
    ]

Update cluster-level parameters

The following parameters in the data section define cluster-level defaults for ECI pod creation. If a pod does not specify these values explicitly, the eci-profile values are used. All changes take effect immediately for new pods without restarting ack-virtual-node.

ParameterExampleDescription
enableClusterIp"true"Whether to support cluster IP addresses for ECI pods
enableLinuxArm64Node"false"Whether to enable ARM-based virtual nodes. See Schedule pods to an ARM-based virtual node.
enableLogController"false"Whether to use the CustomResourceDefinition (CRD) for Simple Log Service to collect pod logs. If set to true, also set slsMachineGroup.
enablePVCController"false"Whether to enable online disk extension. When enabled, the system performs hot extensions on persistent volume claims (PVCs) bound to disks.
enablePrivateZone"false"Whether to use PrivateZone for domain name resolution
enableReuseSSLKey"false"Whether to reuse SSL keys across ECI pods. When enabled, all pods share one SSL certificate instead of receiving unique ones, improving pod creation throughput at the cost of per-pod certificate isolation.
featureGates"WaitForFirstConsumer=false"Feature gate configuration. Only WaitForFirstConsumer is supported. When set to true, PersistentVolumes (PVs) and backend storage are created only after the pod is scheduled, using the node's zone and region. Update csi-provisioner to the latest version before enabling. See Volume binding mode.
securityGroupIdsg-2ze0b9o8pjjzts4h****Security group for ECI pods
slsMachineGroup"test-mg"Simple Log Service machine group for ECI pods. Required when enableLogController is true.
vSwitchIdsvsw-2zeet2ksvw7f14ryz****IDs of the vSwitches for ECI pods, separated by commas
vpcIdvpc-2zeghwzptn5zii0w7****ID of the virtual private cloud (VPC) for ECI pods
Important

By default, ack-virtual-node issues a unique SSL certificate to each pod. Enabling enableReuseSSLKey causes all pods to share a single certificate—this improves creation efficiency for large pod counts but reduces per-pod isolation.

The following shows a complete data section example:

data:
  enableClusterIp: "true"
  enableHybridMode: "false"
  enableLinuxArm64Node: "false"
  enableLogController: "false"
  enablePVCController: "false"
  enablePrivateZone: "false"
  enableReuseSSLKey: "false"
  securityGroupId: sg-2zeeyaaxlkq9sppl****
  selectors: ""
  slsMachineGroup: ""
  vSwitchIds: vsw-2ze23nqzig8inprou****,vsw-2ze94pjtfuj9vaymf****
  vpcId: vpc-2zeghwzptn5zii0w7****

What's next