I am encountering a weird behavior when I try to attach podAffinity
to the Scheduler deployment from the official Airflow helm chart, like:
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- postgresql
topologyKey: "kubernetes.io/hostname"
With an example Deployment to which the podAffinity
should "hook up" to:
metadata:
name: {{ template "postgresql.fullname" . }}
labels:
app: postgresql
chart: {{ template "postgresql.chart" . }}
release: {{ .Release.Name | quote }}
heritage: {{ .Release.Service | quote }}
spec:
serviceName: {{ template "postgresql.fullname" . }}-headless
replicas: 1
selector:
matchLabels:
app: postgresql
release: {{ .Release.Name | quote }}
template:
metadata:
name: {{ template "postgresql.fullname" . }}
labels:
app: postgresql
chart: {{ template "postgresql.chart" . }}
Which results in:
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
However, applying the same podAffinity
config to the Webserver deployment works just fine. Plus, changing the example Deployment to a vanilla nginx manifested itself in the outcome.
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.
Has anyone encounter the same or has any idea what I might do wrong?
Setup:
Links to Airflow charts:
I've recreated this scenario on my GKE cluster and I've decided to provide a Community Wiki answer to show that the podAffinity on the Scheduler works as expected. I will describe step by step how I tested it below.
values.yaml
file, I've configured the podAffinity
as follows:$ cat values.yaml
...
# Airflow scheduler settings
scheduler: affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- postgresql
topologyKey: "kubernetes.io/hostname"
...
values.yaml
file specified.$ helm install airflow apache-airflow/airflow --values values.yaml
After a while we can check the status of the scheduler
:
$ kubectl get pods -owide | grep "scheduler"
airflow-scheduler-79bfb664cc-7n68f 0/2 Pending 0 8m6s <none> <none> <none> <none>
app: postgresql
label:$ 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,...
scheduler
was successfully created:$ kubectl get pods -o wide | grep "scheduler\|test"
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
Additionally, detailed informtion on pod affinity
and pod anti-affinity
can be found in the Understanding pod affinity documentation:
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.
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.
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.