Skip to content

Commit 8a0e73f

Browse files
authored
Make manage-security-groups work with OVN (#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 942db28 commit 8a0e73f

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
@@ -1393,8 +1393,10 @@ func (lbaas *LbaasV2) buildListenerCreateOpt(port corev1.ServicePort, svcConf *s
13931393
listenerCreateOpt.Protocol = listeners.ProtocolHTTP
13941394
}
13951395

1396-
if len(svcConf.allowedCIDR) > 0 {
1397-
listenerCreateOpt.AllowedCIDRs = svcConf.allowedCIDR
1396+
if openstackutil.IsOctaviaFeatureSupported(lbaas.lb, openstackutil.OctaviaFeatureVIPACL, lbaas.opts.LBProvider) {
1397+
if len(svcConf.allowedCIDR) > 0 {
1398+
listenerCreateOpt.AllowedCIDRs = svcConf.allowedCIDR
1399+
}
13981400
}
13991401
return listenerCreateOpt
14001402
}
@@ -1751,18 +1753,19 @@ func (lbaas *LbaasV2) checkService(service *corev1.Service, nodes []*corev1.Node
17511753
svcConf.timeoutTCPInspect = getIntFromServiceAnnotation(service, ServiceAnnotationLoadBalancerTimeoutTCPInspect, 0)
17521754
}
17531755

1754-
var listenerAllowedCIDRs []string
17551756
sourceRanges, err := GetLoadBalancerSourceRanges(service, svcConf.preferredIPFamily)
17561757
if err != nil {
17571758
return fmt.Errorf("failed to get source ranges for loadbalancer service %s: %v", serviceName, err)
17581759
}
17591760
if openstackutil.IsOctaviaFeatureSupported(lbaas.lb, openstackutil.OctaviaFeatureVIPACL, lbaas.opts.LBProvider) {
17601761
klog.V(4).Info("LoadBalancerSourceRanges is suppported")
1761-
listenerAllowedCIDRs = sourceRanges.StringSlice()
1762+
svcConf.allowedCIDR = sourceRanges.StringSlice()
1763+
} else if lbaas.opts.LBProvider == "ovn" && lbaas.opts.ManageSecurityGroups {
1764+
klog.V(4).Info("LoadBalancerSourceRanges will be enforced on the SG created and attached to LB members")
1765+
svcConf.allowedCIDR = sourceRanges.StringSlice()
17621766
} else {
1763-
klog.Warning("LoadBalancerSourceRanges is ignored")
1767+
klog.Warning("LoadBalancerSourceRanges are ignored")
17641768
}
1765-
svcConf.allowedCIDR = listenerAllowedCIDRs
17661769

17671770
if openstackutil.IsOctaviaFeatureSupported(lbaas.lb, openstackutil.OctaviaFeatureFlavors, lbaas.opts.LBProvider) {
17681771
svcConf.flavorID = getStringFromServiceAnnotation(service, ServiceAnnotationLoadBalancerFlavorID, lbaas.opts.FlavorID)
@@ -2009,7 +2012,7 @@ func (lbaas *LbaasV2) ensureOctaviaLoadBalancer(ctx context.Context, clusterName
20092012
status := lbaas.createLoadBalancerStatus(service, svcConf, addr)
20102013

20112014
if lbaas.opts.ManageSecurityGroups {
2012-
err := lbaas.ensureSecurityGroup(clusterName, service, nodes, loadbalancer, svcConf.preferredIPFamily, svcConf.lbMemberSubnetID)
2015+
err := lbaas.ensureAndUpdateOctaviaSecurityGroup(clusterName, service, nodes, svcConf)
20132016
if err != nil {
20142017
return status, fmt.Errorf("failed when reconciling security groups for LB service %v/%v: %v", service.Namespace, service.Name, err)
20152018
}
@@ -2070,14 +2073,6 @@ func (lbaas *LbaasV2) ensureSecurityRule(sgRuleCreateOpts rules.CreateOpts) erro
20702073
return nil
20712074
}
20722075

2073-
// ensureSecurityGroup ensures security group exist for specific loadbalancer service.
2074-
// Creating security group for specific loadbalancer service when it does not exist.
2075-
func (lbaas *LbaasV2) ensureSecurityGroup(clusterName string, apiService *corev1.Service, nodes []*corev1.Node,
2076-
loadbalancer *loadbalancers.LoadBalancer, preferredIPFamily corev1.IPFamily, memberSubnetID string) error {
2077-
2078-
return lbaas.ensureAndUpdateOctaviaSecurityGroup(clusterName, apiService, nodes, memberSubnetID)
2079-
}
2080-
20812076
func (lbaas *LbaasV2) updateOctaviaLoadBalancer(ctx context.Context, clusterName string, service *corev1.Service, nodes []*corev1.Node) error {
20822077
svcConf := new(serviceConfig)
20832078
var err error
@@ -2140,7 +2135,7 @@ func (lbaas *LbaasV2) updateOctaviaLoadBalancer(ctx context.Context, clusterName
21402135
}
21412136

21422137
if lbaas.opts.ManageSecurityGroups {
2143-
err := lbaas.updateSecurityGroup(clusterName, service, nodes, svcConf.lbMemberSubnetID)
2138+
err := lbaas.ensureAndUpdateOctaviaSecurityGroup(clusterName, service, nodes, svcConf)
21442139
if err != nil {
21452140
return fmt.Errorf("failed to update Security Group for loadbalancer service %s: %v", serviceName, err)
21462141
}
@@ -2204,7 +2199,7 @@ func getRulesToCreateAndDelete(wantedRules []rules.CreateOpts, existingRules []r
22042199
}
22052200

22062201
// ensureAndUpdateOctaviaSecurityGroup handles the creation and update of the security group and the securiry rules for the octavia load balancer
2207-
func (lbaas *LbaasV2) ensureAndUpdateOctaviaSecurityGroup(clusterName string, apiService *corev1.Service, nodes []*corev1.Node, memberSubnetID string) error {
2202+
func (lbaas *LbaasV2) ensureAndUpdateOctaviaSecurityGroup(clusterName string, apiService *corev1.Service, nodes []*corev1.Node, svcConf *serviceConfig) error {
22082203
// get service ports
22092204
ports := apiService.Spec.Ports
22102205
if len(ports) == 0 {
@@ -2238,16 +2233,23 @@ func (lbaas *LbaasV2) ensureAndUpdateOctaviaSecurityGroup(clusterName string, ap
22382233
}
22392234

22402235
mc := metrics.NewMetricContext("subnet", "get")
2241-
subnet, err := subnets.Get(lbaas.network, memberSubnetID).Extract()
2236+
subnet, err := subnets.Get(lbaas.network, svcConf.lbMemberSubnetID).Extract()
22422237
if mc.ObserveRequest(err) != nil {
22432238
return fmt.Errorf(
2244-
"failed to find subnet %s from openstack: %v", memberSubnetID, err)
2239+
"failed to find subnet %s from openstack: %v", svcConf.lbMemberSubnetID, err)
22452240
}
22462241

22472242
etherType := rules.EtherType4
22482243
if netutils.IsIPv6CIDRString(subnet.CIDR) {
22492244
etherType = rules.EtherType6
22502245
}
2246+
cidrs := []string{subnet.CIDR}
2247+
if lbaas.opts.LBProvider == "ovn" {
2248+
// OVN keeps the source IP of the incoming traffic. This means that we cannot just open the LB range, but we
2249+
// need to open for the whole world. This can be restricted by using the service.spec.loadBalancerSourceRanges.
2250+
// svcConf.allowedCIDR will give us the ranges calculated by GetLoadBalancerSourceRanges() earlier.
2251+
cidrs = svcConf.allowedCIDR
2252+
}
22512253

22522254
existingRules, err := getSecurityGroupRules(lbaas.network, rules.ListOpts{SecGroupID: lbSecGroupID})
22532255
if err != nil {
@@ -2260,6 +2262,8 @@ func (lbaas *LbaasV2) ensureAndUpdateOctaviaSecurityGroup(clusterName string, ap
22602262
wantedRules := make([]rules.CreateOpts, 0, len(ports)+1)
22612263

22622264
if apiService.Spec.HealthCheckNodePort != 0 {
2265+
// TODO(dulek): How should this work with OVN…? Do we need to allow all?
2266+
// Probably the traffic goes from the compute node?
22632267
wantedRules = append(wantedRules,
22642268
rules.CreateOpts{
22652269
Direction: rules.DirIngress,
@@ -2277,17 +2281,19 @@ func (lbaas *LbaasV2) ensureAndUpdateOctaviaSecurityGroup(clusterName string, ap
22772281
if port.NodePort == 0 { // It's 0 when AllocateLoadBalancerNodePorts=False
22782282
continue
22792283
}
2280-
wantedRules = append(wantedRules,
2281-
rules.CreateOpts{
2282-
Direction: rules.DirIngress,
2283-
Protocol: rules.RuleProtocol(port.Protocol),
2284-
EtherType: etherType,
2285-
RemoteIPPrefix: subnet.CIDR,
2286-
SecGroupID: lbSecGroupID,
2287-
PortRangeMin: int(port.NodePort),
2288-
PortRangeMax: int(port.NodePort),
2289-
},
2290-
)
2284+
for _, cidr := range cidrs {
2285+
wantedRules = append(wantedRules,
2286+
rules.CreateOpts{
2287+
Direction: rules.DirIngress,
2288+
Protocol: rules.RuleProtocol(port.Protocol),
2289+
EtherType: etherType,
2290+
RemoteIPPrefix: cidr,
2291+
SecGroupID: lbSecGroupID,
2292+
PortRangeMin: int(port.NodePort),
2293+
PortRangeMax: int(port.NodePort),
2294+
},
2295+
)
2296+
}
22912297
}
22922298

22932299
toCreate, toDelete := getRulesToCreateAndDelete(wantedRules, existingRules)
@@ -2321,11 +2327,6 @@ func (lbaas *LbaasV2) ensureAndUpdateOctaviaSecurityGroup(clusterName string, ap
23212327
return nil
23222328
}
23232329

2324-
// updateSecurityGroup updating security group for specific loadbalancer service.
2325-
func (lbaas *LbaasV2) updateSecurityGroup(clusterName string, apiService *corev1.Service, nodes []*corev1.Node, memberSubnetID string) error {
2326-
return lbaas.ensureAndUpdateOctaviaSecurityGroup(clusterName, apiService, nodes, memberSubnetID)
2327-
}
2328-
23292330
// EnsureLoadBalancerDeleted deletes the specified load balancer
23302331
func (lbaas *LbaasV2) EnsureLoadBalancerDeleted(ctx context.Context, clusterName string, service *corev1.Service) error {
23312332
mc := metrics.NewMetricContext("loadbalancer", "delete")

0 commit comments

Comments
 (0)