Skip to content
This repository was archived by the owner on Mar 22, 2018. It is now read-only.

Commit fadb6ab

Browse files
author
FengyunPan
committed
Support for specifying external LoadBalancerIP on openstack
Fix #50851 Add ServiceAnnotationLoadBalancerInternal annotation to distinguish between internal LoadBalancerIP and external LoadBalancerIP.
1 parent 86e1ec0 commit fadb6ab

1 file changed

Lines changed: 59 additions & 6 deletions

File tree

pkg/cloudprovider/providers/openstack/openstack_loadbalancer.go

Lines changed: 59 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,11 @@ const (
6868
errorStatus = "ERROR"
6969

7070
ServiceAnnotationLoadBalancerFloatingNetworkId = "loadbalancer.openstack.org/floating-network-id"
71+
72+
// ServiceAnnotationLoadBalancerInternal is the annotation used on the service
73+
// to indicate that we want an internal loadbalancer service.
74+
// If the value of ServiceAnnotationLoadBalancerInternal is false, it indicates that we want an external loadbalancer service. Default to true.
75+
ServiceAnnotationLoadBalancerInternal = "service.beta.kubernetes.io/openstack-internal-load-balancer"
7176
)
7277

7378
// LoadBalancer implementation for LBaaS v1
@@ -501,15 +506,15 @@ func createNodeSecurityGroup(client *gophercloud.ServiceClient, nodeSecurityGrou
501506
return nil
502507
}
503508

