Open tonistiigi opened 1 year ago
I like this idea a lot; a nice side-effect is that it seems like it would probably work if buildkitd was not root and spinning up rootless container via oci worker, thanks to running netstack in userspace?
A mild implementation-detail concern is how much a buildkit client (i.e. buildx, the dagger cli, etc.) is going to get bloated by importing+running wireguard's netstack, both in terms of binary size and performance overhead.
If the client is using the docker-container
connhelper and buildkitd->client connections are via session attachable (w/ grpc-in-grpc), I think at that point we'd be tunneling wireguard-over-grpc-over-grpc-over-stdio-pipes. Entirely possible that works great and doesn't matter, just seems like something to look out for.
spinning up rootless container via oci worker, thanks to running netstack in userspace?
Possibly yes. I guess that case creating a native wg interface would be too privileged.
A mild implementation-detail concern is how much a buildkit client (i.e. buildx, the dagger cli, etc.) is going to get bloated by importing+running wireguard's netstack, both in terms of binary size and performance overhead.
I haven't measured how big these imports are. On buildkitd side, it is needed. On client side, it would probably be a good idea to use a different import that enables the sessionpeer handler support
If the client is using the docker-container connhelper and buildkitd->client connections are via session attachable (w/ grpc-in-grpc), I think at that point we'd be tunneling wireguard-over-grpc-over-grpc-over-stdio-pipes. Entirely possible that works great and doesn't matter, just seems like something to look out for.
Potentially, for the moby and dagger engine case, we could have a new ClientOpt WithNetworkDialer
(bad name), similar to how today we have a WithSessionDialer
. The client could open a direct connection into a reachable endpoint, and then perform wireguard connections through there, without an intermediate GRPC tunneling layer.
ref https://github.com/moby/buildkit/issues/1337 ref https://github.com/moby/buildkit/pull/3960
Network dependencies can be created between:
All communication via WireGuard packets. No support or dependency for any custom CNI backend or special setup.
Implementation is based on go-wireguard/netstack https://pkg.go.dev/golang.zx2c4.com/wireguard@v0.0.0-20230704135630-469159ecf7d1/tun/netstack library. This is imported in client and buildkitd. buildkitd side can (optional) natively create WireGuard interface instead, but that would require that 2 BuildKit containers have discoverable endpoint between them (eg. simplest is to use CNI bridge for that).
There are no open ports or extra communication channels for network traffic. Everything is on the gRPC connection from session endpoint. Daemon side communication is either between buildkitd(running netstack) and tuntap device, or between two wireguard interfaces directly.
For that, instead of
conn.NewDefaultBind()
call above a custom implementation ofconn.Bind
is needed. https://pkg.go.dev/golang.zx2c4.com/wireguard@v0.0.0-20230704135630-469159ecf7d1/conn#BindEg. there is a new API registered in the Session endpoint that defines streaming endpoint that sends init/data/close etc packets that implement this interface.
netstack.CreateNetTun() https://pkg.go.dev/golang.zx2c4.com/wireguard@v0.0.0-20230704135630-469159ecf7d1/tun/netstack#CreateNetTUN
@vito @pchico83