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
vpcIdandvSwitchIds) take effect immediately for newly created ECI pods. You do not need to restart theack-virtual-nodecomponent. Existing ECI pods pick up the new settings only after rolling updates are performed.
Prerequisites
Before you begin, make sure that:
The
ack-virtual-nodecomponent 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 yamlThe 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:
| Parameter | Purpose | Configuration guide |
|---|---|---|
selectors | Defines which pods get scheduled to ECI and which annotations and labels get injected | Configure selectors |
Other parameters (vpcId, vSwitchIds, etc.) | Cluster-level network and feature settings; support hot updates | Update cluster-level parameters |
Edit the eci-profile
Choose one of the following methods:
kubectl:
kubectl edit configmap eci-profile -n kube-systemACK console:
Log on to the Container Service ACK console.
On the Clusters page, click the name of the target cluster.
In the left navigation pane, choose Configurations > ConfigMaps.
Select kube-system from the namespace drop-down list.
Find
eci-profileand 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
namespaceSelectorandobjectSelectorare 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
effectis 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:
| Field | Required | Description |
|---|---|---|
name | Yes | Unique identifier for the selector |
namespaceSelector | No | Matches pods whose namespace has the specified labels (matchLabels). Multiple labels use AND logic. |
objectSelector | No | Matches pods that have the specified labels (matchLabels). Multiple labels use AND logic. |
effect | No | Annotations and labels to inject into matched pods. Does not overwrite existing annotations or labels on the pod. |
Selector template
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-webhookIf 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.
| Parameter | Example | Description |
|---|---|---|
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. |
securityGroupId | sg-2ze0b9o8pjjzts4h**** | Security group for ECI pods |
slsMachineGroup | "test-mg" | Simple Log Service machine group for ECI pods. Required when enableLogController is true. |
vSwitchIds | vsw-2zeet2ksvw7f14ryz**** | IDs of the vSwitches for ECI pods, separated by commas |
vpcId | vpc-2zeghwzptn5zii0w7**** | ID of the virtual private cloud (VPC) for ECI pods |
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
To annotate ECI pods for advanced features such as instance type selection and image caching, see ECI Pod Annotation.
To schedule pods to an ARM-based virtual node, see Schedule pods to an ARM-based virtual node.