Skip to content

Commit

Permalink
resolve hairpinning
Browse files Browse the repository at this point in the history
  • Loading branch information
happytreees committed Jul 30, 2024
1 parent 4042f34 commit b729f2a
Showing 1 changed file with 35 additions and 4 deletions.
39 changes: 35 additions & 4 deletions vultr/loadbalancers.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ package vultr
import (
"context"
"fmt"
"github.com/asaskevich/govalidator"
"net"
"strconv"
"strings"
Expand Down Expand Up @@ -51,6 +52,9 @@ const (
// annoVultrLBBackendProtocol backend protocol
annoVultrLBBackendProtocol = "service.beta.kubernetes.io/vultr-loadbalancer-backend-protocol"

// annoVultrHostname is the hostname used for VLB to prevent hairpinning
annoVultrHostname = "service.beta.kubernetes.io/vultr-loadbalancer-hostname"

annoVultrHealthCheckPath = "service.beta.kubernetes.io/vultr-loadbalancer-healthcheck-path"
annoVultrHealthCheckProtocol = "service.beta.kubernetes.io/vultr-loadbalancer-healthcheck-protocol"
annoVultrHealthCheckPort = "service.beta.kubernetes.io/vultr-loadbalancer-healthcheck-port"
Expand Down Expand Up @@ -116,11 +120,23 @@ func (l *loadbalancers) GetLoadBalancer(ctx context.Context, _ string, service *

enabledIPv6 := checkEnabledIPv6(service)
var ingress []v1.LoadBalancerIngress
hostname := lb.Label

// Check if hostname annotation is blank and set if not
if _, ok := service.Annotations[annoVultrHostname]; !ok {
if service.Annotations[annoVultrHostname] != "" {
if govalidator.IsDNSName(service.Annotations[annoVultrHostname]) {
hostname = service.Annotations[annoVultrHostname]
} else {
return nil, true, fmt.Errorf("hostname %s is not a valid DNS name", service.Annotations[annoVultrHostname])
}
}
}

ingress = append(ingress, v1.LoadBalancerIngress{Hostname: lb.Label, IP: lb.IPV4})
ingress = append(ingress, v1.LoadBalancerIngress{Hostname: hostname, IP: lb.IPV4})

if enabledIPv6 {
ingress = append(ingress, v1.LoadBalancerIngress{Hostname: lb.Label, IP: lb.IPV6})
ingress = append(ingress, v1.LoadBalancerIngress{Hostname: hostname, IP: lb.IPV6})
}

return &v1.LoadBalancerStatus{
Expand Down Expand Up @@ -194,10 +210,22 @@ func (l *loadbalancers) EnsureLoadBalancer(ctx context.Context, clusterName stri
enabledIPv6 := checkEnabledIPv6(service)
var ingress []v1.LoadBalancerIngress

ingress = append(ingress, v1.LoadBalancerIngress{Hostname: lb2.Label, IP: lb2.IPV4})
hostname := lb2.Label
// Check if hostname annotation is blank and set if not
if _, ok := service.Annotations[annoVultrHostname]; !ok {
if service.Annotations[annoVultrHostname] != "" {
if govalidator.IsDNSName(service.Annotations[annoVultrHostname]) {
hostname = service.Annotations[annoVultrHostname]
} else {
return nil, fmt.Errorf("hostname %s is not a valid DNS name", service.Annotations[annoVultrHostname])
}
}
}

ingress = append(ingress, v1.LoadBalancerIngress{Hostname: hostname, IP: lb2.IPV4})

if enabledIPv6 {
ingress = append(ingress, v1.LoadBalancerIngress{Hostname: lb2.Label, IP: lb2.IPV6})
ingress = append(ingress, v1.LoadBalancerIngress{Hostname: hostname, IP: lb2.IPV6})
}

return &v1.LoadBalancerStatus{
Expand All @@ -220,6 +248,9 @@ func (l *loadbalancers) EnsureLoadBalancer(ctx context.Context, clusterName stri

// Set the Vultr VLB ID annotation
if _, ok := service.Annotations[annoVultrLoadBalancerID]; !ok {
if service.Annotations == nil {
service.Annotations = make(map[string]string)
}
service.Annotations[annoVultrLoadBalancerID] = lb.ID
if err = l.GetKubeClient(); err != nil {
return nil, fmt.Errorf("failed to get kubeclient to update service: %s", err)
Expand Down

0 comments on commit b729f2a

Please sign in to comment.