Here is my setup:
My problem: I don't want 2 pods of the same app/version to run on the same node. That can be done with AntiAffinity, but when I deploy a new version, it attempts to add a 3rd pod (the surge pod) and it fails because of the AntiAffinity setting and because there are only 2 nodes.
The question: Can I fine tune AntiAffinity to allow pods of the same app but different version to run on the same node?
Below is the spec that reflects my setup.
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: my-app
spec:
replicas: 2
minReadySeconds: 10
strategy:
rollingUpdate:
maxUnavailable: 0
maxSurge: 1
template:
metadata:
labels:
app: my-app
...
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: "app"
operator: In
values:
- my-app
topologyKey: "kubernetes.io/hostname"
You can, but it requires modifying a label as part of the "new version":
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
pod-version-anti-affinity: my-app-v1
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchLabels:
pod-version-anti-affinity: my-app-v1
topologyKey: kubernetes.io/hostname
This means that the selector for the Deployment is only looking at "my-app" which will be consistent across all "versions" of your application.
However, the pod itself also contains another label that is specific to its "version". This means the anti-affinity rule can just target that specific label, which will allow different versions of the same app to be co-located on the node during a rolling upgrade.
You just need to know that when you're deploying a new version, you modify the label in the template & affinity (e.g. to "-v2").