504-
func (lbaas *LbaasV2) createLoadBalancer(service *v1.Service, name string) (*loadbalancers.LoadBalancer, error) {
509+
func (lbaas *LbaasV2) createLoadBalancer(service *v1.Service, name string, internalAnnotation bool) (*loadbalancers.LoadBalancer, error) {
505510
createOpts := loadbalancers.CreateOpts{
506511
Name: name,
507512
Description: fmt.Sprintf("Kubernetes external service %s", name),
508513
VipSubnetID: lbaas.opts.SubnetId,
509514
}
510515

511516
loadBalancerIP := service.Spec.LoadBalancerIP
512-
if loadBalancerIP != "" {
517+
if loadBalancerIP != "" && internalAnnotation {
513518
createOpts.VipAddress = loadBalancerIP
514519
}
515520

@@ -626,6 +631,24 @@ func (lbaas *LbaasV2) EnsureLoadBalancer(clusterName string, apiService *v1.Serv
626631
floatingPool := getStringFromServiceAnnotation(apiService, ServiceAnnotationLoadBalancerFloatingNetworkId, lbaas.opts.FloatingNetworkId)
627632
glog.V(4).Infof("EnsureLoadBalancer using floatingPool: %v", floatingPool)
628633

634+
var internalAnnotation bool
635+
internal := getStringFromServiceAnnotation(apiService, ServiceAnnotationLoadBalancerInternal, "true")
636+
switch internal {
637+
case "true":
638+
glog.V(4).Infof("Ensure an internal loadbalancer service.")
639+
internalAnnotation = true
640+
case "false":
641+
if len(floatingPool) != 0 {
642+
glog.V(4).Infof("Ensure an external loadbalancer service.")
643+
internalAnnotation = false
644+
} else {
645+
return nil, fmt.Errorf("floating-network-id or loadbalancer.openstack.org/floating-network-id should be specified when service.beta.kubernetes.io/openstack-internal-load-balancer is false")
646+
}
647+
default:
648+
return nil, fmt.Errorf("unknow service.beta.kubernetes.io/openstack-internal-load-balancer annotation: %v, specify \"true\" or \"false\".",
649+
internal)
650+
}
651+
629652
// Check for TCP protocol on each port
630653
// TODO: Convert all error messages to use an event recorder
631654
for _, port := range ports {
@@ -661,7 +684,7 @@ func (lbaas *LbaasV2) EnsureLoadBalancer(clusterName string, apiService *v1.Serv
661684
return nil, fmt.Errorf("Error getting loadbalancer %s: %v", name, err)
662685
}
663686
glog.V(2).Infof("Creating loadbalancer %s", name)
664-
loadbalancer, err = lbaas.createLoadBalancer(apiService, name)
687+
loadbalancer, err = lbaas.createLoadBalancer(apiService, name, internalAnnotation)
665688
if err != nil {
666689
// Unknown error, retry later
667690
return nil, fmt.Errorf("Error creating loadbalancer %s: %v", name, err)
@@ -855,12 +878,18 @@ func (lbaas *LbaasV2) EnsureLoadBalancer(clusterName string, apiService *v1.Serv
855878
if err != nil && err != ErrNotFound {
856879
return nil, fmt.Errorf("Error getting floating ip for port %s: %v", portID, err)
857880
}
858-
if floatIP == nil && floatingPool != "" {
881+
if floatIP == nil && floatingPool != "" && !internalAnnotation {
859882
glog.V(4).Infof("Creating floating ip for loadbalancer %s port %s", loadbalancer.ID, portID)
860883
floatIPOpts := floatingips.CreateOpts{
861884
FloatingNetworkID: floatingPool,
862885
PortID: portID,
863886
}
887+
888+
loadBalancerIP := apiService.Spec.LoadBalancerIP
889+
if loadBalancerIP != "" {
890+
floatIPOpts.FloatingIP = loadBalancerIP
891+
}
892+
864893
floatIP, err = floatingips.Create(lbaas.network, floatIPOpts).Extract()
865894
if err != nil {
866895
return nil, fmt.Errorf("Error creating LB floatingip %+v: %v", floatIPOpts, err)
@@ -1284,6 +1313,24 @@ func (lb *LbaasV1) EnsureLoadBalancer(clusterName string, apiService *v1.Service
12841313
floatingPool := getStringFromServiceAnnotation(apiService, ServiceAnnotationLoadBalancerFloatingNetworkId, lb.opts.FloatingNetworkId)
12851314
glog.V(4).Infof("EnsureLoadBalancer using floatingPool: %v", floatingPool)
12861315

1316+
var internalAnnotation bool
1317+
internal := getStringFromServiceAnnotation(apiService, ServiceAnnotationLoadBalancerInternal, "true")
1318+
switch internal {
1319+
case "true":
1320+
glog.V(4).Infof("Ensure an internal loadbalancer service.")
1321+
internalAnnotation = true
1322+
case "false":
1323+
if len(floatingPool) != 0 {
1324+
glog.V(4).Infof("Ensure an external loadbalancer service.")
1325+
internalAnnotation = false
1326+
} else {
1327+
return nil, fmt.Errorf("floating-network-id or loadbalancer.openstack.org/floating-network-id should be specified when service.beta.kubernetes.io/openstack-internal-load-balancer is false")
1328+
}
1329+
default:
1330+
return nil, fmt.Errorf("unknow service.beta.kubernetes.io/openstack-internal-load-balancer annotation: %v, specify \"true\" or \"false\".",
1331+
internal)
1332+
}
1333+
12871334
ports := apiService.Spec.Ports
12881335
if len(ports) > 1 {
12891336
return nil, fmt.Errorf("multiple ports are not supported in openstack v1 load balancers")
@@ -1394,7 +1441,7 @@ func (lb *LbaasV1) EnsureLoadBalancer(clusterName string, apiService *v1.Service
13941441
}
13951442

13961443
loadBalancerIP := apiService.Spec.LoadBalancerIP
1397-
if loadBalancerIP != "" {
1444+
if loadBalancerIP != "" && internalAnnotation {
13981445
createOpts.Address = loadBalancerIP
13991446
}
14001447

@@ -1407,11 +1454,17 @@ func (lb *LbaasV1) EnsureLoadBalancer(clusterName string, apiService *v1.Service
14071454

14081455
status.Ingress = []v1.LoadBalancerIngress{{IP: vip.Address}}
14091456

1410-
if floatingPool != "" {
1457+
if floatingPool != "" && !internalAnnotation {
14111458
floatIPOpts := floatingips.CreateOpts{
14121459
FloatingNetworkID: floatingPool,
14131460
PortID: vip.PortID,
14141461
}
1462+
1463+
loadBalancerIP := apiService.Spec.LoadBalancerIP
1464+
if loadBalancerIP != "" {
1465+
floatIPOpts.FloatingIP = loadBalancerIP
1466+
}
1467+
14151468
floatIP, err := floatingips.Create(lb.network, floatIPOpts).Extract()
14161469
if err != nil {
14171470
return nil, fmt.Errorf("Error creating floatingip for openstack load balancer %s: %v", name, err)

0 commit comments

Comments
 (0)