Bird
Raised Fist0
Kubernetesdevops~7 mins

Pod affinity and anti-affinity in Kubernetes - Commands & Configuration

Choose your learning style10 modes available
Introduction
Sometimes you want certain pods to run close together or far apart on your cluster nodes. Pod affinity and anti-affinity help control where pods are placed based on other pods' locations to improve performance or reliability.
When you want two related services to run on the same node for faster communication.
When you want to spread replicas of a service across different nodes to avoid all going down at once.
When you want to avoid running pods that use a lot of resources on the same node to prevent overload.
When you want to ensure pods that share data are scheduled near each other to reduce network latency.
When you want to keep pods of the same type apart to improve fault tolerance.
Config File - pod-affinity.yaml
pod-affinity.yaml
apiVersion: v1
kind: Pod
metadata:
  name: my-app-pod
  labels:
    app: my-app
spec:
  affinity:
    podAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - key: app
            operator: In
            values:
            - my-app
        topologyKey: kubernetes.io/hostname
    podAntiAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 100
        podAffinityTerm:
          labelSelector:
            matchExpressions:
            - key: app
              operator: In
              values:
              - my-app
          topologyKey: failure-domain.beta.kubernetes.io/zone
  containers:
  - name: my-app-container
    image: nginx:1.23.3
    ports:
    - containerPort: 80

This file defines a pod named my-app-pod running an Nginx container.

The affinity section has two parts:

  • podAffinity: Requires this pod to be scheduled on the same node as other pods labeled app: my-app.
  • podAntiAffinity: Prefers to avoid scheduling this pod in the same zone as other pods labeled app: my-app, spreading pods across zones.

topologyKey controls the scope of affinity or anti-affinity, like node hostname or zone.

Commands
This command creates the pod with the specified affinity and anti-affinity rules to control where it runs.
Terminal
kubectl apply -f pod-affinity.yaml
Expected OutputExpected
pod/my-app-pod created
This shows the pods with their node assignments so you can verify if the pod affinity and anti-affinity rules worked.
Terminal
kubectl get pods -o wide
Expected OutputExpected
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES my-app-pod 1/1 Running 0 10s 10.244.1.5 worker-node1 <none> <none>
→
-o wide - Shows extra details including the node where each pod is running
This command shows detailed information about the pod, including the affinity rules and scheduling decisions.
Terminal
kubectl describe pod my-app-pod
Expected OutputExpected
Name: my-app-pod Namespace: default Node: worker-node1/192.168.1.10 Start Time: Thu, 01 Jun 2023 12:00:00 +0000 Labels: app=my-app Annotations: <none> Status: Running IP: 10.244.1.5 Containers: my-app-container: Image: nginx:1.23.3 Port: 80/TCP State: Running Ready: True Restart Count: 0 Conditions: Type Status Initialized True Ready True ContainersReady True PodScheduled True Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 10s default-scheduler Successfully assigned default/my-app-pod to worker-node1 Normal Pulled 9s kubelet Container image "nginx:1.23.3" already present on machine Normal Created 9s kubelet Created container my-app-container Normal Started 9s kubelet Started container my-app-container
Key Concept

If you remember nothing else from this pattern, remember: pod affinity and anti-affinity let you control pod placement based on other pods to improve performance and reliability.

Common Mistakes
Using pod affinity without matching labels on other pods
The scheduler cannot find pods matching the label selector, so affinity rules have no effect and pods may schedule anywhere.
Ensure the label selectors in affinity rules match labels on existing pods you want to be near or avoid.
Confusing requiredDuringScheduling with preferredDuringScheduling
Required rules must be met or pod won't schedule; preferred rules are soft preferences and may be ignored if not possible.
Use requiredDuringScheduling for strict placement needs and preferredDuringScheduling for flexible preferences.
Using the wrong topologyKey like a non-existent label
The scheduler cannot group nodes correctly, so affinity or anti-affinity rules fail or behave unexpectedly.
Use valid topology keys like kubernetes.io/hostname for nodes or failure-domain.beta.kubernetes.io/zone for zones.
Summary
Create a pod manifest with affinity and anti-affinity rules to control pod placement.
Apply the manifest with kubectl apply to create the pod with these rules.
Use kubectl get pods -o wide and kubectl describe pod to verify pod placement and affinity details.

