Skip to content

Commit 023da46

Browse files
committed
Merge pull request oracle#309 in OKE/oci-cloud-controller-manager from TASK/OKE-21137-release-1.23 to release-1.23
* commit 'c89c504da603b1a26076b896a0729e449134047a': Addition of node-label-selector property to load-balancer-annotations document Add support for filtering the nodes based on label selectors for an LB service by annotation
2 parents 3242794 + c89c504 commit 023da46

File tree

4 files changed

+334
-10
lines changed

4 files changed

+334
-10
lines changed

docs/load-balancer-annotations.md

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,11 @@ spec:
3434
| `oci-load-balancer-health-check-timeout` | The maximum time, in milliseconds, to wait for a reply to a [health check][6]. A [health check][6] is successful only if a reply returns within this timeout period. | `3000` |
3535
| `oci-load-balancer-health-check-interval` | The interval between [health checks][6] requests, in milliseconds. | `10000` |
3636
| `oci-load-balancer-connection-idle-timeout` | The maximum idle time, in seconds, allowed between two successive receive or two successive send operations between the client and backend servers. | `300` for TCP listeners, `60` for HTTP listeners |
37-
| `oci-load-balancer-security-list-management-mode` | Specifies the [security list mode](##security-list-management-modes) (`"All"`, `"Frontend"`,`"None"`) to configure how security lists are managed by the CCM. | `"All"`
38-
| `oci-load-balancer-backend-protocol` | Specifies protocol on which the listener accepts connection requests. To get a list of valid protocols, use the [`ListProtocols`][5] operation. | `"TCP"`
39-
| `loadbalancer-policy` | Specifies loadbalancer traffic policy for the loadbalancer. To get a list of valid policies, use the [`ListPolicies`][7] operation. | `"ROUND_ROBIN"`
40-
| `oci-network-security-groups` | Specifies Network Security Groups' OCIDs to be associated with the loadbalancer. Please refer [here][8] for NSG details. | `N/A`
37+
| `oci-load-balancer-security-list-management-mode` | Specifies the [security list mode](##security-list-management-modes) (`"All"`, `"Frontend"`,`"None"`) to configure how security lists are managed by the CCM. | `"All"` |
38+
| `oci-load-balancer-backend-protocol` | Specifies protocol on which the listener accepts connection requests. To get a list of valid protocols, use the [`ListProtocols`][5] operation. | `"TCP"` |
39+
| `loadbalancer-policy` | Specifies loadbalancer traffic policy for the loadbalancer. To get a list of valid policies, use the [`ListPolicies`][7] operation. | `"ROUND_ROBIN"` |
40+
| `oci-network-security-groups` | Specifies Network Security Groups' OCIDs to be associated with the loadbalancer. Please refer [here][8] for NSG details. | `N/A` |
41+
| `node-label-selector` | Specifies which nodes to add as a backend to the OCI Load Balancer and Network Load Balancer. | `N/A`|
4142

4243
Note:
4344
- Only one annotation `oci-load-balancer-subnet1` should be passed if it is a regional subnet.
@@ -50,11 +51,11 @@ Note:
5051
| `oci-load-balancer-ssl-ports` | A `,` separated list of port number(s) for which to enable SSL termination. | `""` |
5152

5253
## Security List Management Modes
53-
| Mode | Description |
54-
| ---- | ----------- |
55-
| `"All"` | CCM will manage all required security list rules for load balancer services |
56-
| `"Frontend"` | CCM will manage only security list rules for ingress to the load balancer. Requires that the user has setup a rule that allows inbound traffic to the appropriate ports for kube proxy health port, node port ranges, and health check port ranges. |
57-
| `"None`" | Disables all security list management. Requires that the user has setup a rule that allows inbound traffic to the appropriate ports for kube proxy health port, node port ranges, and health check port ranges. *Additionally, requires the user to mange rules to allow inbound traffic to load balancers.* |
54+
| Mode | Description |
55+
| ---- | ----------- |
56+
| `"All"` | CCM will manage all required security list rules for load balancer services |
57+
| `"Frontend"` | CCM will manage only security list rules for ingress to the load balancer. Requires that the user has setup a rule that allows inbound traffic to the appropriate ports for kube proxy health port, node port ranges, and health check port ranges. |
58+
| `"None`" | Disables all security list management. Requires that the user has setup a rule that allows inbound traffic to the appropriate ports for kube proxy health port, node port ranges, and health check port ranges. *Additionally, requires the user to mange rules to allow inbound traffic to load balancers.* |
5859

5960
Note:
6061
- If an invalid mode is passed in the annotation, then the default (`"All"`) mode is configured.

pkg/cloudprovider/providers/oci/load_balancer.go

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,13 +351,60 @@ func (clb *CloudLoadBalancerProvider) createLoadBalancer(ctx context.Context, sp
351351

352352
}
353353

354+
// getNodeFilter extracts the node filter based on load balancer type.
355+
// if no selector is defined then an all label selector object is returned to match everything.
356+
func getNodeFilter(svc *v1.Service) (labels.Selector, error) {
357+
lbType := getLoadBalancerType(svc)
358+
359+
var labelSelector string
360+
361+
switch lbType {
362+
case NLB:
363+
labelSelector = svc.Annotations[ServiceAnnotationNetworkLoadBalancerNodeFilter]
364+
default:
365+
labelSelector = svc.Annotations[ServiceAnnotationLoadBalancerNodeFilter]
366+
}
367+
368+
if labelSelector == "" {
369+
return labels.Everything(), nil
370+
}
371+
372+
return labels.Parse(labelSelector)
373+
}
374+
375+
// filterNodes based on the label selector, if present, and returns the set of nodes
376+
// that should be backends in the load balancer.
377+
func filterNodes(svc *v1.Service, nodes []*v1.Node) ([]*v1.Node, error) {
378+
379+
selector, err := getNodeFilter(svc)
380+
if err != nil {
381+
return nil, err
382+
}
383+
384+
var filteredNodes []*v1.Node
385+
for _, n := range nodes {
386+
if selector.Matches(labels.Set(n.GetLabels())) {
387+
filteredNodes = append(filteredNodes, n)
388+
}
389+
}
390+
391+
return filteredNodes, nil
392+
}
393+
354394
// EnsureLoadBalancer creates a new load balancer or updates the existing one.
355395
// Returns the status of the balancer (i.e it's public IP address if one exists).
356396
func (cp *CloudProvider) EnsureLoadBalancer(ctx context.Context, clusterName string, service *v1.Service, nodes []*v1.Node) (*v1.LoadBalancerStatus, error) {
357397
startTime := time.Now()
358398
lbName := GetLoadBalancerName(service)
359399
loadBalancerType := getLoadBalancerType(service)
360400
logger := cp.logger.With("loadBalancerName", lbName, "serviceName", service.Name, "loadBalancerType", loadBalancerType)
401+
402+
nodes, err := filterNodes(service, nodes)
403+
if err != nil {
404+
logger.With(zap.Error(err)).Error("Failed to filter nodes with label selector")
405+
return nil, err
406+
}
407+
361408
logger.With("nodes", len(nodes)).Info("Ensuring load balancer")
362409

363410
dimensionsMap := make(map[string]string)

pkg/cloudprovider/providers/oci/load_balancer_spec.go

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,10 @@ const (
138138

139139
// ServiceAnnotationLoadBalancerType is a service annotation for specifying lb type
140140
ServiceAnnotationLoadBalancerType = "oci.oraclecloud.com/load-balancer-type"
141+
142+
// ServiceAnnotationLoadBalancerNodeFilter is a service annotation to select specific nodes as your backend in the LB
143+
// based on label selector.
144+
ServiceAnnotationLoadBalancerNodeFilter = "oci.oraclecloud.com/node-label-selector"
141145
)
142146

143147
// NLB specific annotations
@@ -191,6 +195,10 @@ const (
191195
// ServiceAnnotationNetworkLoadBalancerInitialFreeformTagsOverride is a service annotation for specifying
192196
// freeform tags on the nlb
193197
ServiceAnnotationNetworkLoadBalancerInitialFreeformTagsOverride = "oci-network-load-balancer.oraclecloud.com/initial-freeform-tags-override"
198+
199+
// ServiceAnnotationNetworkLoadBalancerNodeFilter is a service annotation to select specific nodes as your backend in the NLB
200+
// based on label selector.
201+
ServiceAnnotationNetworkLoadBalancerNodeFilter = "oci-network-load-balancer.oraclecloud.com/node-label-selector"
194202
)
195203

196204
// certificateData is a structure containing the data about a K8S secret required
@@ -502,11 +510,17 @@ func getBackends(logger *zap.SugaredLogger, nodes []*v1.Node, nodePort int32) []
502510
logger.Warnf("Node %q has an empty Internal IP address.", node.Name)
503511
continue
504512
}
513+
instanceID, err := MapProviderIDToInstanceID(node.Spec.ProviderID)
514+
if err != nil {
515+
logger.Warnf("Node %q has an empty ProviderID.", node.Name)
516+
continue
517+
}
518+
505519
backends = append(backends, client.GenericBackend{
506520
IpAddress: nodeAddressString,
507521
Port: common.Int(int(nodePort)),
508522
Weight: common.Int(1),
509-
TargetId: &node.Spec.ProviderID,
523+
TargetId: &instanceID,
510524
})
511525
}
512526
return backends

0 commit comments

Comments
 (0)