Skip to content

Commit e41c7e7

Browse files
dulekmandre
authored andcommitted
Make manage-security-groups work with OVN (kubernetes#2291)
OVN keeps the source IP of the incoming traffic. This means that the SG on the members of the LB (nodes) needs to have a rule opening traffic not only from inside the cluster, but also elsewhere. This can restricted by using the `Service.Spec.LoadBalancerSourceRanges` and this commit also makes sure the setting is taken into account.
1 parent 4b76bbe commit e41c7e7

File tree

1 file changed

+36
-35
lines changed

1 file changed

+36
-35
lines changed

pkg/openstack/loadbalancer.go

Lines changed: 36 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1408,8 +1408,10 @@ func (lbaas *LbaasV2) buildListenerCreateOpt(port corev1.ServicePort, svcConf *s
14081408
listenerCreateOpt.Protocol = listeners.ProtocolHTTP
14091409
}
14101410

1411-
if len(svcConf.allowedCIDR) > 0 {
1412-
listenerCreateOpt.AllowedCIDRs = svcConf.allowedCIDR
1411+
if openstackutil.IsOctaviaFeatureSupported(lbaas.lb, openstackutil.OctaviaFeatureVIPACL, lbaas.opts.LBProvider) {
1412+
if len(svcConf.allowedCIDR) > 0 {
1413+
listenerCreateOpt.AllowedCIDRs = svcConf.allowedCIDR
1414+
}
14131415
}
14141416
return listenerCreateOpt
14151417
}
@@ -1781,18 +1783,19 @@ func (lbaas *LbaasV2) checkService(service *corev1.Service, nodes []*corev1.Node
17811783
svcConf.timeoutTCPInspect = getIntFromServiceAnnotation(service, ServiceAnnotationLoadBalancerTimeoutTCPInspect, 0)
17821784
}
17831785

1784-
var listenerAllowedCIDRs []string
17851786
sourceRanges, err := GetLoadBalancerSourceRanges(service, svcConf.preferredIPFamily)
17861787
if err != nil {
17871788
return fmt.Errorf("failed to get source ranges for loadbalancer service %s: %v", serviceName, err)
17881789
}
17891790
if openstackutil.IsOctaviaFeatureSupported(lbaas.lb, openstackutil.OctaviaFeatureVIPACL, lbaas.opts.LBProvider) {
17901791
klog.V(4).Info("LoadBalancerSourceRanges is suppported")
1791-
listenerAllowedCIDRs = sourceRanges.StringSlice()
1792+
svcConf.allowedCIDR = sourceRanges.StringSlice()
1793+
} else if lbaas.opts.LBProvider == "ovn" && lbaas.opts.ManageSecurityGroups {
1794+
klog.V(4).Info("LoadBalancerSourceRanges will be enforced on the SG created and attached to LB members")
1795+
svcConf.allowedCIDR = sourceRanges.StringSlice()
17921796
} else {
1793-
klog.Warning("LoadBalancerSourceRanges is ignored")
1797+
klog.Warning("LoadBalancerSourceRanges are ignored")
17941798
}
1795-
svcConf.allowedCIDR = listenerAllowedCIDRs
17961799

17971800
if openstackutil.IsOctaviaFeatureSupported(lbaas.lb, openstackutil.OctaviaFeatureFlavors, lbaas.opts.LBProvider) {
17981801
svcConf.flavorID = getStringFromServiceAnnotation(service, ServiceAnnotationLoadBalancerFlavorID, lbaas.opts.FlavorID)
@@ -2040,7 +2043,7 @@ func (lbaas *LbaasV2) ensureOctaviaLoadBalancer(ctx context.Context, clusterName
20402043
status := lbaas.createLoadBalancerStatus(service, svcConf, addr)
20412044

20422045
if lbaas.opts.ManageSecurityGroups {
2043-
err := lbaas.ensureSecurityGroup(clusterName, service, nodes, loadbalancer, svcConf.preferredIPFamily, svcConf.lbMemberSubnetID)
2046+
err := lbaas.ensureAndUpdateOctaviaSecurityGroup(clusterName, service, nodes, svcConf)
20442047
if err != nil {
20452048
return status, fmt.Errorf("failed when reconciling security groups for LB service %v/%v: %v", service.Namespace, service.Name, err)
20462049
}
@@ -2101,14 +2104,6 @@ func (lbaas *LbaasV2) ensureSecurityRule(sgRuleCreateOpts rules.CreateOpts) erro
21012104
return nil
21022105
}
21032106

2104-
// ensureSecurityGroup ensures security group exist for specific loadbalancer service.
2105-
// Creating security group for specific loadbalancer service when it does not exist.
2106-
func (lbaas *LbaasV2) ensureSecurityGroup(clusterName string, apiService *corev1.Service, nodes []*corev1.Node,
2107-
loadbalancer *loadbalancers.LoadBalancer, preferredIPFamily corev1.IPFamily, memberSubnetID string) error {
2108-
2109-
return lbaas.ensureAndUpdateOctaviaSecurityGroup(clusterName, apiService, nodes, memberSubnetID)
2110-
}
2111-
21122107
func (lbaas *LbaasV2) updateOctaviaLoadBalancer(ctx context.Context, clusterName string, service *corev1.Service, nodes []*corev1.Node) error {
21132108
svcConf := new(serviceConfig)
21142109
var err error
@@ -2176,7 +2171,7 @@ func (lbaas *LbaasV2) updateOctaviaLoadBalancer(ctx context.Context, clusterName
21762171
}
21772172

21782173
if lbaas.opts.ManageSecurityGroups {
2179-
err := lbaas.updateSecurityGroup(clusterName, service, nodes, svcConf.lbMemberSubnetID)
2174+
err := lbaas.ensureAndUpdateOctaviaSecurityGroup(clusterName, service, nodes, svcConf)
21802175
if err != nil {
21812176
return fmt.Errorf("failed to update Security Group for loadbalancer service %s: %v", serviceName, err)
21822177
}
@@ -2240,7 +2235,7 @@ func getRulesToCreateAndDelete(wantedRules []rules.CreateOpts, existingRules []r
22402235
}
22412236

22422237
// ensureAndUpdateOctaviaSecurityGroup handles the creation and update of the security group and the securiry rules for the octavia load balancer
2243-
func (lbaas *LbaasV2) ensureAndUpdateOctaviaSecurityGroup(clusterName string, apiService *corev1.Service, nodes []*corev1.Node, memberSubnetID string) error {
2238+
func (lbaas *LbaasV2) ensureAndUpdateOctaviaSecurityGroup(clusterName string, apiService *corev1.Service, nodes []*corev1.Node, svcConf *serviceConfig) error {
22442239
// get service ports
22452240
ports := apiService.Spec.Ports
22462241
if len(ports) == 0 {
@@ -2274,16 +2269,23 @@ func (lbaas *LbaasV2) ensureAndUpdateOctaviaSecurityGroup(clusterName string, ap
22742269
}
22752270

22762271
mc := metrics.NewMetricContext("subnet", "get")
2277-
subnet, err := subnets.Get(lbaas.network, memberSubnetID).Extract()
2272+
subnet, err := subnets.Get(lbaas.network, svcConf.lbMemberSubnetID).Extract()
22782273
if mc.ObserveRequest(err) != nil {
22792274
return fmt.Errorf(
2280-
"failed to find subnet %s from openstack: %v", memberSubnetID, err)
2275+
"failed to find subnet %s from openstack: %v", svcConf.lbMemberSubnetID, err)
22812276
}
22822277

22832278
etherType := rules.EtherType4
22842279
if netutils.IsIPv6CIDRString(subnet.CIDR) {
22852280
etherType = rules.EtherType6
22862281
}
2282+
cidrs := []string{subnet.CIDR}
2283+
if lbaas.opts.LBProvider == "ovn" {
2284+
// OVN keeps the source IP of the incoming traffic. This means that we cannot just open the LB range, but we
2285+
// need to open for the whole world. This can be restricted by using the service.spec.loadBalancerSourceRanges.
2286+
// svcConf.allowedCIDR will give us the ranges calculated by GetLoadBalancerSourceRanges() earlier.
2287+
cidrs = svcConf.allowedCIDR
2288+
}
22872289

22882290
existingRules, err := getSecurityGroupRules(lbaas.network, rules.ListOpts{SecGroupID: lbSecGroupID})
22892291
if err != nil {
@@ -2296,6 +2298,8 @@ func (lbaas *LbaasV2) ensureAndUpdateOctaviaSecurityGroup(clusterName string, ap
22962298
wantedRules := make([]rules.CreateOpts, 0, len(ports)+1)
22972299

22982300
if apiService.Spec.HealthCheckNodePort != 0 {
2301+
// TODO(dulek): How should this work with OVN…? Do we need to allow all?
2302+
// Probably the traffic goes from the compute node?
22992303
wantedRules = append(wantedRules,
23002304
rules.CreateOpts{
23012305
Direction: rules.DirIngress,
@@ -2313,17 +2317,19 @@ func (lbaas *LbaasV2) ensureAndUpdateOctaviaSecurityGroup(clusterName string, ap
23132317
if port.NodePort == 0 { // It's 0 when AllocateLoadBalancerNodePorts=False
23142318
continue
23152319
}
2316-
wantedRules = append(wantedRules,
2317-
rules.CreateOpts{
2318-
Direction: rules.DirIngress,
2319-
Protocol: rules.RuleProtocol(port.Protocol),
2320-
EtherType: etherType,
2321-
RemoteIPPrefix: subnet.CIDR,
2322-
SecGroupID: lbSecGroupID,
2323-
PortRangeMin: int(port.NodePort),
2324-
PortRangeMax: int(port.NodePort),
2325-
},
2326-
)
2320+
for _, cidr := range cidrs {
2321+
wantedRules = append(wantedRules,
2322+
rules.CreateOpts{
2323+
Direction: rules.DirIngress,
2324+
Protocol: rules.RuleProtocol(port.Protocol),
2325+
EtherType: etherType,
2326+
RemoteIPPrefix: cidr,
2327+
SecGroupID: lbSecGroupID,
2328+
PortRangeMin: int(port.NodePort),
2329+
PortRangeMax: int(port.NodePort),
2330+
},
2331+
)
2332+
}
23272333
}
23282334

23292335
toCreate, toDelete := getRulesToCreateAndDelete(wantedRules, existingRules)
@@ -2357,11 +2363,6 @@ func (lbaas *LbaasV2) ensureAndUpdateOctaviaSecurityGroup(clusterName string, ap
23572363
return nil
23582364
}
23592365

2360-
// updateSecurityGroup updating security group for specific loadbalancer service.
2361-
func (lbaas *LbaasV2) updateSecurityGroup(clusterName string, apiService *corev1.Service, nodes []*corev1.Node, memberSubnetID string) error {
2362-
return lbaas.ensureAndUpdateOctaviaSecurityGroup(clusterName, apiService, nodes, memberSubnetID)
2363-
}
2364-
23652366
// EnsureLoadBalancerDeleted deletes the specified load balancer
23662367
func (lbaas *LbaasV2) EnsureLoadBalancerDeleted(ctx context.Context, clusterName string, service *corev1.Service) error {
23672368
mc := metrics.NewMetricContext("loadbalancer", "delete")

0 commit comments

Comments
 (0)