Skip to content

Commit 8e028f9

Browse files
committed
Propagate NodeSelector and Tolerations to Affinity Assistant
To be able to run Tekton workload on a subset of the Nodes in a cluster, a NodeSelector or Tolerations can be set on the pods, e.g. by specifying a custom PodTemplate. When using the Affinity Assistant, this was not supported to customize. This commit, also propagate NodeSelector and Tolerations to the Affinity Assistant pod, so that Tekton workload can be kept to a subset of the Nodes in a cluster, also when using the Affinity Assistant. Fixes #2742 /kind feature
1 parent 49828a1 commit 8e028f9

File tree

4 files changed

+67
-4
lines changed

4 files changed

+67
-4
lines changed

docs/install.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,7 @@ The example below customizes the following:
245245
- the default timeout from 60 minutes to 20 minutes.
246246
- the default `app.kubernetes.io/managed-by` label is applied to all Pods created to execute `TaskRuns`.
247247
- the default Pod template to include a node selector to select the node where the Pod will be scheduled by default.
248-
For more information, see [`PodTemplate` in `TaskRuns`](./taskruns.md#pod-template) or [`PodTemplate` in `PipelineRuns`](./pipelineruns.md#pod-template).
248+
For more information, see [`PodTemplate` in `TaskRuns`](./taskruns.md#specifying-a-pod-template) or [`PodTemplate` in `PipelineRuns`](./pipelineruns.md#specifying-a-pod-template).
249249

250250
```yaml
251251
apiVersion: v1
@@ -270,7 +270,7 @@ To customize the behavior of the Pipelines Controller, modify the ConfigMap `fea
270270

271271
- `disable-affinity-assistant` - set this flag to disable the [Affinity Assistant](./workspaces.md#affinity-assistant-and-specifying-workspace-order-in-a-pipeline)
272272
that is used to provide Node Affinity for `TaskRun` pods that share workspace volume.
273-
The Affinity Assistant pods may be incompatible with NodeSelector and other affinity rules
273+
The Affinity Assistant is incompatible with other affinity rules
274274
configured for `TaskRun` pods.
275275

276276
**Note:** Affinity Assistant use [Inter-pod affinity and anti-affinity](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#inter-pod-affinity-and-anti-affinity)

docs/workspaces.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ When a `PersistentVolumeClaim` is used as volume source for a `Workspace` in a `
215215
an Affinity Assistant will be created. The Affinity Assistant acts as a placeholder for `TaskRun` pods
216216
sharing the same `Workspace`. All `TaskRun` pods within the `PipelineRun` that share the `Workspace`
217217
will be scheduled to the same Node as the Affinity Assistant pod. This means that Affinity Assistant is incompatible
218-
with e.g. NodeSelectors or other affinity rules configured for the `TaskRun` pods. The Affinity Assistant
218+
with e.g. other affinity rules configured for the `TaskRun` pods. The Affinity Assistant
219219
is deleted when the `PipelineRun` is completed. The Affinity Assistant can be disabled by setting the
220220
[disable-affinity-assistant](install.md#customizing-basic-execution-parameters) feature gate.
221221

pkg/reconciler/pipelinerun/affinity_assistant.go

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,18 @@ func affinityAssistantStatefulSet(name string, pr *v1beta1.PipelineRun, claimNam
117117
// We want a singleton pod
118118
replicas := int32(1)
119119

120+
// use tolerations from default podTemplate if specified
121+
var tolerations []corev1.Toleration
122+
if pr.Spec.PodTemplate != nil {
123+
tolerations = pr.Spec.PodTemplate.Tolerations
124+
}
125+
126+
// use nodeSelector from default podTemplate if specified
127+
var nodeSelector map[string]string
128+
if pr.Spec.PodTemplate != nil {
129+
nodeSelector = pr.Spec.PodTemplate.NodeSelector
130+
}
131+
120132
containers := []corev1.Container{{
121133
Name: "affinity-assistant",
122134

@@ -171,7 +183,9 @@ func affinityAssistantStatefulSet(name string, pr *v1beta1.PipelineRun, claimNam
171183
Labels: getStatefulSetLabels(pr, name),
172184
},
173185
Spec: corev1.PodSpec{
174-
Containers: containers,
186+
Containers: containers,
187+
Tolerations: tolerations,
188+
NodeSelector: nodeSelector,
175189
Affinity: &corev1.Affinity{
176190
PodAntiAffinity: &corev1.PodAntiAffinity{
177191
PreferredDuringSchedulingIgnoredDuringExecution: []corev1.WeightedPodAffinityTerm{repelOtherAffinityAssistantsPodAffinityTerm},

pkg/reconciler/pipelinerun/affinity_assistant_test.go

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,55 @@ func TestCreateAndDeleteOfAffinityAssistant(t *testing.T) {
8282
}
8383
}
8484

85+
func TestThatTolerationsAndNodeSelectorIsPropagatedToAffinityAssistant(t *testing.T) {
86+
prWithCustomPodTemplate := &v1beta1.PipelineRun{
87+
TypeMeta: metav1.TypeMeta{Kind: "PipelineRun"},
88+
ObjectMeta: metav1.ObjectMeta{
89+
Name: "pipelinerun-with-custom-podtemplate",
90+
},
91+
Spec: v1beta1.PipelineRunSpec{
92+
PodTemplate: &v1beta1.PodTemplate{
93+
NodeSelector: map[string]string{
94+
"disktype": "ssd",
95+
},
96+
Tolerations: []corev1.Toleration{{
97+
Key: "key",
98+
Operator: "Equal",
99+
Value: "value",
100+
Effect: "NoSchedule",
101+
}},
102+
},
103+
},
104+
}
105+
106+
prWithoutCustomPodTemplate := &v1beta1.PipelineRun{
107+
TypeMeta: metav1.TypeMeta{Kind: "PipelineRun"},
108+
ObjectMeta: metav1.ObjectMeta{
109+
Name: "pipelinerun-without-custom-podtemplate",
110+
},
111+
Spec: v1beta1.PipelineRunSpec{},
112+
}
113+
114+
stsWithTolerationsAndNodeSelector := affinityAssistantStatefulSet("test-assistant", prWithCustomPodTemplate, "mypvc")
115+
stsWithoutTolerationsAndNodeSelector := affinityAssistantStatefulSet("test-assistant", prWithoutCustomPodTemplate, "mypvc")
116+
117+
if len(stsWithTolerationsAndNodeSelector.Spec.Template.Spec.NodeSelector) != 1 {
118+
t.Errorf("expected a NodeSelector in the StatefulSet")
119+
}
120+
121+
if len(stsWithTolerationsAndNodeSelector.Spec.Template.Spec.Tolerations) != 1 {
122+
t.Errorf("expected Tolerations in the StatefulSet")
123+
}
124+
125+
if len(stsWithoutTolerationsAndNodeSelector.Spec.Template.Spec.NodeSelector) != 0 {
126+
t.Errorf("unexpected NodeSelector in the StatefulSet")
127+
}
128+
129+
if len(stsWithoutTolerationsAndNodeSelector.Spec.Template.Spec.Tolerations) != 0 {
130+
t.Errorf("unexpected Tolerations in the StatefulSet")
131+
}
132+
}
133+
85134
func TestDisableAffinityAssistant(t *testing.T) {
86135
for _, tc := range []struct {
87136
description string

0 commit comments

Comments
 (0)