Pod AntiAffinity: can it tolerates different pod versions?

10/19/2017

Here is my setup:

  • 2 nodes
  • 2 pods of the same app
  • deployment settings allow a surge of 1 pod

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"
-- Finch_Powers
kubernetes

1 Answer

10/20/2017

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").

-- Aaron Levy
Source: StackOverflow