This workshop has been deprecated and archived. The new Amazon EKS Workshop is now available at www.eksworkshop.com.
AntiAffinity
can be even more useful when they are used with higher level collections such as ReplicaSets
, StatefulSets
, Deployments
, etc. One can easily configure a set of workloads to be co-located in the same defined topology, eg., the same node.
In a three-node cluster, a web application has an in-memory cache such as redis. We want the web-servers to be co-located with the cache whenever possible.
Here is the YAML snippet of a simple redis deployment with three replicas and selector label app=store
. The deployment has PodAntiAffinity
configured to ensure the scheduler does not co-locate replicas on a single node.
cat <<EoF > ~/environment/redis-with-node-affinity.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis-cache
spec:
selector:
matchLabels:
app: store
replicas: 3
template:
metadata:
labels:
app: store
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- store
topologyKey: "kubernetes.io/hostname"
containers:
- name: redis-server
image: redis:3.2-alpine
EoF
The below YAML snippet of the web-server deployment has podAntiAffinity
and podAffinity
configured. This informs the scheduler that all its replicas are to be co-located with pods that have selector label app=store
. This will also ensure that each web-server replica does not co-locate on a single node.
cat <<EoF > ~/environment/web-with-node-affinity.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-server
spec:
selector:
matchLabels:
app: web-store
replicas: 3
template:
metadata:
labels:
app: web-store
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- web-store
topologyKey: "kubernetes.io/hostname"
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- store
topologyKey: "kubernetes.io/hostname"
containers:
- name: web-app
image: nginx:1.12-alpine
EoF
Let’s apply these Deployments:
kubectl apply -f ~/environment/redis-with-node-affinity.yaml
kubectl apply -f ~/environment/web-with-node-affinity.yaml
When we create the above two deployments, our three node cluster should look like:
node-1 - webserver-1 - cache-1
node-2 - webserver-2 - cache-2
node-3 - webserver-3 - cache-3
As you can see, all 3 web-server pod replicas are automatically co-located with the redis cache pods as expected.
# We will use --sort-by to filter by nodes name
kubectl get pods -o wide --sort-by='.spec.nodeName'