Add config flag to disable usage of endpointslices#937
Add config flag to disable usage of endpointslices#937rata merged 1 commit intometallb:mainfrom Christoph-Raab:config-flag-to-disable-endpointslices
Conversation
|
@fedepaol Can you take a look? |
sure! |
|
@Christoph-Raab if I get this right, in the cluster you are mentioning the EndpointSliceProxying feature gate is disabled but EndpointSlice is enabled, so the CR is getting filled but it's not used. Just to understand, any reason why you did not go with disabling EndpointSlice too instead of modifying metallb? |
Exactly.
The main reason is that you can not disable the Endpointslices resource in the apiserver. So we would not only need to disable the endpointslices controller in the controller-manager, but also deny creating the resource and remove all existing ones. That's why we want a feature flag like core-dns has to disable the usage in the addon. |
But (and I may be wrong here), if you disable the controller in controller-manager via the EndpointSlice, ep slices won't be created (even though the resource is still available), and the automatic check should cover that: Line 611 in 4de2c0c Here we check if the kubernetes service doesn't have endpoint slices, and if so we assume that ep slices are disabled. Would that work or is that logic bugged somehow? |
|
You are correct that if you disable the controller, EndpointSlices will not be automatically created by kubernetes. But the resource still exists in the apiserver. So any user or addon/operator could still create EndpointSlices. So you need to forbid that operation as well, remove all existing ones (because they are no longer manged by the controller/user/addon/operator) and hope, that no user/addon/operator depends on them or something breaks, if they are not there/can not be created. It's much saver to disable them in metallb, where we are certain, that we don't want to use them and nothing breaks if we do so. |
Well, endpoints slices are not meant to be created by anything else than k8s. You could say the same thing about endpoints, if somebody creates a new endpoint manually you break the service. I understand on the other hand the fact that having to delete them is clunky, and that we did not think about this corner case where a cluster could switch from having them enabled to disabled.
|
controller/main.go
Outdated
| mlSecret = flag.String("ml-secret-name", os.Getenv("METALLB_ML_SECRET_NAME"), "name of the memberlist secret to create") | ||
| deployName = flag.String("deployment", os.Getenv("METALLB_DEPLOYMENT"), "name of the MetalLB controller Deployment") | ||
| logLevel = flag.String("log-level", "info", fmt.Sprintf("log level. must be one of: [%s]", strings.Join(logging.Levels, ", "))) | ||
| disableSlices = flag.Bool("disable-slices", false, "Disable the usage of endpointslices") |
There was a problem hiding this comment.
I'd call this disable-epslices and mention the fact that it defaults to endpoints in the description without relying on the autodiscovery mechanism
There was a problem hiding this comment.
Also, EndpointSlices or endpoint slices in the description
internal/k8s/k8s.go
Outdated
| // UseEndpointSlices detect if Endpoints Slices are enabled in the cluster. | ||
| func UseEndpointSlices(kubeClient kubernetes.Interface) bool { | ||
| func UseEndpointSlices(kubeClient kubernetes.Interface, cfg *Config) bool { | ||
| if cfg.DisableSlices { |
There was a problem hiding this comment.
Can you add a comment about the particular scenario (epslices enabled but disabled in the proxy) that we are covering with this parameter?
internal/k8s/k8s.go
Outdated
|
|
||
| if cfg.ReadEndpoints { | ||
| if !UseEndpointSlices(c.client) { | ||
| if !UseEndpointSlices(c.client, cfg) { |
There was a problem hiding this comment.
I'd change this to check the flag outside, seems more readable.
Something like if cfg.DisableEPSlices || !UseEndpointSlices(c.client) {
There was a problem hiding this comment.
Having all logic to determine if EndpointSlices should be used in one method seams like the reasonalbe thing to do, so I put it there. But I can change that.
Should I add a comment like I did in UseEndpointSlices? Or is it fine without that?
There was a problem hiding this comment.
Agree, but passing a flag just to return early won't add much value to the function itself I think. Might be different if we start using that in many different places, but that's not the current situation.
I'd move the comment too.
|
@Christoph-Raab sorry for not reviewing this before |
Also, mind adding the rationale to the commit message? Same thing you added as a comment. |
If set controller/speaker default to Endpoints without relying on the autodiscovery mechanism. Useful if EndpointSlices are enabled in the cluster but disabled in kube-proxy.
Sure, no problem |
|
lgtm , and thanks! |
rata
left a comment
There was a problem hiding this comment.
LGTM, thanks @Christoph-Raab and @fedepaol ! Will merge now.
However, some questions for both regarding a possible follow-up PR:
- Would it make sense in a future PR to try to detect this situation in "UseEndpointSlices()" without any need for a user-specified flag?
For example, we can look at the kubernetes service (to say an example) or some other service that should be present on any conformant clusters and see if endpoint slices are created for them? Or was that considered too hacky or there isn't such a service we can know to be present?
Or the issue is that endpoint slices are being created and updated, but we don't want to use them in metallb for some reason? What is the reason to not use them in metalLB if they are created and updated by k8s controllers?
I think I'm missing those details. Will merge this now, but please let me know what you think :)
The current code tries to do what you just described, against the k8s service, checking for the presence of epslices. There is one corner case though, where you can have the epslices enabled but kubeproxy instructed to consume endpoints, that is enabled by a feature flag and there's no way (I know of) to find it programmatically.
|
|
@fedepaol oh, you are right, on my quick look I missed that the current code is doing just that. Thanks! @Christoph-Raab just curious, in which scenario endpoint slices are created by the k8s controllers (I assume they have up to date information) but is problematic if MetalLB uses them? Do you hit a bug in MetalLB using endpoint slices? Or why MetalLB should not use them? In any case, if kube-proxy is doing this, I guess we can too... |
|
(on my phone) Is the flag name the same as kube-proxy ? If not does it make sense to use the same flag name ? |
We disabled endpointslices with kube-proxy but not in the whole cluster. So metallb would be using them but kube-proxy would still work with endpoints. We don't really trust that endpoints and endpointslices are in perfect sync so we rather want addons to use endpoints.
Kube-proxy uses a flag in the config map: We chose |
As discussed in #936 there are certain scenarios where endpointslices are technical available but should not be used by metallb.
This PR adds a config flag to disable the usage of endpointslices completely. If the flag is not provided the behaviour is the same as before.