cmd/k8s-operator: add nodeSelector to DNSConfig resource (#19429)

This commit modifies the `DNSConfig` resource to allow customisation of
the `spec.nodeSelector` field in the nameserver pods.

Closes: https://github.com/tailscale/tailscale/issues/19419

Signed-off-by: David Bond <davidsbond93@gmail.com>
This commit is contained in:
David Bond 2026-04-29 15:56:33 +01:00 committed by GitHub
parent 4cec06b8f2
commit a29e42135b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 39 additions and 9 deletions

View File

@ -977,6 +977,11 @@ spec:
Empty topologyKey is not allowed.
type: string
x-kubernetes-list-type: atomic
nodeSelector:
description: If specified, applies node selector rules to the pods deployed by the DNSConfig resource.
type: object
additionalProperties:
type: string
tolerations:
description: If specified, applies tolerations to the pods deployed by the DNSConfig resource.
type: array

View File

@ -1315,6 +1315,11 @@ spec:
x-kubernetes-list-type: atomic
type: object
type: object
nodeSelector:
additionalProperties:
type: string
description: If specified, applies node selector rules to the pods deployed by the DNSConfig resource.
type: object
tolerations:
description: If specified, applies tolerations to the pods deployed by the DNSConfig resource.
items:

View File

@ -191,6 +191,7 @@ func (a *NameserverReconciler) maybeProvision(ctx context.Context, tsDNSCfg *tsa
if tsDNSCfg.Spec.Nameserver.Pod != nil {
dCfg.tolerations = tsDNSCfg.Spec.Nameserver.Pod.Tolerations
dCfg.affinity = tsDNSCfg.Spec.Nameserver.Pod.Affinity
dCfg.nodeSelector = tsDNSCfg.Spec.Nameserver.Pod.NodeSelector
}
for _, deployable := range []deployable{saDeployable, deployDeployable, svcDeployable, cmDeployable} {
@ -218,15 +219,16 @@ type deployable struct {
}
type deployConfig struct {
replicas int32
imageRepo string
imageTag string
labels map[string]string
ownerRefs []metav1.OwnerReference
namespace string
clusterIP string
tolerations []corev1.Toleration
affinity *corev1.Affinity
replicas int32
imageRepo string
imageTag string
labels map[string]string
ownerRefs []metav1.OwnerReference
namespace string
clusterIP string
tolerations []corev1.Toleration
affinity *corev1.Affinity
nodeSelector map[string]string
}
var (
@ -253,6 +255,7 @@ var (
d.ObjectMeta.OwnerReferences = cfg.ownerRefs
d.Spec.Template.Spec.Tolerations = cfg.tolerations
d.Spec.Template.Spec.Affinity = cfg.affinity
d.Spec.Template.Spec.NodeSelector = cfg.nodeSelector
updateF := func(oldD *appsv1.Deployment) {
oldD.Spec = d.Spec
}

View File

@ -43,6 +43,9 @@ func TestNameserverReconciler(t *testing.T) {
ClusterIP: "5.4.3.2",
},
Pod: &tsapi.NameserverPod{
NodeSelector: map[string]string{
"foo": "bar",
},
Tolerations: []corev1.Toleration{
{
Key: "some-key",
@ -131,6 +134,9 @@ func TestNameserverReconciler(t *testing.T) {
},
},
}
wantsDeploy.Spec.Template.Spec.NodeSelector = map[string]string{
"foo": "bar",
}
expectEqual(t, fc, wantsDeploy)
})

View File

@ -484,6 +484,7 @@ _Appears in:_
| --- | --- | --- | --- |
| `tolerations` _[Toleration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.3/#toleration-v1-core) array_ | If specified, applies tolerations to the pods deployed by the DNSConfig resource. | | |
| `affinity` _[Affinity](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.3/#affinity-v1-core)_ | If specified, applies affinity rules to the pods deployed by the DNSConfig resource. | | |
| `nodeSelector` _object (keys:string, values:string)_ | If specified, applies node selector rules to the pods deployed by the DNSConfig resource. | | |
#### NameserverService

View File

@ -116,6 +116,9 @@ type NameserverPod struct {
// If specified, applies affinity rules to the pods deployed by the DNSConfig resource.
// +optional
Affinity *corev1.Affinity `json:"affinity,omitzero"`
// If specified, applies node selector rules to the pods deployed by the DNSConfig resource.
// +optional
NodeSelector map[string]string `json:"nodeSelector,omitzero"`
}
type DNSConfigStatus struct {

View File

@ -474,6 +474,13 @@ func (in *NameserverPod) DeepCopyInto(out *NameserverPod) {
*out = new(corev1.Affinity)
(*in).DeepCopyInto(*out)
}
if in.NodeSelector != nil {
in, out := &in.NodeSelector, &out.NodeSelector
*out = make(map[string]string, len(*in))
for key, val := range *in {
(*out)[key] = val
}
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NameserverPod.