-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
Use thread locking instead of clone hack for netns #3402
base: master
Are you sure you want to change the base?
Conversation
This uses gonso to setup the network namespace which is a thin wrapper around setns(2) that works out the details of locking/releasing go threads, can manage ns state, etc. Notably it does not require calling SYS_CLONE or setting up fork hooks for go (at least not for network namespaces). Signed-off-by: Brian Goff <[email protected]>
f5cf795
to
edf9106
Compare
Looks like this issue was already addressed in #3738 (this PR is actually older but looks like it got lost in review). The difference is still if we would want to use a library. Iiuc then Moby as well doesn't use that library atm. If the intention is to change that(and if using the library simplifies the code) we can make buildkit use it as well. There is another PR still open about umask that uses the same pattern(without extra library). |
FWIW I'd like to see us use this library in moby/moby; cc @corhere for thoughts on that. |
While there is significant overlap between gonso and github.com/docker/docker/internal/unshare I think they have different strengths. Gonso provides a far superior toolset for managing the lifecycles of namespaces, and unlike internal/unshare actually supports creating user namespaces, but I think it's a little heavy for the use case I designed internal/unshare for: just running a function in an ephemeral throwaway namespace. Compared to unshare.Go(unix.CLONE_NEWNS, func() error { return nil }, nil)
// open current ns, unshare, setns current ns, close gonso issues a lot more syscalls to do the same thing: c, _ := gonso.Current(gonso.NS_MNT) // open current ns
defer c.Close() // close current ns
s, _ := c.Unshare(gonso.NS_MNT) // unshare, open new ns, setns current ns
s.Do(func() error { return nil }) // open current ns, setns new ns, setns current ns
s.Close() // close new ns Also, gonso doesn't have an API to spawn a goroutine asynchronously. You'd have to call I think the two packages are complementary. And maybe with a bit of work gonso could be made to be no costlier than |
I think it depends on what being done. I played around with adding a raw "just unshare these namespaces and run my function":
BenchmarkUnshareAndDo is two different benchmarks:
These both should be compared with
Of note, with |
This uses gonso to setup the network namespace which is a thin wrapper around setns(2) that works out the details of locking/releasing go threads, can manage ns state, etc.
Notably it does not require calling SYS_CLONE or setting up fork hooks for go (at least not for network namespaces).
Also worth noting, the old implementation does not work with gccgo.