From 7e7f7d20bc8094ba3b99fb1891c071680e5b9e18 Mon Sep 17 00:00:00 2001 From: Glenn Pratt Date: Mon, 13 Nov 2023 15:41:57 -0800 Subject: [PATCH] Allow specifying Private IP by annotation for VLAN / VPC support --- cloud/linode/loadbalancers.go | 14 ++++++++++++-- cloud/linode/loadbalancers_test.go | 23 +++++++++++++++++++++-- 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/cloud/linode/loadbalancers.go b/cloud/linode/loadbalancers.go index 54dd0f26..f9a88152 100644 --- a/cloud/linode/loadbalancers.go +++ b/cloud/linode/loadbalancers.go @@ -50,6 +50,8 @@ const ( annLinodeHostnameOnlyIngress = "service.beta.kubernetes.io/linode-loadbalancer-hostname-only-ingress" annLinodeLoadBalancerTags = "service.beta.kubernetes.io/linode-loadbalancer-tags" + + annLinodeNodePrivateIP = "node.k8s.linode.com/private-ip" ) var ( @@ -644,7 +646,7 @@ func (l *loadbalancers) buildLoadBalancerRequest(ctx context.Context, clusterNam func (l *loadbalancers) buildNodeBalancerNodeCreateOptions(node *v1.Node, nodePort int32) linodego.NodeBalancerNodeCreateOptions { return linodego.NodeBalancerNodeCreateOptions{ - Address: fmt.Sprintf("%v:%v", getNodeInternalIP(node), nodePort), + Address: fmt.Sprintf("%v:%v", getNodePrivateIP(node), nodePort), Label: node.Name, Mode: "accept", Weight: 100, @@ -758,7 +760,15 @@ func getPortConfigAnnotation(service *v1.Service, port int) (portConfigAnnotatio return annotation, nil } -func getNodeInternalIP(node *v1.Node) string { +// getNodePrivateIP should provide the Linode Private IP the NodeBalance +// will comminucate with. When using a VLAN or VPC for the Kubernetes cluster +// network, this will not be the NodeInternalIP, so this prefers an annotation +// cluster operators may specify in such a situation. +func getNodePrivateIP(node *v1.Node) string { + if address, exists := node.Annotations[annLinodeNodePrivateIP]; exists { + return address + } + for _, addr := range node.Status.Addresses { if addr.Type == v1.NodeInternalIP { return addr.Address diff --git a/cloud/linode/loadbalancers_test.go b/cloud/linode/loadbalancers_test.go index 05d327f8..63afdcc7 100644 --- a/cloud/linode/loadbalancers_test.go +++ b/cloud/linode/loadbalancers_test.go @@ -1112,7 +1112,7 @@ func Test_getHealthCheckType(t *testing.T) { } } -func Test_getNodeInternalIP(t *testing.T) { +func Test_getNodePrivateIP(t *testing.T) { testcases := []struct { name string node *v1.Node @@ -1146,11 +1146,30 @@ func Test_getNodeInternalIP(t *testing.T) { }, "", }, + { + "node internal ip annotation present", + &v1.Node{ + ObjectMeta: metav1.ObjectMeta{ + Annotations: map[string]string{ + annLinodeNodePrivateIP: "192.168.42.42", + }, + }, + Status: v1.NodeStatus{ + Addresses: []v1.NodeAddress{ + { + Type: v1.NodeInternalIP, + Address: "10.0.1.1", + }, + }, + }, + }, + "192.168.42.42", + }, } for _, test := range testcases { t.Run(test.name, func(t *testing.T) { - ip := getNodeInternalIP(test.node) + ip := getNodePrivateIP(test.node) if ip != test.address { t.Error("unexpected certificate") t.Logf("expected: %q", test.address)