From f40b27baf30951b13fd299b6afba0ce0f0538c1c Mon Sep 17 00:00:00 2001 From: Aswin Suryanarayanan Date: Thu, 19 Dec 2024 11:38:10 -0500 Subject: [PATCH] Change loadbalancer type for HCP deployments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Kubevirt(HCP) clusters do not have their loadbalancer installed and rely on the host loadblancer( like netallb) when a loadbalancer is created.So when the Submariner exposes the submariner-gateway loadbalancer service with ServiceExternalTrafficPolicy locally does not work, as the traffic from the remotecluster first lands on the host cluster. Hence the traffic policy need to be updated to cluster in these deployments. A new parameter hostedCluster is added to submariner config, if set the traffic policy will be set to cluster Signed-off-by: Aswin Suryanarayanan --- api/v1alpha1/submariner_types.go | 13 +++++++++++-- config/crd/bases/submariner.io_submariners.yaml | 2 ++ .../submariner/loadbalancer_resources.go | 8 +++++++- .../controllers/submariner/submariner_controller.go | 1 + .../submariner/submariner_controller_test.go | 2 ++ pkg/embeddedyamls/yamls.go | 6 ++++++ tools/go.mod | 3 ++- 7 files changed, 31 insertions(+), 4 deletions(-) diff --git a/api/v1alpha1/submariner_types.go b/api/v1alpha1/submariner_types.go index 7dc385e15..8bc224353 100644 --- a/api/v1alpha1/submariner_types.go +++ b/api/v1alpha1/submariner_types.go @@ -160,10 +160,14 @@ type SubmarinerSpec struct { // Enable NAT between clusters. // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Enable NAT" // +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors={"urn:alm:descriptor:com.tectonic.ui:booleanSwitch"} - NatEnabled bool `json:"natEnabled"` - + NatEnabled bool `json:"natEnabled"` AirGappedDeployment bool `json:"airGappedDeployment,omitempty"` + // Is the cluster a hosted cluster. + // +operator-sdk:csv:customresourcedefinitions:type=status,displayName="Hosted Cluster" + // +operator-sdk:csv:customresourcedefinitions:type=status,xDescriptors={"urn:alm:descriptor:com.tectonic.ui:text"} + HostedCluster bool `json:"hostedCluster,omitempty"` + // Enable automatic Load Balancer in front of the gateways. // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Enable Load Balancer" // +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors={"urn:alm:descriptor:com.tectonic.ui:booleanSwitch"} @@ -228,6 +232,11 @@ type SubmarinerStatus struct { AirGappedDeployment bool `json:"airGappedDeployment,omitempty"` + // Is the cluster a hosted cluster. + // +operator-sdk:csv:customresourcedefinitions:type=status,displayName="Hosted Cluster" + // +operator-sdk:csv:customresourcedefinitions:type=status,xDescriptors={"urn:alm:descriptor:com.tectonic.ui:text"} + HostedCluster bool `json:"hostedCluster,omitempty"` + ColorCodes string `json:"colorCodes,omitempty"` // The current cluster ID. diff --git a/config/crd/bases/submariner.io_submariners.yaml b/config/crd/bases/submariner.io_submariners.yaml index 5d98f28e2..fc23e62d6 100644 --- a/config/crd/bases/submariner.io_submariners.yaml +++ b/config/crd/bases/submariner.io_submariners.yaml @@ -146,6 +146,8 @@ spec: haltOnCertificateError: description: Halt on certificate error (so the pod gets restarted). type: boolean + hostedCluster: + type: boolean imageOverrides: additionalProperties: type: string diff --git a/internal/controllers/submariner/loadbalancer_resources.go b/internal/controllers/submariner/loadbalancer_resources.go index e135e1ab5..90fdd81bb 100644 --- a/internal/controllers/submariner/loadbalancer_resources.go +++ b/internal/controllers/submariner/loadbalancer_resources.go @@ -91,6 +91,8 @@ func (r *Reconciler) getOCPPlatformType(ctx context.Context) (string, error) { } func newLoadBalancerService(instance *v1alpha1.Submariner, platformTypeOCP string) *corev1.Service { + externalTrafficPolicy := corev1.ServiceExternalTrafficPolicyTypeLocal + var svcAnnotations map[string]string switch platformTypeOCP { @@ -104,6 +106,10 @@ func newLoadBalancerService(instance *v1alpha1.Submariner, platformTypeOCP strin "service.kubernetes.io/ibm-load-balancer-cloud-provider-ip-type": "public", "service.kubernetes.io/ibm-load-balancer-cloud-provider-vpc-health-check-protocol": "http", } + case string(configv1.KubevirtPlatformType): + if instance.Spec.HostedCluster { + externalTrafficPolicy = corev1.ServiceExternalTrafficPolicyTypeCluster + } default: svcAnnotations = map[string]string{} } @@ -115,7 +121,7 @@ func newLoadBalancerService(instance *v1alpha1.Submariner, platformTypeOCP strin Annotations: svcAnnotations, }, Spec: corev1.ServiceSpec{ - ExternalTrafficPolicy: corev1.ServiceExternalTrafficPolicyTypeLocal, + ExternalTrafficPolicy: externalTrafficPolicy, Type: corev1.ServiceTypeLoadBalancer, Selector: map[string]string{ // Traffic is directed to the active gateway diff --git a/internal/controllers/submariner/submariner_controller.go b/internal/controllers/submariner/submariner_controller.go index c50c69576..e341d9452 100644 --- a/internal/controllers/submariner/submariner_controller.go +++ b/internal/controllers/submariner/submariner_controller.go @@ -222,6 +222,7 @@ func (r *Reconciler) Reconcile(ctx context.Context, request reconcile.Request) ( instance.Status.Version = instance.Spec.Version instance.Status.NatEnabled = instance.Spec.NatEnabled instance.Status.AirGappedDeployment = instance.Spec.AirGappedDeployment + instance.Status.HostedCluster = instance.Spec.HostedCluster instance.Status.ColorCodes = instance.Spec.ColorCodes instance.Status.ClusterID = instance.Spec.ClusterID instance.Status.GlobalCIDR = instance.Spec.GlobalCIDR diff --git a/internal/controllers/submariner/submariner_controller_test.go b/internal/controllers/submariner/submariner_controller_test.go index 1a6a0f57c..9822bcfb8 100644 --- a/internal/controllers/submariner/submariner_controller_test.go +++ b/internal/controllers/submariner/submariner_controller_test.go @@ -83,6 +83,7 @@ func testSubmarinerResourceReconciliation() { BeforeEach(func() { t.submariner.Spec.NatEnabled = true t.submariner.Spec.AirGappedDeployment = true + t.submariner.Spec.HostedCluster = true }) It("should populate general Submariner resource Status fields from the Spec", func(ctx SpecContext) { @@ -91,6 +92,7 @@ func testSubmarinerResourceReconciliation() { updated := t.getSubmariner(ctx) Expect(updated.Status.NatEnabled).To(BeTrue()) Expect(updated.Status.AirGappedDeployment).To(BeTrue()) + Expect(updated.Status.HostedCluster).To(BeTrue()) Expect(updated.Status.ClusterID).To(Equal(t.submariner.Spec.ClusterID)) Expect(updated.Status.GlobalCIDR).To(Equal(t.submariner.Spec.GlobalCIDR)) Expect(updated.Status.NetworkPlugin).To(Equal(t.clusterNetwork.NetworkPlugin)) diff --git a/pkg/embeddedyamls/yamls.go b/pkg/embeddedyamls/yamls.go index f3320c307..7e1bc1481 100644 --- a/pkg/embeddedyamls/yamls.go +++ b/pkg/embeddedyamls/yamls.go @@ -248,6 +248,9 @@ spec: haltOnCertificateError: description: Halt on certificate error (so the pod gets restarted). type: boolean + hostedCluster: + description: Is the cluster a hosted cluster. + type: boolean imageOverrides: additionalProperties: type: string @@ -840,6 +843,9 @@ spec: required: - mismatchedContainerImages type: object + hostedCluster: + description: Is the cluster a hosted cluster. + type: boolean loadBalancerStatus: description: The status of the load balancer DaemonSet. properties: diff --git a/tools/go.mod b/tools/go.mod index 0b0cac18f..55ba87f28 100644 --- a/tools/go.mod +++ b/tools/go.mod @@ -1,6 +1,7 @@ module github.com/submariner-io/submariner-operator/tools -go 1.22.10 +go 1.23.4 + require ( github.com/operator-framework/operator-sdk v1.39.0 github.com/uw-labs/lichen v0.1.7