Balanced Kubernetes Deployment With podAntiAffinity

Sreejith V U
3 min readMay 20, 2020

--

Scenario:

“You have a multizone cluster and you need high availability of the application which is deployed”.

Normally we can do deployments of pods into nodes but we cannot guarentee that each node have atleast one pod running.

Solution:

One of the simplest method is to use the podAntiAffinity feature.

podAffinity can tell the scheduler to locate a new pod on the same node as other pods if the label selector on the new pod matches the label on the current pod.

podAntiAffinity can prevent the scheduler from locating a new pod on the same node as pods with the same labels if the label selector on the new pod matches the label on the current pod.

weight can be any value from 1 to 100. The weight number gives the matching node a relatively higher weight than other nodes.The more you want your preference to be fulfilled, set weight to a higher value.

topology can be defined as node labels

With requiredDuringSchedulingIgnoredDuringExecution (HARD) in the deployment, only one pod will be deployed to each node, the next pods will be in pending state.

And with preferredDuringSchedulingIgnoredDuringExecution (SOFT) and weight in the deployment we can deploy pods which will get evenly distributed among nodes.

So, a rule of podAntiAffinity with SOFT scheduling will do the task here!. Lets go through deployment file.

Below is a sample deployment file which used podAntiAffinity with a replica count of 3.

Deployment with soft podAntiAffinity:

apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
run: nginx
name: nginx
spec:
replicas: 3
selector:
matchLabels:
run: nginx
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
run: nginx
spec:
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- podAffinityTerm:
labelSelector:
matchExpressions:
- key: run
operator: In
values:
- nginx
topologyKey: kubernetes.io/hostname
weight: 100
containers:
- image: nginx
name: nginx
resources:
limits:
memory: "200Mi"
cpu: "200m"
requests:
memory: "100Mi"
cpu: "100m"
status: {}

This rule ensures that two pods with the key run equals nginx must not run in the same node.

I have deployed this deployment to a 3 master node HA cluster.

Result:

As you can see each pod is deployed to each k8’s node.

What happens while scaling the deployment?

Now we will see if this approach works fine with scaling of nodes.

kubectl scale deployment nginx --replicas=6

I have scaled the pods with 6 replicas.

Result:

As you can see the next set of pods also got distributed evenly over the nodes. Each node have 2 pods of nginx.

What happens if HPA (Horizontal Pod Scaling) is configured for this deployment?

Lets see if this works with horizontal pod scaling. I have configured HPA and created a load generator pod. Now as you can see the newly launched pods are successfully distributed among the nodes.

Result:

I hope this post has helped you to understand about podAffinity and how it works. Ultimately a easy solution for high availability of deployments.

--

--