Practice

(1/5)
1. What is the main purpose of podAffinity in Kubernetes?
easy
A. To automatically restart pods on failure
B. To prevent pods from running on the same node
C. To limit the number of pods per node
D. To schedule pods close to other pods with matching labels

Solution

  1. Step 1: Understand podAffinity concept

    Pod affinity is used to place pods close to other pods that have specific labels, improving communication or resource sharing.
  2. Step 2: Compare options with podAffinity purpose

    Only To schedule pods close to other pods with matching labels describes placing pods close to others with matching labels, which matches podAffinity's goal.
  3. Final Answer:

    To schedule pods close to other pods with matching labels -> Option D
  4. Quick Check:

    podAffinity = place pods close [OK]
Hint: Affinity means placing pods near each other [OK]
Common Mistakes:
  • Confusing affinity with anti-affinity
  • Thinking affinity limits pods per node
  • Mixing affinity with pod restart policies
2. Which of the following is the correct syntax to specify a required pod anti-affinity rule in a pod spec?
easy
A. "podAntiAffinity": {"requiredDuringSchedulingIgnoredDuringExecution": [{"labelSelector": {"matchLabels": {"app": "web"}}, "topologyKey": "kubernetes.io/hostname"}]}
B. "podAntiAffinity": {"preferredDuringSchedulingIgnoredDuringExecution": [{"weight": 100, "podAffinityTerm": {"labelSelector": {"matchLabels": {"app": "web"}}, "topologyKey": "kubernetes.io/hostname"}}]}
C. "podAffinity": {"requiredDuringSchedulingIgnoredDuringExecution": [{"labelSelector": {"matchLabels": {"app": "web"}}, "topologyKey": "kubernetes.io/hostname"}]}
D. "podAffinity": {"preferredDuringSchedulingIgnoredDuringExecution": [{"weight": 50, "podAffinityTerm": {"labelSelector": {"matchLabels": {"app": "web"}}, "topologyKey": "kubernetes.io/zone"}}]}

Solution

  1. Step 1: Identify required pod anti-affinity syntax

    Required pod anti-affinity uses podAntiAffinity with requiredDuringSchedulingIgnoredDuringExecution and a label selector plus topology key.
  2. Step 2: Match syntax with options

    "podAntiAffinity": {"requiredDuringSchedulingIgnoredDuringExecution": [{"labelSelector": {"matchLabels": {"app": "web"}}, "topologyKey": "kubernetes.io/hostname"}]} correctly uses podAntiAffinity with requiredDuringSchedulingIgnoredDuringExecution and proper labelSelector and topologyKey.
  3. Final Answer:

    Correct required pod anti-affinity syntax -> Option A
  4. Quick Check:

    Required anti-affinity uses podAntiAffinity + requiredDuringScheduling [OK]
Hint: Required anti-affinity uses podAntiAffinity + requiredDuringScheduling [OK]
Common Mistakes:
  • Using podAffinity instead of podAntiAffinity
  • Confusing required and preferred rules
  • Wrong topologyKey values
3. Given this pod spec snippet, what will happen if a pod with label app: frontend is scheduled?
affinity:
  podAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
    - labelSelector:
        matchLabels:
          app: backend
      topologyKey: kubernetes.io/hostname
medium
A. The pod will be scheduled only if no pod with label app=backend exists
B. The pod will be scheduled on any node regardless of other pods
C. The pod will be scheduled on a node that already runs a pod with label app=backend
D. The pod scheduling will fail due to syntax error

Solution

  1. Step 1: Understand required podAffinity behavior

    Required podAffinity means the pod must be placed on a node where pods with matching labels already run, here app=backend.
  2. Step 2: Apply to given pod spec

    The pod with label app=frontend requires a node with pods labeled app=backend, so it will schedule only on such nodes.
  3. Final Answer:

    The pod will be scheduled on a node that already runs a pod with label app=backend -> Option C
  4. Quick Check:

    Required podAffinity = schedule near matching pods [OK]
