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
Add SO_REUSEPORT support for EntryPoints #9823
Comments
Hello @aofei , That's an interesting idea, but as often, we would probably wait to gauge the interest of the community before spending some time on it. However, I am personally interested in how you would do that. In a few words, how would you change the underlying net listeners in traefik so that they have SO_REUSEPORT enabled? thanks. |
Hi @mpl!
Just to be clear we are not replacing any existing What's off the top of my head is that we could introduce a new configuration option for EntryPoints, maybe a boolean ## Static configuration
entryPoints:
web:
address: ":80"
reusePort: true We can then decide whether to use our own
As for the actual implementation of the SO_REUSEPORT-enabled // (I know this seems too simple to be true. But that's all the code that needs to be written.)
//
// Usage:
// tcp80Listener, err := reusePortListenConfig.Listen(context.Background(), "tcp", "127.0.0.1:80")
// tcp443Listener, err := reusePortListenConfig.Listen(context.Background(), "tcp", "127.0.0.1:443")
// udp443PacketConn, err := reusePortListenConfig.ListenPacket(context.Background(), "udp", "127.0.0.1:443")
// udp53PacketConn, err := reusePortListenConfig.ListenPacket(context.Background(), "udp", "127.0.0.1:53")
// udp53Conn := udp53PacketConn.(*net.UDPConn)
var reusePortListenConfig = net.ListenConfig{
Control: func(_, _ string, c syscall.RawConn) error {
var err error
c.Control(func(fd uintptr) {
err = unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_REUSEADDR, 1)
if err != nil {
return
}
err = unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_REUSEPORT, 1)
if err != nil {
return
}
})
return err
},
} |
Ah, the last part (3.) is what I was missing. I didn't remember/know that ListenConfig existed, thanks. So, in 1. , you would not do a |
If Actually the |
Hi again @mpl! Just got some time, so I wrote an implementation and opened a PR for it. (#9834) Just to be clear, I get what you said about gauging the interest of the community first, and I respect that. I wrote the implementation just to show the Traefik Team how simple it is, and most importantly, how non-invasive it is. Hope this helps in the future when you decide whether to add this support. |
@aofei Hello, thanks for this - I was looking for this myself earlier this week. Could you possibly adjust your patch so that it uses SO_REUSEPORT_LB on FreeBSD - this is closer to what Linux does for the same option. |
@jpds Done. Thanks for the reminder, somehow I missed it. |
I would love to see SO_REUSEPORT added into Traefik. When updating configuration (using Consul-Template/Nomad) a new job/deploy is used and currently results in stopping/starting Traefik. Adding SO_REUSEPORT would allow updates with a much lower risk of downtime and an overall simpler configuration and deployment in this situation. |
Closed by #9834. |
Welcome!
What did you expect to see?
Somehow people never discuss SO_REUSEPORT here, but IMHO it can be very useful sometimes for a program like Traefik running on the very edge.
For example, if your Traefik occupies ports 80 and 443, then you have no way to gracefully upgrade or restart (currently the only way to reload the config) your Traefik without any service downtime. But with SO_REUSEPORT support, you can do canary deployments against Traefik. Just like its name, we can have two Traefik processes listen to the same TCP/UDP port (or, REUSE the same port).
Nginx supports reuseport, and it served us very well:
I think bringing SO_REUSEPORT into Traefik will be very easy, given that there are only a few
net.Listen*
calls here: https://github.com/search?q=repo%3Atraefik%2Ftraefik+language%3Ago+NOT+path%3A*_test.go+%2Fnet%5C.Listen%5Cw*%5C%28%2F&type=code.If the Traefik Team thinks it's good but doesn't have the bandwidth, I can help draft a PR. 🙂
The text was updated successfully, but these errors were encountered: