mirror of
https://github.com/tailscale/tailscale.git
synced 2025-10-03 19:41:34 +02:00
cmd/k8s-operator: add DNS policy and config support to ProxyClass (#16887)
DNS configuration support to ProxyClass, allowing users to customize DNS resolution for Tailscale proxy pods. Fixes #16886 Signed-off-by: Raj Singh <raj@tailscale.com>
This commit is contained in:
parent
9aa16bf97b
commit
a45473c4c5
@ -1046,6 +1046,62 @@ spec:
|
|||||||
type: object
|
type: object
|
||||||
additionalProperties:
|
additionalProperties:
|
||||||
type: string
|
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:
|
imagePullSecrets:
|
||||||
description: |-
|
description: |-
|
||||||
Proxy Pod's image pull Secrets.
|
Proxy Pod's image pull Secrets.
|
||||||
|
@ -1574,6 +1574,62 @@ spec:
|
|||||||
Annotations must be valid Kubernetes annotations.
|
Annotations must be valid Kubernetes annotations.
|
||||||
https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/#syntax-and-character-set
|
https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/#syntax-and-character-set
|
||||||
type: object
|
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:
|
imagePullSecrets:
|
||||||
description: |-
|
description: |-
|
||||||
Proxy Pod's image pull Secrets.
|
Proxy Pod's image pull Secrets.
|
||||||
|
@ -906,6 +906,12 @@ func applyProxyClassToStatefulSet(pc *tsapi.ProxyClass, ss *appsv1.StatefulSet,
|
|||||||
ss.Spec.Template.Spec.Tolerations = wantsPod.Tolerations
|
ss.Spec.Template.Spec.Tolerations = wantsPod.Tolerations
|
||||||
ss.Spec.Template.Spec.PriorityClassName = wantsPod.PriorityClassName
|
ss.Spec.Template.Spec.PriorityClassName = wantsPod.PriorityClassName
|
||||||
ss.Spec.Template.Spec.TopologySpreadConstraints = wantsPod.TopologySpreadConstraints
|
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.
|
// Update containers.
|
||||||
updateContainer := func(overlay *tsapi.Container, base corev1.Container) corev1.Container {
|
updateContainer := func(overlay *tsapi.Container, base corev1.Container) corev1.Container {
|
||||||
|
@ -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{
|
TailscaleContainer: &tsapi.Container{
|
||||||
SecurityContext: &corev1.SecurityContext{
|
SecurityContext: &corev1.SecurityContext{
|
||||||
Privileged: ptr.To(true),
|
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].Image = "ghcr.io/my-repo/tailscale:v0.01testsomething"
|
||||||
wantSS.Spec.Template.Spec.InitContainers[0].ImagePullPolicy = "IfNotPresent"
|
wantSS.Spec.Template.Spec.InitContainers[0].ImagePullPolicy = "IfNotPresent"
|
||||||
wantSS.Spec.Template.Spec.PriorityClassName = proxyClassAllOpts.Spec.StatefulSet.Pod.PriorityClassName
|
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())
|
gotSS := applyProxyClassToStatefulSet(proxyClassAllOpts, nonUserspaceProxySS.DeepCopy(), new(tailscaleSTSConfig), zl.Sugar())
|
||||||
if diff := cmp.Diff(gotSS, wantSS); diff != "" {
|
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].ImagePullPolicy = "IfNotPresent"
|
||||||
wantSS.Spec.Template.Spec.Containers[0].Image = "ghcr.io/my-repo/tailscale:v0.01testsomething"
|
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.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())
|
gotSS = applyProxyClassToStatefulSet(proxyClassAllOpts, userspaceProxySS.DeepCopy(), new(tailscaleSTSConfig), zl.Sugar())
|
||||||
if diff := cmp.Diff(gotSS, wantSS); diff != "" {
|
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)
|
t.Errorf("Unexpected result applying ProxyClass with all options to a StatefulSet for a userspace proxy (-got +want):\n%s", diff)
|
||||||
|
@ -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.<br />By default Tailscale Kubernetes operator does not apply any<br />tolerations.<br />https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#scheduling | | |
|
| `tolerations` _[Toleration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.3/#toleration-v1-core) array_ | Proxy Pod's tolerations.<br />By default Tailscale Kubernetes operator does not apply any<br />tolerations.<br />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.<br />By default Tailscale Kubernetes operator does not apply any topology spread constraints.<br />https://kubernetes.io/docs/concepts/scheduling-eviction/topology-spread-constraints/ | | |
|
| `topologySpreadConstraints` _[TopologySpreadConstraint](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.3/#topologyspreadconstraint-v1-core) array_ | Proxy Pod's topology spread constraints.<br />By default Tailscale Kubernetes operator does not apply any topology spread constraints.<br />https://kubernetes.io/docs/concepts/scheduling-eviction/topology-spread-constraints/ | | |
|
||||||
| `priorityClassName` _string_ | PriorityClassName for the proxy Pod.<br />By default Tailscale Kubernetes operator does not apply any priority class.<br />https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#scheduling | | |
|
| `priorityClassName` _string_ | PriorityClassName for the proxy Pod.<br />By default Tailscale Kubernetes operator does not apply any priority class.<br />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.<br />By default the Tailscale Kubernetes Operator does not set a DNS policy (uses cluster default).<br />https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/#pod-s-dns-policy | | Enum: [ClusterFirstWithHostNet ClusterFirst Default None] <br /> |
|
||||||
|
| `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.<br />When DNSPolicy is set to "None", DNSConfig must be specified.<br />https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/#pod-dns-config | | |
|
||||||
|
|
||||||
|
|
||||||
#### PortRange
|
#### PortRange
|
||||||
|
@ -303,6 +303,17 @@ type Pod struct {
|
|||||||
// https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#scheduling
|
// https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#scheduling
|
||||||
// +optional
|
// +optional
|
||||||
PriorityClassName string `json:"priorityClassName,omitempty"`
|
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"
|
// +kubebuilder:validation:XValidation:rule="!(has(self.serviceMonitor) && self.serviceMonitor.enable && !self.enable)",message="ServiceMonitor can only be enabled if metrics are enabled"
|
||||||
|
@ -574,6 +574,16 @@ func (in *Pod) DeepCopyInto(out *Pod) {
|
|||||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
(*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.
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Pod.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user