diff --git a/cmd/k8s-operator/deploy/crds/tailscale.com_proxyclasses.yaml b/cmd/k8s-operator/deploy/crds/tailscale.com_proxyclasses.yaml
index cb9e0b991..516e75f48 100644
--- a/cmd/k8s-operator/deploy/crds/tailscale.com_proxyclasses.yaml
+++ b/cmd/k8s-operator/deploy/crds/tailscale.com_proxyclasses.yaml
@@ -1046,6 +1046,62 @@ spec:
type: object
additionalProperties:
type: string
+ dnsConfig:
+ description: |-
+ DNSConfig defines DNS parameters for the proxy Pod in addition to those generated from DNSPolicy.
+ When DNSPolicy is set to "None", DNSConfig must be specified.
+ https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/#pod-dns-config
+ type: object
+ properties:
+ nameservers:
+ description: |-
+ A list of DNS name server IP addresses.
+ This will be appended to the base nameservers generated from DNSPolicy.
+ Duplicated nameservers will be removed.
+ type: array
+ items:
+ type: string
+ x-kubernetes-list-type: atomic
+ options:
+ description: |-
+ A list of DNS resolver options.
+ This will be merged with the base options generated from DNSPolicy.
+ Duplicated entries will be removed. Resolution options given in Options
+ will override those that appear in the base DNSPolicy.
+ type: array
+ items:
+ description: PodDNSConfigOption defines DNS resolver options of a pod.
+ type: object
+ properties:
+ name:
+ description: |-
+ Name is this DNS resolver option's name.
+ Required.
+ type: string
+ value:
+ description: Value is this DNS resolver option's value.
+ type: string
+ x-kubernetes-list-type: atomic
+ searches:
+ description: |-
+ A list of DNS search domains for host-name lookup.
+ This will be appended to the base search paths generated from DNSPolicy.
+ Duplicated search paths will be removed.
+ type: array
+ items:
+ type: string
+ x-kubernetes-list-type: atomic
+ dnsPolicy:
+ description: |-
+ DNSPolicy defines how DNS will be configured for the proxy Pod.
+ By default the Tailscale Kubernetes Operator does not set a DNS policy (uses cluster default).
+ https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/#pod-s-dns-policy
+ type: string
+ enum:
+ - ClusterFirstWithHostNet
+ - ClusterFirst
+ - Default
+ - None
imagePullSecrets:
description: |-
Proxy Pod's image pull Secrets.
diff --git a/cmd/k8s-operator/deploy/manifests/operator.yaml b/cmd/k8s-operator/deploy/manifests/operator.yaml
index 9c19554aa..520d17eae 100644
--- a/cmd/k8s-operator/deploy/manifests/operator.yaml
+++ b/cmd/k8s-operator/deploy/manifests/operator.yaml
@@ -1574,6 +1574,62 @@ spec:
Annotations must be valid Kubernetes annotations.
https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/#syntax-and-character-set
type: object
+ dnsConfig:
+ description: |-
+ DNSConfig defines DNS parameters for the proxy Pod in addition to those generated from DNSPolicy.
+ When DNSPolicy is set to "None", DNSConfig must be specified.
+ https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/#pod-dns-config
+ properties:
+ nameservers:
+ description: |-
+ A list of DNS name server IP addresses.
+ This will be appended to the base nameservers generated from DNSPolicy.
+ Duplicated nameservers will be removed.
+ items:
+ type: string
+ type: array
+ x-kubernetes-list-type: atomic
+ options:
+ description: |-
+ A list of DNS resolver options.
+ This will be merged with the base options generated from DNSPolicy.
+ Duplicated entries will be removed. Resolution options given in Options
+ will override those that appear in the base DNSPolicy.
+ items:
+ description: PodDNSConfigOption defines DNS resolver options of a pod.
+ properties:
+ name:
+ description: |-
+ Name is this DNS resolver option's name.
+ Required.
+ type: string
+ value:
+ description: Value is this DNS resolver option's value.
+ type: string
+ type: object
+ type: array
+ x-kubernetes-list-type: atomic
+ searches:
+ description: |-
+ A list of DNS search domains for host-name lookup.
+ This will be appended to the base search paths generated from DNSPolicy.
+ Duplicated search paths will be removed.
+ items:
+ type: string
+ type: array
+ x-kubernetes-list-type: atomic
+ type: object
+ dnsPolicy:
+ description: |-
+ DNSPolicy defines how DNS will be configured for the proxy Pod.
+ By default the Tailscale Kubernetes Operator does not set a DNS policy (uses cluster default).
+ https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/#pod-s-dns-policy
+ enum:
+ - ClusterFirstWithHostNet
+ - ClusterFirst
+ - Default
+ - None
+ type: string
imagePullSecrets:
description: |-
Proxy Pod's image pull Secrets.
diff --git a/cmd/k8s-operator/sts.go b/cmd/k8s-operator/sts.go
index 80c9ca806..6300341b7 100644
--- a/cmd/k8s-operator/sts.go
+++ b/cmd/k8s-operator/sts.go
@@ -906,6 +906,12 @@ func applyProxyClassToStatefulSet(pc *tsapi.ProxyClass, ss *appsv1.StatefulSet,
ss.Spec.Template.Spec.Tolerations = wantsPod.Tolerations
ss.Spec.Template.Spec.PriorityClassName = wantsPod.PriorityClassName
ss.Spec.Template.Spec.TopologySpreadConstraints = wantsPod.TopologySpreadConstraints
+ if wantsPod.DNSPolicy != nil {
+ ss.Spec.Template.Spec.DNSPolicy = *wantsPod.DNSPolicy
+ }
+ if wantsPod.DNSConfig != nil {
+ ss.Spec.Template.Spec.DNSConfig = wantsPod.DNSConfig
+ }
// Update containers.
updateContainer := func(overlay *tsapi.Container, base corev1.Container) corev1.Container {
diff --git a/cmd/k8s-operator/sts_test.go b/cmd/k8s-operator/sts_test.go
index e2cb2962f..ea28e77a1 100644
--- a/cmd/k8s-operator/sts_test.go
+++ b/cmd/k8s-operator/sts_test.go
@@ -87,6 +87,15 @@ func Test_applyProxyClassToStatefulSet(t *testing.T) {
},
},
},
+ DNSPolicy: ptr.To(corev1.DNSClusterFirstWithHostNet),
+ DNSConfig: &corev1.PodDNSConfig{
+ Nameservers: []string{"1.1.1.1", "8.8.8.8"},
+ Searches: []string{"example.com", "test.local"},
+ Options: []corev1.PodDNSConfigOption{
+ {Name: "ndots", Value: ptr.To("2")},
+ {Name: "edns0"},
+ },
+ },
TailscaleContainer: &tsapi.Container{
SecurityContext: &corev1.SecurityContext{
Privileged: ptr.To(true),
@@ -200,6 +209,8 @@ func Test_applyProxyClassToStatefulSet(t *testing.T) {
wantSS.Spec.Template.Spec.InitContainers[0].Image = "ghcr.io/my-repo/tailscale:v0.01testsomething"
wantSS.Spec.Template.Spec.InitContainers[0].ImagePullPolicy = "IfNotPresent"
wantSS.Spec.Template.Spec.PriorityClassName = proxyClassAllOpts.Spec.StatefulSet.Pod.PriorityClassName
+ wantSS.Spec.Template.Spec.DNSPolicy = corev1.DNSClusterFirstWithHostNet
+ wantSS.Spec.Template.Spec.DNSConfig = proxyClassAllOpts.Spec.StatefulSet.Pod.DNSConfig
gotSS := applyProxyClassToStatefulSet(proxyClassAllOpts, nonUserspaceProxySS.DeepCopy(), new(tailscaleSTSConfig), zl.Sugar())
if diff := cmp.Diff(gotSS, wantSS); diff != "" {
@@ -239,6 +250,8 @@ func Test_applyProxyClassToStatefulSet(t *testing.T) {
wantSS.Spec.Template.Spec.Containers[0].ImagePullPolicy = "IfNotPresent"
wantSS.Spec.Template.Spec.Containers[0].Image = "ghcr.io/my-repo/tailscale:v0.01testsomething"
wantSS.Spec.Template.Spec.PriorityClassName = proxyClassAllOpts.Spec.StatefulSet.Pod.PriorityClassName
+ wantSS.Spec.Template.Spec.DNSPolicy = corev1.DNSClusterFirstWithHostNet
+ wantSS.Spec.Template.Spec.DNSConfig = proxyClassAllOpts.Spec.StatefulSet.Pod.DNSConfig
gotSS = applyProxyClassToStatefulSet(proxyClassAllOpts, userspaceProxySS.DeepCopy(), new(tailscaleSTSConfig), zl.Sugar())
if diff := cmp.Diff(gotSS, wantSS); diff != "" {
t.Errorf("Unexpected result applying ProxyClass with all options to a StatefulSet for a userspace proxy (-got +want):\n%s", diff)
diff --git a/k8s-operator/api.md b/k8s-operator/api.md
index b1c56c068..d75a21e37 100644
--- a/k8s-operator/api.md
+++ b/k8s-operator/api.md
@@ -537,6 +537,8 @@ _Appears in:_
| `tolerations` _[Toleration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.3/#toleration-v1-core) array_ | Proxy Pod's tolerations.
By default Tailscale Kubernetes operator does not apply any
tolerations.
https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#scheduling | | |
| `topologySpreadConstraints` _[TopologySpreadConstraint](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.3/#topologyspreadconstraint-v1-core) array_ | Proxy Pod's topology spread constraints.
By default Tailscale Kubernetes operator does not apply any topology spread constraints.
https://kubernetes.io/docs/concepts/scheduling-eviction/topology-spread-constraints/ | | |
| `priorityClassName` _string_ | PriorityClassName for the proxy Pod.
By default Tailscale Kubernetes operator does not apply any priority class.
https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#scheduling | | |
+| `dnsPolicy` _[DNSPolicy](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.3/#dnspolicy-v1-core)_ | DNSPolicy defines how DNS will be configured for the proxy Pod.
By default the Tailscale Kubernetes Operator does not set a DNS policy (uses cluster default).
https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/#pod-s-dns-policy | | Enum: [ClusterFirstWithHostNet ClusterFirst Default None]
|
+| `dnsConfig` _[PodDNSConfig](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.3/#poddnsconfig-v1-core)_ | DNSConfig defines DNS parameters for the proxy Pod in addition to those generated from DNSPolicy.
When DNSPolicy is set to "None", DNSConfig must be specified.
https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/#pod-dns-config | | |
#### PortRange
diff --git a/k8s-operator/apis/v1alpha1/types_proxyclass.go b/k8s-operator/apis/v1alpha1/types_proxyclass.go
index ea4e6a27c..4026f9084 100644
--- a/k8s-operator/apis/v1alpha1/types_proxyclass.go
+++ b/k8s-operator/apis/v1alpha1/types_proxyclass.go
@@ -303,6 +303,17 @@ type Pod struct {
// https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#scheduling
// +optional
PriorityClassName string `json:"priorityClassName,omitempty"`
+ // DNSPolicy defines how DNS will be configured for the proxy Pod.
+ // By default the Tailscale Kubernetes Operator does not set a DNS policy (uses cluster default).
+ // https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/#pod-s-dns-policy
+ // +kubebuilder:validation:Enum=ClusterFirstWithHostNet;ClusterFirst;Default;None
+ // +optional
+ DNSPolicy *corev1.DNSPolicy `json:"dnsPolicy,omitempty"`
+ // DNSConfig defines DNS parameters for the proxy Pod in addition to those generated from DNSPolicy.
+ // When DNSPolicy is set to "None", DNSConfig must be specified.
+ // https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/#pod-dns-config
+ // +optional
+ DNSConfig *corev1.PodDNSConfig `json:"dnsConfig,omitempty"`
}
// +kubebuilder:validation:XValidation:rule="!(has(self.serviceMonitor) && self.serviceMonitor.enable && !self.enable)",message="ServiceMonitor can only be enabled if metrics are enabled"
diff --git a/k8s-operator/apis/v1alpha1/zz_generated.deepcopy.go b/k8s-operator/apis/v1alpha1/zz_generated.deepcopy.go
index 3fd64c28e..5684fd5f8 100644
--- a/k8s-operator/apis/v1alpha1/zz_generated.deepcopy.go
+++ b/k8s-operator/apis/v1alpha1/zz_generated.deepcopy.go
@@ -574,6 +574,16 @@ func (in *Pod) DeepCopyInto(out *Pod) {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
+ if in.DNSPolicy != nil {
+ in, out := &in.DNSPolicy, &out.DNSPolicy
+ *out = new(corev1.DNSPolicy)
+ **out = **in
+ }
+ if in.DNSConfig != nil {
+ in, out := &in.DNSConfig, &out.DNSConfig
+ *out = new(corev1.PodDNSConfig)
+ (*in).DeepCopyInto(*out)
+ }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Pod.