-
Notifications
You must be signed in to change notification settings - Fork 378
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
CPLB userspace reverse proxy load balancer #5279
Conversation
c7886ee
to
3682cf7
Compare
ac4e148
to
0910d28
Compare
0910d28
to
a651dbd
Compare
Got some feedback on the docs from Daniel, so I'm making it a draft temporarily |
This pull request has merge conflicts that need to be resolved. |
a651dbd
to
dfaf7d8
Compare
This pull request has merge conflicts that need to be resolved. |
dfaf7d8
to
cf158fb
Compare
tcpproxy is a subset of github.com/inetaf/tcpproxy with some modifications: 1- Implement the method SetRoutes to allow to set routes in bulk. Also allows deletion of routes which otherwise would be impossible. 2- Implement round robin load balancing (there was no load balancing at all). 3- Remove unused code. 4- Append Mirantis copyright for the modifications. Additionaly this PR had to do some modifications in the copyright linter script and `.golangci.yaml` because this is a file copied and modified. This is required to Apache 2.0 retribution right. Signed-off-by: Juan-Luis de Sousa-Valadas Castaño <[email protected]>
cf158fb
to
8220614
Compare
b0a4984
to
5c2c026
Compare
// The order that routes are added in matters; each is matched in the order | ||
// registered. | ||
type Proxy struct { | ||
configs map[string]*config // ip:port => config |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NB: There's the special type netip.AddrPort
for IP plus port number in the standard library, so this could be typed accordingly:
configs map[string]*config // ip:port => config | |
configs map[netip.AddrPort]*config |
I guess this would make the public Proxy API clearer as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since it's a private field, how about we leave the map as it is (a string is more convinient than a struct for the map) and we use netip.AddrPort in the public functions?
for _, c := range p.lns { | ||
c.Close() | ||
} | ||
return nil |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The errors are completely ignored here. Let's either remove the error return completely, or collect them instead.
for _, c := range p.lns { | |
c.Close() | |
} | |
return nil | |
var errs []error | |
for _, c := range p.lns { | |
if err := c.Close(); err != nil { | |
errs = append(errs, err) | |
} | |
} | |
return errors.Join(errs...) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a way to merge this with the other inttest, and call this multiple times, as we're doing it e.g. for the dualstack tests.
cmd/controller/controller.go
Outdated
if cplbCfg := nodeConfig.Spec.Network.ControlPlaneLoadBalancing; cplbCfg != nil && cplbCfg.Enabled { | ||
if c.SingleNode { | ||
return errors.New("control plane load balancing cannot be used in a single-node cluster") | ||
} | ||
|
||
if enableK0sEndpointReconciler { | ||
return errors.New("control plane load balancing requires the component 'endpoint-reconciler' to be disabled") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if there's some way of making this error message a bit more comprehensive 🤔
The message is technically correct, but might not be too helpful for folks to understand the connection between externalAddress and k0s's understanding of endpoint reconciliation...
aed0b18
to
5155c18
Compare
IPVS is problematic for many reasons, implement a userspace load balancer which should get the job done and should be far less problematic. Signed-off-by: Juan-Luis de Sousa-Valadas Castaño <[email protected]>
5155c18
to
ba2de2c
Compare
I addressed most of the comments. As for the comments: 1-Add tcpproxy remains unchanged for easier reviews There are a few things unchanged: |
// +kubebuilder:validation:Minimum=1 | ||
// +kubebuilder:validation:Maximum=65535 | ||
// +optional | ||
UserSpaceProxyPort int `json:"userSpaceProxyBindPort,omitempty"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about I add that in the subsequent PR?
SGTM
} | ||
|
||
fmt.Println("Waiting for updateCh") | ||
<-k.updateCh |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might be bit more clear if the func gets the context as param, that way the stop case is bit more clear IMO
The only reason why we block externalAddres is that we need a disabled endpoint-reconciler. It doesn't make sense to move all this logic and these parameters to the config validation, instead do it all in cmd. Signed-off-by: Juan-Luis de Sousa-Valadas Castaño <[email protected]>
1- Included userspace reverse proxy and made it the default option. 2- Explained better the difference between virtual IP and a load balancer, it was confusing for many users. 3- Added a whole troubleshooting section. Signed-off-by: Juan-Luis de Sousa-Valadas Castaño <[email protected]>
1- Simplify tcpproxy by reomivng useless interfaces: The original tcpproxy allowed different types of routes and needed to do a bunch of interfacing for it to work. Since we only implement one kind of route and one kind of target, we remove all the interfaces and merge both structs into a unique struct. 2- Remove proxy.AddRoute: We only used it once and setRoutes can cover that use case 3- Lock tcpproxy.Proxy when modifying routes to make it thread safe. Prior to this we relied on the proxy being called only from one goroutine. Now it can be called concurrently, not that we expect to do that but a lock gives us extra safety. 4- Panic if tcpproxy.SetRoutes gets and empty route list. We now check this in cplb_unix.go. 5- Remove the route feeding goroutine for round robin, since we added a lock to make proxy.SetRoutes threadsafe we don't need that anymore and it can be made much simpler by adding a lock. Signed-off-by: Juan-Luis de Sousa-Valadas Castaño <[email protected]>
ba2de2c
to
b133769
Compare
All issues addressed. Ready to review again. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM at this stage. This is getting really large already so I think we should merge this at this stage and address any further things in subsequent PRs.
@juanluisvaladas let's make sure we have tickets for the remaining issues to be addressed
This is one of the remaining tasks of k0sproject#5279. The intended use case for this is to allow to use the VIPs functionality while using some user provided load balancer such as HAProxy, nginx, etc... Signed-off-by: Juan-Luis de Sousa-Valadas Castaño <[email protected]>
This is one of the remaining tasks of k0sproject#5279. The intended use case for this is to allow to use the VIPs functionality while using some user provided load balancer such as HAProxy, nginx, etc... Also fixes some CPLB documentation mistakes spotted while fixing this. Signed-off-by: Juan-Luis de Sousa-Valadas Castaño <[email protected]> mend
This is one of the remaining tasks of k0sproject#5279. The intended use case for this is to allow to use the VIPs functionality while using some user provided load balancer such as HAProxy, nginx, etc... Also fixes some CPLB documentation mistakes spotted while fixing this. Signed-off-by: Juan-Luis de Sousa-Valadas Castaño <[email protected]> mend
This is one of the remaining tasks of k0sproject#5279. The intended use case for this is to allow to use the VIPs functionality while using some user provided load balancer such as HAProxy, nginx, etc... Also fixes some CPLB documentation mistakes spotted while fixing this. Signed-off-by: Juan-Luis de Sousa-Valadas Castaño <[email protected]> mend
This is one of the remaining tasks of k0sproject#5279. The intended use case for this is to allow to use the VIPs functionality while using some user provided load balancer such as HAProxy, nginx, etc... Also fixes some CPLB documentation mistakes spotted while fixing this. Signed-off-by: Juan-Luis de Sousa-Valadas Castaño <[email protected]>
Description
Implement userspace CPLB reverse proxy load balancer.
Due to the keepalived virtualservers using IPVS for the load balancing, we simply couldn't make it work on some environments and needed to implement a userspace reverse proxy.
Fixes #4700
Type of change
How Has This Been Tested?
Checklist: