Skip to content

Commit f5ca696

Browse files
authored
Merge pull request #515 from fahedouch/integrate-gvisor-tap-vsock-network-driver
Add gvisor-tap-vsock network driver support
2 parents ec6c63f + ae984d4 commit f5ca696

File tree

7 files changed

+715
-6
lines changed

7 files changed

+715
-6
lines changed

.github/workflows/main.yaml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,10 @@ jobs:
7070
run: |
7171
docker run --rm --privileged rootlesskit:test-integration ./integration-net.sh pasta
7272
docker run --rm --privileged rootlesskit:test-integration ./integration-net.sh pasta --detach-netns
73+
- name: "Integration test: Network (network driver=gvisor-tap-vsock)"
74+
run: |
75+
docker run --rm --privileged rootlesskit:test-integration ./integration-net.sh gvisor-tap-vsock
76+
docker run --rm --privileged rootlesskit:test-integration ./integration-net.sh gvisor-tap-vsock --detach-netns
7377
# ===== Benchmark: Network (MTU=1500) =====
7478
- name: "Benchmark: Network (MTU=1500, network driver=slirp4netns)"
7579
run: |
@@ -101,6 +105,14 @@ jobs:
101105
run: |
102106
docker run --rm --security-opt seccomp=unconfined --security-opt apparmor=unconfined --device /dev/net/tun \
103107
rootlesskit:test-integration ./benchmark-iperf3-net.sh pasta 1500 --detach-netns
108+
- name: "Benchmark: Network (MTU=1500, network driver=gvisor-tap-vsock)"
109+
run: |
110+
docker run --rm --security-opt seccomp=unconfined --security-opt apparmor=unconfined --device /dev/net/tun \
111+
rootlesskit:test-integration ./benchmark-iperf3-net.sh gvisor-tap-vsock 1500
112+
- name: "Benchmark: Network (MTU=1500, network driver=gvisor-tap-vsock) with detach-netns"
113+
run: |
114+
docker run --rm --security-opt seccomp=unconfined --security-opt apparmor=unconfined --device /dev/net/tun \
115+
rootlesskit:test-integration ./benchmark-iperf3-net.sh gvisor-tap-vsock 1500 --detach-netns
104116
- name: "Benchmark: Network (MTU=1500, network driver=lxc-user-nic)"
105117
run: |
106118
docker run --rm --privileged \
@@ -126,6 +138,10 @@ jobs:
126138
run: |
127139
docker run --rm --security-opt seccomp=unconfined --security-opt apparmor=unconfined --device /dev/net/tun \
128140
rootlesskit:test-integration ./benchmark-iperf3-net.sh pasta 65520
141+
- name: "Benchmark: Network (MTU=65520, network driver=gvisor-tap-vsock)"
142+
run: |
143+
docker run --rm --security-opt seccomp=unconfined --security-opt apparmor=unconfined --device /dev/net/tun \
144+
rootlesskit:test-integration ./benchmark-iperf3-net.sh gvisor-tap-vsock 65520
129145
- name: "Benchmark: Network (MTU=65520, network driver=lxc-user-nic)"
130146
run: |
131147
docker run --rm --privileged \
@@ -242,3 +258,10 @@ jobs:
242258
docker exec test docker info
243259
docker exec test ./integration-docker.sh
244260
docker rm -f test
261+
- name: "Docker Integration test: net=gvisor-tap-vsock, port-driver=builtin"
262+
run: |
263+
docker run -d --name test --network custom --privileged -e DOCKERD_ROOTLESS_ROOTLESSKIT_NET=gvisor-tap-vsock -e DOCKERD_ROOTLESS_ROOTLESSKIT_PORT_DRIVER=builtin rootlesskit:test-integration-docker
264+
sleep 2
265+
docker exec test docker info
266+
docker exec test ./integration-docker.sh
267+
docker rm -f test

