<p>I am encountering a weird behavior when I try to attach <code>podAffinity</code> to the <strong>Scheduler deployment from the official Airflow helm chart</strong>, like:</p>
<pre><code>  affinity:
    podAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - key: app 
            operator: In
            values:
            - postgresql
        topologyKey: &quot;kubernetes.io/hostname&quot;
</code></pre>
<p>With an example Deployment to which the <code>podAffinity</code> should &quot;hook up&quot; to:</p>
<pre><code>metadata:
  name: {{ template &quot;postgresql.fullname&quot; . }}
  labels:
    app: postgresql
    chart: {{ template &quot;postgresql.chart&quot; . }}
    release: {{ .Release.Name | quote }}
    heritage: {{ .Release.Service | quote }}
spec:
  serviceName: {{ template &quot;postgresql.fullname&quot; . }}-headless
  replicas: 1
  selector:
    matchLabels:
      app: postgresql
      release: {{ .Release.Name | quote }}
  template:
    metadata:
      name: {{ template &quot;postgresql.fullname&quot; . }}
      labels:
        app: postgresql
        chart: {{ template &quot;postgresql.chart&quot; . }}

</code></pre>
<p>Which results in:</p>
<pre><code>NotTriggerScaleUp: pod didn't trigger scale-up: 1 node(s) didn't match pod affinity/anti-affinity, 1 node(s) didn't match pod affinity rules
</code></pre>
<p><strong>However, applying the same <code>podAffinity</code> config to the Webserver deployment works just fine. Plus, changing the example Deployment to a vanilla nginx manifested itself in the outcome.</strong></p>
<p>It does not seem to be any resource limitation issue since I already tried various configs, every time with the same result.
I do not use any custom configurations apart from node affinity.</p>
<p>Has anyone encounter the same or has any idea what I might do wrong?</p>
<p><strong>Setup:</strong></p>
<ul>
<li>AKS cluster</li>
<li>Airflow helm chart 1.1.0</li>
<li>Airflow 1.10.15 (but I don't think this matters)</li>
<li>kubectl client (1.22.1) and server (1.20.7)</li>
</ul>
<p><strong>Links to Airflow charts:</strong></p>
<ul>
<li><a href="https://github.com/apache/airflow/blob/main/chart/templates/scheduler/scheduler-deployment.yaml" rel="nofollow noreferrer">Scheduler</a></li>
<li><a href="https://github.com/apache/airflow/blob/main/chart/templates/webserver/webserver-deployment.yaml" rel="nofollow noreferrer">Webserver</a></li>
</ul>

<p>I've recreated this scenario on my GKE cluster and I've decided to provide a Community Wiki answer to show that the <a href="https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#inter-pod-affinity-and-anti-affinity" rel="nofollow noreferrer">podAffinity</a> on the <a href="https://github.com/apache/airflow/blob/main/chart/templates/scheduler/scheduler-deployment.yaml" rel="nofollow noreferrer">Scheduler</a> works as expected.
I will describe step by step how I tested it below.</p>
<hr />
<ol>
<li>In the <code>values.yaml</code> file, I've configured the <code>podAffinity</code> as follows:</li>
</ol>
<pre><code>$ cat values.yaml
...
# Airflow scheduler settings
scheduler:  affinity:
    podAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - key: app
            operator: In
            values:
            - postgresql
        topologyKey: &quot;kubernetes.io/hostname&quot;
...
</code></pre>
<ol start="2">
<li>I've installed the <a href="https://airflow.apache.org/docs/helm-chart/stable/index.html#installing-the-chart" rel="nofollow noreferrer">Airflow</a> on a Kubernetes cluster using the Helm package manager with the <code>values.yaml</code> file specified.</li>
</ol>
<pre><code>$ helm install airflow apache-airflow/airflow --values values.yaml
</code></pre>
<p>After a while we can check the status of the <code>scheduler</code>:</p>
<pre><code>$ kubectl get pods -owide | grep &quot;scheduler&quot;
airflow-scheduler-79bfb664cc-7n68f   0/2     Pending   0          8m6s   &lt;none&gt;      &lt;none&gt;                                 &lt;none&gt;           &lt;none&gt;
</code></pre>
<ol start="3">
<li>I've created an example Deployment with the <code>app: postgresql</code> label:</li>
</ol>
<pre><code>$ cat test.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: postgresql
  name: test
spec:
  replicas: 1
  selector:
    matchLabels:
      app: postgresql
  template:
    metadata:
      labels:
        app: postgresql
    spec:
      containers:
      - image: nginx
        name: nginx
        
$ kubectl apply -f test.yaml
deployment.apps/test created

$ kubectl get pods --show-labels | grep test
test-7d4c9c654-7lqns                 1/1     Running   0          2m   app=postgresql,...
</code></pre>
<ol start="4">
<li>Finally, we can check that the <code>scheduler</code> was successfully created:</li>
</ol>
<pre><code>$ kubectl get pods -o wide | grep &quot;scheduler\|test&quot;
airflow-scheduler-79bfb664cc-7n68f   2/2     Running   0          14m     10.X.1.6    nodeA     
test-7d4c9c654-7lqns                 1/1     Running   0          2m27s   10.X.1.5    nodeA
</code></pre>
<hr />
<p>Additionally, detailed informtion on <code>pod affinity</code> and <code>pod anti-affinity</code> can be found in the <a href="https://docs.openshift.com/container-platform/4.9/nodes/scheduling/nodes-scheduler-pod-affinity.html#nodes-scheduler-pod-affinity-about_nodes-scheduler-pod-affinity" rel="nofollow noreferrer">Understanding pod affinity</a> documentation:</p>
<blockquote>
<p>Pod affinity and pod anti-affinity allow you to constrain which nodes your pod is eligible to be scheduled on based on the key/value labels on other pods.</p>
<p>Pod affinity 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.</p>
<p>Pod anti-affinity 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.</p>
</blockquote>
