Pod affinity scheduling constrains where a pod can be scheduled based on the labels of pods already running on virtual nodes — not on node properties. In an ACS cluster, pod affinity uses native Kubernetes scheduling semantics: specify topology domains and label rules in podAffinity or podAntiAffinity to co-locate or spread pods across zones.
A common use case: you run a stateless service with multiple replicas and want all replicas to land in the same availability zone as a shared cache pod to reduce cross-zone latency. Pod affinity with requiredDuringSchedulingIgnoredDuringExecution enforces this strictly at scheduling time.
Prerequisites
Before you begin, make sure that:
-
kube-scheduler is installed and meets the following version requirements:
ACS cluster version Scheduler component version 1.31 v1.31.0-aliyun-1.2.0 and later 1.30 v1.30.3-aliyun-1.1.1 and later 1.28 v1.28.9-aliyun-1.1.0 and later -
acs-virtual-node is installed at version v2.12.0-acs.4 or later.
Limitations
ACS imposes the following constraints on pod affinity.
GPU-HPN pods
Pod affinity has constraints when all three conditions below apply to a pod:
-
The pod uses the High-Performance Network GPU (GPU-HPN) compute type.
-
The pod's
schedulerNameisdefault-scheduler. -
Enable Custom Tags And Scheduler For GPU-HPN Nodes is not selected in the scheduler component configuration.
The Enable Custom Tags and the Scheduler for GPU-HPN Nodes option is enabled by default in new versions. For details, see kube-scheduler.
Supported policy
Only requiredDuringSchedulingIgnoredDuringExecution is supported. preferredDuringSchedulingIgnoredDuringExecution is not supported.
The following fields apply within requiredDuringSchedulingIgnoredDuringExecution:
| Field | Description | Constraint |
|---|---|---|
labelSelector |
Finds matching pods. Pods with this label are counted per topology domain. | Pods of other compute types (general-purpose, compute-optimized, GPU) are excluded from the count. |
namespaces |
Specifies namespaces to search for matching pods, used with labelSelector. |
Not supported |
namespaceSelector |
Selects namespaces by namespace labels instead of names. | Not supported |
For the full field reference, see Pod affinity and anti-affinity in the Kubernetes documentation.
Schedule pods into the same zone
This example shows how to use podAffinity to schedule a Deployment's pods into the same availability zone as an existing labeled pod. This pattern is typical when you want a service's replicas to share the same zone as a dependency (for example, a cache) to avoid cross-zone latency.
The workflow has two stages: first, deploy a pod with a target label; then, deploy a Deployment that uses podAffinity to co-locate with that labeled pod.
Stage 1: Deploy the labeled reference pod
-
List virtual nodes in the cluster.
kubectl get nodeExpected output:
NAME STATUS ROLES AGE VERSION virtual-kubelet-cn-hangzhou-i Ready agent 5h42m v1.28.3-xx virtual-kubelet-cn-hangzhou-j Ready agent 5h42m v1.28.3-xx -
Create a file named
with-affinity-pod.yamlwith the following content.apiVersion: v1 kind: Pod metadata: labels: pod-affinity-label: with-pod-affinity # This label is the affinity target name: with-affinity-label-pod spec: containers: - args: - 'infinity' command: - sleep image: registry-cn-hangzhou.ack.aliyuncs.com/acs/stress:v1.0.4 imagePullPolicy: IfNotPresent name: stress resources: limits: cpu: '1' memory: 1Gi requests: cpu: '1' memory: 1Gi -
Deploy the pod.
kubectl apply -f with-affinity-pod.yaml -
Verify the pod is running and note which zone it lands in.
kubectl get pod -o wideExpected output:
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES with-affinity-label-pod 1/1 Running 0 75s 192.168.xx.xxx virtual-kubelet-cn-hangzhou-i <none> <none>The pod is scheduled to zone
cn-hangzhou-i. The Deployment in the next stage uses this pod's label to determine the target zone.
Stage 2: Deploy with pod affinity
-
Create a file named
origin-affinity-pod.yamlwith the following content.apiVersion: apps/v1 kind: Deployment metadata: name: dep-pod-affinity labels: app: pod-affinity-demo spec: replicas: 4 selector: matchLabels: app: pod-affinity-demo template: metadata: labels: app: pod-affinity-demo spec: containers: - name: pod-affinity-demo image: registry-cn-hangzhou.ack.aliyuncs.com/acs/stress:v1.0.4 command: - "sleep" - "infinity" resources: limits: cpu: '1' memory: 1Gi requests: cpu: '1' memory: 1Gi affinity: podAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: pod-affinity-label operator: In values: - with-pod-affinity # Match the label on with-affinity-label-pod topologyKey: topology.kubernetes.io/zone # Co-locate in the same zone # Note: only GPU-HPN pods count toward the labelSelector total. # Pods of other compute types are excluded from the count in ACS. -
Deploy the Deployment.
kubectl apply -f origin-affinity-pod.yaml -
Verify that all pods are scheduled in the same zone.
kubectl get pod -o wideExpected output:
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES dep-pod-affinity-6b9d4f7c87-5jlfx 1/1 Running 0 3m26s 192.168.xx.xxx virtual-kubelet-cn-hangzhou-i <none> <none> dep-pod-affinity-6b9d4f7c87-hwdpc 1/1 Running 0 3m26s 192.168.xx.xxx virtual-kubelet-cn-hangzhou-i <none> <none> dep-pod-affinity-6b9d4f7c87-jfcrq 1/1 Running 0 3m26s 192.168.xx.xxx virtual-kubelet-cn-hangzhou-i <none> <none> dep-pod-affinity-6b9d4f7c87-xwbfr 1/1 Running 0 3m26s 192.168.xx.xxx virtual-kubelet-cn-hangzhou-i <none> <none> with-affinity-label-pod 1/1 Running 0 6m30s 192.168.xx.xxx virtual-kubelet-cn-hangzhou-i <none> <none>All five pods — the four Deployment replicas and the reference pod — run in zone
cn-hangzhou-i.