Add support for LoadBalancerClass#1417
Conversation
8a331bb to
cd3800b
Compare
charts/metallb/README.md
Outdated
| | controller.tolerations | list | `[]` | | | ||
| | fullnameOverride | string | `""` | | | ||
| | imagePullSecrets | list | `[]` | | | ||
| | loadbalancerClass | string | `""` | | |
| } | ||
|
|
||
| if filterByLoadbalancerClass(service, r.LoadBalancerClass) { | ||
| level.Info(r.Logger).Log("controller", "ServiceReconciler", "filtered service", req.NamespacedName) |
There was a problem hiding this comment.
wdyt about having this and the other Debug? I'm inclined to think someone using this will apply the class to a small subset of services and could easily have a lot of these logs around.
| return ctrl.Result{}, err | ||
| } | ||
|
|
||
| if filterByLoadbalancerClass(service, r.LoadBalancerClass) { |
There was a problem hiding this comment.
iiuc loadBalancerClass is immutable, can we use this in this controller as a predicate?
There was a problem hiding this comment.
I tried, but I am getting failures because I am not getting passed service objects. I think it's because of when we get events for the endpoints, and at this point I am not sure it's worth having a complex predicate that switches over the object, considering there's no real performance benefit.
Also, I kind of like the symmetry between the reloader and the regular flow.
| func filterByLoadbalancerClass(service *v1.Service, loadBalancerClass string) bool { | ||
| // if it's a delete we can't make assumptions. We'll leverage the application code | ||
| // that will receive a delete of a non handled service. | ||
| if service == nil { |
There was a problem hiding this comment.
we can remove this if the service controller uses this func as a predicate (the service_reload_controller does not pass nils)
| return &res, nil | ||
| } | ||
|
|
||
| func filterByLoadbalancerClass(service *v1.Service, loadBalancerClass string) bool { |
controller/main.go
Outdated
| disableCertRotation = flag.Bool("disable-cert-rotation", false, "disable automatic generation and rotation of webhook TLS certificates/keys") | ||
| certDir = flag.String("cert-dir", "/tmp/k8s-webhook-server/serving-certs", "The directory where certs are stored") | ||
| certServiceName = flag.String("cert-service-name", "webhook-service", "The service name used to generate the TLS cert's hostname") | ||
| loadBalancerClass = flag.String("lbclass", "", "load balancer class. When enabled, metallb will handle only those services with the given lb class") |
There was a problem hiding this comment.
nit: lbclass -> lb-class (seems more consistent with the others)
suggestion for the description: only services whose spec.loadBalancerClass matches the given lb class will be handled. (I think it's worth mentioning that this corresponds to the loadBalancerClass field)
speaker/main.go
Outdated
| logLevel = flag.String("log-level", "info", fmt.Sprintf("log level. must be one of: [%s]", logging.Levels.String())) | ||
| disableEpSlices = flag.Bool("disable-epslices", false, "Disable the usage of EndpointSlices and default to Endpoints instead of relying on the autodiscovery mechanism") | ||
| enablePprof = flag.Bool("enable-pprof", false, "Enable pprof profiling") | ||
| loadBalancerClass = flag.String("lbclass", "", "load balancer class. When enabled, metallb will handle only those services with the given lb class") |
| framework.ExpectNoError(err) | ||
|
|
||
| jig := e2eservice.NewTestJig(cs, f.Namespace.Name, "lbclass") | ||
| ginkgo.By("creating a service " + jig.Namespace + "/" + jig.Name + " with type=LoadBalancer") |
There was a problem hiding this comment.
this is already logged by the framework
e2etest/pkg/service/tweak.go
Outdated
| func WithLoadbalancerClass(loadbalancerClass string) func(*corev1.Service) { | ||
| return func(svc *corev1.Service) { | ||
| svc.Spec.LoadBalancerClass = pointer.StrPtr(loadbalancerClass) | ||
| fmt.Println("FEDE lb class", svc.Spec.LoadBalancerClass) |
| MetalLB supports [LoadBalancerClass](https://kubernetes.io/docs/concepts/services-networking/service/#load-balancer-class), | ||
| which allows multiple LoadBalancers to co-exist. In order to set the loadbalancer class MetalLB should be listening | ||
| for, the `--lbclass=<CLASS_NAME>` parameter must be provided to both the spekaer and the controller. | ||
|
|
||
| The helm charts support it via the `loadbalancerClass` parameter. |
There was a problem hiding this comment.
nits:
multiple load balancer implementations/providers (like the k8s docs) ...
spekaer -> speaker
75d566c to
8f52444
Compare
oribon
left a comment
There was a problem hiding this comment.
2 small nits (sorry), other than that looks good
controller/main.go
Outdated
| disableCertRotation = flag.Bool("disable-cert-rotation", false, "disable automatic generation and rotation of webhook TLS certificates/keys") | ||
| certDir = flag.String("cert-dir", "/tmp/k8s-webhook-server/serving-certs", "The directory where certs are stored") | ||
| certServiceName = flag.String("cert-service-name", "webhook-service", "The service name used to generate the TLS cert's hostname") | ||
| loadBalancerClass = flag.String("lb-class", "", "load balancer class. When enabled, metallb will handle only services whose spec.loadBalancerClass matches the given lb class will be handled") |
speaker/main.go
Outdated
| logLevel = flag.String("log-level", "info", fmt.Sprintf("log level. must be one of: [%s]", logging.Levels.String())) | ||
| disableEpSlices = flag.Bool("disable-epslices", false, "Disable the usage of EndpointSlices and default to Endpoints instead of relying on the autodiscovery mechanism") | ||
| enablePprof = flag.Bool("enable-pprof", false, "Enable pprof profiling") | ||
| loadBalancerClass = flag.String("lb-class", "", "load balancer class. When enabled, metallb will handle only services whose spec.loadBalancerClass matches the given lb class will be handled") |
8f52444 to
26ab89c
Compare
Loadbalancer class enable different loadbalancers to co-exist. We add a parameter to the speaker and the controller to process only the services consistent with the loadbalancer class provided to metallb.
We expose a knob to set the loadbalancer class supported by metallb. Signed-off-by: Federico Paolinelli <fpaoline@redhat.com>
We can't change settings on the fly, but we want to cover the fact that metallb with no settings will ignore a service with loadbalancer class set. Signed-off-by: Federico Paolinelli <fpaoline@redhat.com>
We extend the docs with the newly added loadbalancer class parameter. Signed-off-by: Federico Paolinelli <fpaoline@redhat.com>
f22f69d to
aff8adc
Compare
The operator was using an old kubernetes version with no loadbalancer class support. Signed-off-by: Federico Paolinelli <fpaoline@redhat.com>
Add the ability to set a 'loadBalancerClass' value on the 'MetalLB' CRD. The 'Service.Spec.LoadBalancerClass' field reached GA in Kubernetes 1.24 and support was introduced in MetalLB in v0.13 [1]. [1] metallb/metallb#1417 Signed-off-by: Stephen Finucane <stephenfin@redhat.com> Closes: #267
Add the ability to set a 'loadBalancerClass' value on the 'MetalLB' CRD. The 'Service.Spec.LoadBalancerClass' field reached GA in Kubernetes 1.24 and support was introduced in MetalLB in v0.13 [1]. [1] metallb/metallb#1417 Signed-off-by: Stephen Finucane <stephenfin@redhat.com> Closes: metallb#267
Loadbalancer class enable different loadbalancers to co-exist. We add a parameter to the speaker and the controller to process only the services consistent with the loadbalancer class provided to metallb.
Fixes #685 and #996