Hint: Required podAffinity means schedule near matching pods [OK]
Common Mistakes:
  • Thinking podAffinity prevents scheduling near pods
  • Confusing required and preferred affinity
  • Assuming scheduling fails without matching pods
4. You wrote this anti-affinity rule but pods are still scheduled on the same node:
podAntiAffinity:
  requiredDuringSchedulingIgnoredDuringExecution:
  - labelSelector:
      matchLabels:
        app: database
    topologyKey: ""

What is the likely cause?
medium
A. Empty topologyKey causes the rule to be ignored
B. Label selector is incorrect syntax
C. Required rules are always ignored by scheduler
D. podAntiAffinity must be under preferredDuringSchedulingIgnoredDuringExecution

Solution

  1. Step 1: Check topologyKey usage

    The topologyKey must be a valid node label key like kubernetes.io/hostname. Empty string disables the rule.
  2. Step 2: Understand scheduler behavior

    With empty topologyKey, the scheduler ignores the anti-affinity rule, allowing pods on same node.
  3. Final Answer:

    Empty topologyKey causes the rule to be ignored -> Option A
  4. Quick Check:

    Valid topologyKey needed for anti-affinity [OK]
Hint: topologyKey cannot be empty for anti-affinity rules [OK]
Common Mistakes:
  • Leaving topologyKey empty
  • Misplacing anti-affinity under preferred instead of required
  • Assuming required rules are ignored
5. You want to deploy multiple replicas of a pod with label app: cache so that no two pods run on the same node, but you want the scheduler to try to keep pods in the same zone if possible. Which affinity configuration achieves this?
hard
A. Use podAffinity with requiredDuringSchedulingIgnoredDuringExecution on app: cache and topologyKey: kubernetes.io/hostname only
B. Use podAntiAffinity with requiredDuringSchedulingIgnoredDuringExecution on app: cache and topologyKey: kubernetes.io/hostname, plus podAffinity with preferredDuringSchedulingIgnoredDuringExecution on topologyKey: failure-domain.beta.kubernetes.io/zone
C. Use podAntiAffinity with preferredDuringSchedulingIgnoredDuringExecution on app: cache and topologyKey: kubernetes.io/hostname only
D. Use podAffinity with preferredDuringSchedulingIgnoredDuringExecution on app: cache and topologyKey: failure-domain.beta.kubernetes.io/zone only

Solution

  1. Step 1: Prevent pods on same node strictly

    Use podAntiAffinity with requiredDuringSchedulingIgnoredDuringExecution and topologyKey: kubernetes.io/hostname to ensure no two pods run on the same node.
  2. Step 2: Prefer pods in same zone

    Add podAffinity with preferredDuringSchedulingIgnoredDuringExecution and topologyKey: failure-domain.beta.kubernetes.io/zone to encourage scheduling pods in the same zone but not strictly.
  3. Step 3: Combine both rules

    Use podAntiAffinity with requiredDuringSchedulingIgnoredDuringExecution on app: cache and topologyKey: kubernetes.io/hostname, plus podAffinity with preferredDuringSchedulingIgnoredDuringExecution on topologyKey: failure-domain.beta.kubernetes.io/zone combines strict anti-affinity on node and preferred affinity on zone, matching the requirement.
  4. Final Answer:

    Use required podAntiAffinity on hostname and preferred podAffinity on zone -> Option B
  5. Quick Check:

    Strict anti-affinity + preferred affinity = Use podAntiAffinity with requiredDuringSchedulingIgnoredDuringExecution on app: cache and topologyKey: kubernetes.io/hostname, plus podAffinity with preferredDuringSchedulingIgnoredDuringExecution on topologyKey: failure-domain.beta.kubernetes.io/zone [OK]
Hint: Use required anti-affinity on node + preferred affinity on zone [OK]
Common Mistakes:
  • Using affinity instead of anti-affinity to separate pods
  • Using preferred instead of required for strict separation
  • Ignoring zone preference
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard