From 8a21cb25331839a062ae58d8ad9b5c2c7bd75a29 Mon Sep 17 00:00:00 2001 From: Erik Karsten Date: Thu, 13 Jun 2024 16:40:04 +0300 Subject: [PATCH] feat: support configuring nodeSelectors and tolerations for tunnel resources (#98) * feat: implement nodeSelector and tolerations to tunnel.spec * gen: kubebuilder auto-generated changes * fix: remove unnecessary log line * fix: build with controller-gen v0.7.0 --- api/v1alpha1/tunnel_types.go | 9 ++++ api/v1alpha1/zz_generated.deepcopy.go | 20 ++++++-- ...rking.cfargotunnel.com_clustertunnels.yaml | 47 +++++++++++++++++++ .../networking.cfargotunnel.com_tunnels.yaml | 47 +++++++++++++++++++ controllers/reconciler.go | 10 +++- 5 files changed, 129 insertions(+), 4 deletions(-) diff --git a/api/v1alpha1/tunnel_types.go b/api/v1alpha1/tunnel_types.go index abcfa8a..0354e12 100644 --- a/api/v1alpha1/tunnel_types.go +++ b/api/v1alpha1/tunnel_types.go @@ -17,6 +17,7 @@ limitations under the License. package v1alpha1 import ( + corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -104,6 +105,14 @@ type TunnelSpec struct { // OriginCaPool speficies the secret with tls.crt (and other certs as needed to be referred in the service annotation) of the Root CA to be trusted when sending traffic to HTTPS endpoints OriginCaPool string `json:"originCaPool,omitempty"` + //+kubebuilder:validation:Optional + // NodeSelectors specifies the nodeSelectors to apply to the cloudflared tunnel deployment + NodeSelectors map[string]string `json:"nodeSelectors,omitempty"` + + //+kubebuilder:validation:Optional + // Tolerations specifies the tolerations to apply to the cloudflared tunnel deployment + Tolerations []corev1.Toleration `json:"tolerations,omitempty"` + //+kubebuilder:validation:Optional //+kubebuilder:default:="http_status:404" // FallbackTarget speficies the target for requests that do not match an ingress. Defaults to http_status:404 diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index 153967f..a339515 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -1,5 +1,4 @@ //go:build !ignore_autogenerated -// +build !ignore_autogenerated /* Copyright 2022. @@ -22,6 +21,7 @@ limitations under the License. package v1alpha1 import ( + "k8s.io/api/core/v1" runtime "k8s.io/apimachinery/pkg/runtime" ) @@ -45,7 +45,7 @@ func (in *ClusterTunnel) DeepCopyInto(out *ClusterTunnel) { *out = *in out.TypeMeta = in.TypeMeta in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - out.Spec = in.Spec + in.Spec.DeepCopyInto(&out.Spec) out.Status = in.Status } @@ -149,7 +149,7 @@ func (in *Tunnel) DeepCopyInto(out *Tunnel) { *out = *in out.TypeMeta = in.TypeMeta in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - out.Spec = in.Spec + in.Spec.DeepCopyInto(&out.Spec) out.Status = in.Status } @@ -336,6 +336,20 @@ func (in *TunnelRef) DeepCopy() *TunnelRef { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *TunnelSpec) DeepCopyInto(out *TunnelSpec) { *out = *in + if in.NodeSelectors != nil { + in, out := &in.NodeSelectors, &out.NodeSelectors + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.Tolerations != nil { + in, out := &in.Tolerations, &out.Tolerations + *out = make([]v1.Toleration, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } out.Cloudflare = in.Cloudflare out.ExistingTunnel = in.ExistingTunnel out.NewTunnel = in.NewTunnel diff --git a/config/crd/bases/networking.cfargotunnel.com_clustertunnels.yaml b/config/crd/bases/networking.cfargotunnel.com_clustertunnels.yaml index f010307..6a34d00 100644 --- a/config/crd/bases/networking.cfargotunnel.com_clustertunnels.yaml +++ b/config/crd/bases/networking.cfargotunnel.com_clustertunnels.yaml @@ -124,6 +124,12 @@ spec: description: NoTlsVerify disables origin TLS certificate checks when the endpoint is HTTPS. type: boolean + nodeSelectors: + additionalProperties: + type: string + description: NodeSelectors specifies the nodeSelectors to apply to + the cloudflared tunnel deployment + type: object originCaPool: description: OriginCaPool speficies the secret with tls.crt (and other certs as needed to be referred in the service annotation) of the @@ -136,6 +142,47 @@ spec: format: int32 minimum: 0 type: integer + tolerations: + description: Tolerations specifies the tolerations to apply to the + cloudflared tunnel deployment + items: + description: The pod this Toleration is attached to tolerates any + taint that matches the triple using the matching + operator . + properties: + effect: + description: Effect indicates the taint effect to match. Empty + means match all taint effects. When specified, allowed values + are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: Key is the taint key that the toleration applies + to. Empty means match all taint keys. If the key is empty, + operator must be Exists; this combination means to match all + values and all keys. + type: string + operator: + description: Operator represents a key's relationship to the + value. Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod + can tolerate all taints of a particular category. + type: string + tolerationSeconds: + description: TolerationSeconds represents the period of time + the toleration (which must be of effect NoExecute, otherwise + this field is ignored) tolerates the taint. By default, it + is not set, which means tolerate the taint forever (do not + evict). Zero and negative values will be treated as 0 (evict + immediately) by the system. + format: int64 + type: integer + value: + description: Value is the taint value the toleration matches + to. If the operator is Exists, the value should be empty, + otherwise just a regular string. + type: string + type: object + type: array type: object status: description: TunnelStatus defines the observed state of Tunnel diff --git a/config/crd/bases/networking.cfargotunnel.com_tunnels.yaml b/config/crd/bases/networking.cfargotunnel.com_tunnels.yaml index 4b9f44c..1f81a97 100644 --- a/config/crd/bases/networking.cfargotunnel.com_tunnels.yaml +++ b/config/crd/bases/networking.cfargotunnel.com_tunnels.yaml @@ -124,6 +124,12 @@ spec: description: NoTlsVerify disables origin TLS certificate checks when the endpoint is HTTPS. type: boolean + nodeSelectors: + additionalProperties: + type: string + description: NodeSelectors specifies the nodeSelectors to apply to + the cloudflared tunnel deployment + type: object originCaPool: description: OriginCaPool speficies the secret with tls.crt (and other certs as needed to be referred in the service annotation) of the @@ -136,6 +142,47 @@ spec: format: int32 minimum: 0 type: integer + tolerations: + description: Tolerations specifies the tolerations to apply to the + cloudflared tunnel deployment + items: + description: The pod this Toleration is attached to tolerates any + taint that matches the triple using the matching + operator . + properties: + effect: + description: Effect indicates the taint effect to match. Empty + means match all taint effects. When specified, allowed values + are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: Key is the taint key that the toleration applies + to. Empty means match all taint keys. If the key is empty, + operator must be Exists; this combination means to match all + values and all keys. + type: string + operator: + description: Operator represents a key's relationship to the + value. Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod + can tolerate all taints of a particular category. + type: string + tolerationSeconds: + description: TolerationSeconds represents the period of time + the toleration (which must be of effect NoExecute, otherwise + this field is ignored) tolerates the taint. By default, it + is not set, which means tolerate the taint forever (do not + evict). Zero and negative values will be treated as 0 (evict + immediately) by the system. + format: int64 + type: integer + value: + description: Value is the taint value the toleration matches + to. If the operator is Exists, the value should be empty, + otherwise just a regular string. + type: string + type: object + type: array type: object status: description: TunnelStatus defines the observed state of Tunnel diff --git a/controllers/reconciler.go b/controllers/reconciler.go index 0ee49bc..715c06a 100644 --- a/controllers/reconciler.go +++ b/controllers/reconciler.go @@ -49,6 +49,10 @@ func labelsForTunnel(cf Tunnel) map[string]string { } } +func nodeSelectorsForTunnel(cf Tunnel) map[string]string { + return cf.GetSpec().NodeSelectors +} + func setupTunnel(r GenericTunnelReconciler) (ctrl.Result, bool, error) { okNewTunnel := r.GetTunnel().GetSpec().NewTunnel != networkingv1alpha1.NewTunnel{} okExistingTunnel := r.GetTunnel().GetSpec().ExistingTunnel != networkingv1alpha1.ExistingTunnel{} @@ -405,6 +409,8 @@ func secretForTunnel(r GenericTunnelReconciler) *corev1.Secret { func deploymentForTunnel(r GenericTunnelReconciler) *appsv1.Deployment { ls := labelsForTunnel(r.GetTunnel()) replicas := r.GetTunnel().GetSpec().Size + nodeSelector := nodeSelectorsForTunnel(r.GetTunnel()) + tolerations := r.GetTunnel().GetSpec().Tolerations args := []string{"tunnel", "--config", "/etc/cloudflared/config/config.yaml", "--metrics", "0.0.0.0:2000", "run"} volumes := []corev1.Volume{{ @@ -491,7 +497,9 @@ func deploymentForTunnel(r GenericTunnelReconciler) *appsv1.Deployment { Limits: corev1.ResourceList{"memory": resource.MustParse("256Mi"), "cpu": resource.MustParse("500m")}, }, }}, - Volumes: volumes, + Volumes: volumes, + NodeSelector: nodeSelector, + Tolerations: tolerations, }, }, },