Place One Pod per Node Without Using a DaemonSet
Scenario
You are working in the aws-ecr namespace on a Kubernetes cluster with two
worker nodes.
An application must be deployed with three replicas, but the design requires that no more than one Pod runs on the same worker node — to spread the application across nodes for resilience.
A DaemonSet must not be used to achieve this behavior — DaemonSets are designed for a different use case (one pod per node automatically, tied to node lifecycle) and do not support replica counts or rolling update strategies the same way a Deployment does.
Task
- Create a Deployment named
ecr-deploymentwith 3 replicas in theaws-ecrnamespace - Apply the following labels to the Deployment and Pod template:
app: ecr-apptier: backend
- Configure the Deployment with two containers:
eks-container1using imagepublic.ecr.aws/docker/library/httpd:alpineeks-container2using imagepublic.ecr.aws/eks-distro/kubernetes/pause:3.10.1
- Ensure no more than one Pod from this Deployment runs on the same worker node — use
topologyKey: kubernetes.io/hostnameto achieve this - With 2 worker nodes and 3 replicas, the third Pod has nowhere to go. Verify the resulting scheduling behavior:
- 2 Pods should be in the
Runningstate - 1 Pod should remain in the
Pendingstate
- 2 Pods should be in the
Hint 1 — Spreading Pods Across Nodes
Kubernetes provides Pod Anti-Affinity to control which nodes a Pod can or
cannot be scheduled on relative to other Pods. To ensure no two Pods from the
same Deployment land on the same node, use podAntiAffinity with
requiredDuringSchedulingIgnoredDuringExecution.
The topologyKey: kubernetes.io/hostname tells the scheduler to treat each
node as a separate topology domain — meaning Pods matching the
labelSelector cannot share the same node.
spec:
template:
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchLabels:
app: ecr-app
topologyKey: kubernetes.io/hostname
Documentation
Hint 2 — Why the Third Pod Stays Pending
requiredDuringSchedulingIgnoredDuringExecution is a hard requirement —
the scheduler will not place a Pod on a node if doing so violates the
anti-affinity rule, even if no other node has room. With 2 worker nodes and
replicas: 3, the third Pod has no valid node left and will remain
Pending indefinitely. This is expected behavior, not a misconfiguration.
kubectl get pods -n aws-ecr -o wide
kubectl describe pod -n aws-ecr -l app=ecr-app | grep -A5 Events
The FailedScheduling event on the pending Pod will explicitly mention the
anti-affinity constraint as the reason no node was available.
Documentation