cmd/rootlesskit/main.go

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import (
1919
"github.com/rootless-containers/rootlesskit/v2/pkg/child"
2020
"github.com/rootless-containers/rootlesskit/v2/pkg/common"
2121
"github.com/rootless-containers/rootlesskit/v2/pkg/copyup/tmpfssymlink"
22+
"github.com/rootless-containers/rootlesskit/v2/pkg/network/gvisortapvsock"
2223
"github.com/rootless-containers/rootlesskit/v2/pkg/network/lxcusernic"
2324
"github.com/rootless-containers/rootlesskit/v2/pkg/network/none"
2425
"github.com/rootless-containers/rootlesskit/v2/pkg/network/pasta"
@@ -97,7 +98,7 @@ See https://rootlesscontaine.rs/getting-started/common/ .
9798
}, CategoryState),
9899
Categorize(&cli.StringFlag{
99100
Name: "net",
100-
Usage: "network driver [host, none, pasta(experimental), slirp4netns, vpnkit, lxc-user-nic(experimental)]",
101+
Usage: "network driver [host, none, pasta(experimental), slirp4netns, vpnkit, lxc-user-nic(experimental), gvisor-tap-vsock(experimental)]",
101102
Value: "host",
102103
}, CategoryNetwork),
103104
Categorize(&cli.StringFlag{
@@ -142,7 +143,7 @@ See https://rootlesscontaine.rs/getting-started/common/ .
142143
}, CategoryNetwork),
143144
Categorize(&cli.StringFlag{
144145
Name: "cidr",
145-
Usage: "CIDR for pasta and slirp4netns networks (default: 10.0.2.0/24)",
146+
Usage: "CIDR for pasta, slirp4netns and gvisor-tap-vsock networks (default: 10.0.2.0/24)",
146147
}, CategoryNetwork),
147148
Categorize(&cli.StringFlag{
148149
Name: "ifname",
@@ -536,6 +537,35 @@ func createParentOpt(clicontext *cli.Context) (parent.Opt, error) {
536537
if err != nil {
537538
return opt, err
538539
}
540+
case "gvisor-tap-vsock":
541+
logrus.Warn("\"gvisor-tap-vsock\" network driver is experimental")
542+
if disableHostLoopback {
543+
logrus.Warn("\"--disable-host-loopback\" is not yet supported for gvisor-tap-vsock")
544+
}
545+
546+
if clicontext.String("cidr") != "" {
547+
ipnet, err = parseCIDR(clicontext.String("cidr"))
548+
if err != nil {
549+
return opt, err
550+
}
551+
} else {
552+
// Default CIDR for the virtual network
553+
_, ipnet, err = net.ParseCIDR("10.0.2.0/24")
554+
if err != nil {
555+
return opt, err
556+
}
557+
}
558+
559+
if clicontext.Bool("ipv6") {
560+
// virtual network does not support IPv6 yet
561+
// see https://github.com/containers/gvisor-tap-vsock/blob/v0.8.6/pkg/virtualnetwork/virtualnetwork.go#L102
562+
return opt, errors.New("--ipv6 is not supported for gvisor-tap-vsock")
563+
}
564+
565+
opt.NetworkDriver, err = gvisortapvsock.NewParentDriver(&logrusDebugWriter{label: "network/gvisor-tap-vsock"}, mtu, ipnet, ifname, disableHostLoopback, ipv6)
566+
if err != nil {
567+
return opt, err
568+
}
539569
default:
540570
return opt, fmt.Errorf("unknown network mode: %s", s)
541571
}
@@ -635,6 +665,8 @@ func createChildOpt(clicontext *cli.Context) (child.Opt, error) {
635665
opt.NetworkDriver = vpnkit.NewChildDriver()
636666
case "lxc-user-nic":
637667
opt.NetworkDriver = lxcusernic.NewChildDriver()
668+
case "gvisor-tap-vsock":
669+
opt.NetworkDriver = gvisortapvsock.NewChildDriver()
638670
default:
639671
return opt, fmt.Errorf("unknown network mode: %s", s)
640672
}

docs/network.md

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ RootlessKit provides several drivers for providing network connectivity:
77
* `--net=slirp4netns`: use [slirp4netns](https://github.com/rootless-containers/slirp4netns) (recommended)
88
* `--net=vpnkit`: use [VPNKit](https://github.com/moby/vpnkit)
99
* `--net=lxc-user-nic`: use `lxc-user-nic` (experimental)
10+
* `--net=gvisor-tap-vsock`: use [gvisor-tap-vsock](https://github.com/containers/gvisor-tap-vsock) (experimental)
1011

1112
[Benchmark: iperf3 from the child to the parent (Mar 8, 2020)](https://github.com/rootless-containers/rootlesskit/runs/492498728):
1213

@@ -207,6 +208,53 @@ You might need to reset `/var/lib/misc/dnsmasq.lxcbr0.leases` and restart the `l
207208

208209
Currently, the MAC address is always set to a random address.
209210

211+
### `--net=gvisor-tap-vsock` (experimental)
212+
213+
`--net=gvisor-tap-vsock` isolates the network namespace from the host and uses [gvisor-tap-vsock](https://github.com/containers/gvisor-tap-vsock) for providing usermode networking.
214+
215+
Pros:
216+
* Possible to perform network-namespaced operations, e.g. creating iptables rules, running `tcpdump`
217+
* Supports ICMP Echo (`ping`) when `/proc/sys/net/ipv4/ping_group_range` is configured
218+
219+
Cons:
220+
* Supports only TCP, UDP, and ICMP Echo packets
221+
* Does not support IPv6 routing (`--ipv6`)
222+
223+
The network is configured as follows by default:
224+
* IP: 10.0.2.100/24
225+
* Gateway: 10.0.2.1
226+
* DNS: 10.0.2.1
227+
228+
The network configuration can be changed by specifying custom CIDR, e.g. `--cidr=10.0.3.0/24`.
229+
230+
As in `--net=slirp4netns`, specifying `--copy-up=/etc` is highly recommended unless `/etc/resolv.conf` on the host is statically configured. It is also highly recommended to specify `--disable-host-loopback`. Otherwise ports listening on 127.0.0.1 in the host are accessible as 10.0.2.1 in the RootlessKit's network namespace.
231+
232+
Example session:
233+
234+
```console
235+
$ rootlesskit --net=gvisor-tap-vsock --copy-up=/etc --disable-host-loopback bash
236+
rootlesskit$ ip a
237+
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
238+
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
239+
inet 127.0.0.1/8 scope host lo
240+
valid_lft forever preferred_lft forever
241+
inet6 ::1/128 scope host
242+
valid_lft forever preferred_lft forever
243+
2: tap0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 65520 qdisc fq_codel state UP group default qlen 1000
244+
link/ether 1a:25:a3:a5:1d:03 brd ff:ff:ff:ff:ff:ff
245+
inet 10.0.2.100/24 scope global tap0
246+
valid_lft forever preferred_lft forever
247+
inet6 fe80::1825:a3ff:fea5:1d03/64 scope link
248+
valid_lft forever preferred_lft forever
249+
rootlesskit$ ip r
250+
default via 10.0.2.1 dev tap0
251+
10.0.2.0/24 dev tap0 proto kernel scope link src 10.0.2.100
252+
rootlesskit$ cat /etc/resolv.conf
253+
nameserver 10.0.2.1
254+
rootlesskit$ curl https://www.google.com
255+
<!doctype html><html ...>...</html>
256+
```
257+
210258
## IPv6
211259

212260
The `--ipv6` flag (since v0.14.0, EXPERIMENTAL) enables IPv6 routing for slirp4netns network driver.

go.mod

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ go 1.23.0
55
require (
66
github.com/Masterminds/semver/v3 v3.4.0
77
github.com/containernetworking/plugins v1.7.1
8+
github.com/containers/gvisor-tap-vsock v0.8.6
89
github.com/gofrs/flock v0.12.1
910
github.com/google/uuid v1.6.0
1011
github.com/gorilla/mux v1.8.1
@@ -19,11 +20,23 @@ require (
1920
)
2021

2122
require (
23+
github.com/Microsoft/go-winio v0.6.2 // indirect
24+
github.com/apparentlymart/go-cidr v1.1.0 // indirect
2225
github.com/cpuguy83/go-md2man/v2 v2.0.7 // indirect
26+
github.com/google/btree v1.1.2 // indirect
2327
github.com/google/go-cmp v0.7.0 // indirect
28+
github.com/google/gopacket v1.1.19 // indirect
29+
github.com/miekg/dns v1.1.65 // indirect
2430
github.com/pierrec/lz4/v4 v4.1.21 // indirect
31+
github.com/pkg/errors v0.9.1 // indirect
2532
github.com/russross/blackfriday/v2 v2.1.0 // indirect
2633
github.com/u-root/uio v0.0.0-20240224005618-d2acac8f3701 // indirect
2734
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect
35+
golang.org/x/crypto v0.38.0 // indirect
36+
golang.org/x/mod v0.24.0 // indirect
2837
golang.org/x/net v0.38.0 // indirect
38+
golang.org/x/sync v0.14.0 // indirect
39+
golang.org/x/time v0.5.0 // indirect
40+
golang.org/x/tools v0.31.0 // indirect
41+
gvisor.dev/gvisor v0.0.0-20240916094835-a174eb65023f // indirect
2942
)

0 commit comments

Comments
 (0)