Use veth instead of slirp4netns while preventing impact on supervisor.

This commit is contained in:
utam0k 2022-04-11 00:55:58 +00:00 committed by Robo Quat
parent f046782319
commit fa49f33dfa
5 changed files with 71 additions and 84 deletions

View File

@ -88,15 +88,13 @@ func TestFindWorkspaces(t *testing.T) {
Env: []string{"GITPOD_WORKSPACE_ID=foobar", "GITPOD_INSTANCE_ID=baz"},
}
res[3] = memoryProcEntry{P: &process{PID: 3, Parent: res[2].P, Cmdline: []string{"supervisor", "init"}}}
res[4] = memoryProcEntry{P: &process{PID: 4, Parent: res[2].P, Cmdline: []string{"slirp4netns"}}}
res[1].P.Children = []*process{res[2].P}
res[2].P.Children = []*process{res[3].P, res[4].P}
res[2].P.Children = []*process{res[3].P}
return res
})(),
Expectation: []WorkspaceAndDepth{
{PID: 2, D: 1, K: ProcessSandbox, C: "/proc/self/exe", W: ws},
{PID: 3, D: 2, K: ProcessSupervisor, C: "supervisor", W: ws},
{PID: 4, D: 2, K: ProcessUserWorkload, C: "slirp4netns", W: ws},
},
},
{

View File

@ -249,10 +249,6 @@ var ring1Cmd = &cobra.Command{
fsshift = api.FSShiftMethod(v)
}
var (
slirp4netnsSocket string
)
type mnte struct {
Target string
Source string
@ -319,7 +315,6 @@ var ring1Cmd = &cobra.Command{
return
}
slirp4netnsSocket = filepath.Join(f, "slirp4netns.sock")
mnts = append(mnts, mnte{Target: "/.supervisor/slirp4netns.sock", Source: f, Flags: unix.MS_BIND | unix.MS_REC})
for _, m := range mnts {
@ -475,26 +470,6 @@ var ring1Cmd = &cobra.Command{
return
}
slirpCmd := exec.Command(filepath.Join(filepath.Dir(ring2Opts.SupervisorPath), "slirp4netns"),
"--configure",
"--mtu=65520",
"--disable-host-loopback",
"--api-socket", slirp4netnsSocket,
strconv.Itoa(cmd.Process.Pid),
"tap0",
)
slirpCmd.SysProcAttr = &syscall.SysProcAttr{
Pdeathsig: syscall.SIGKILL,
}
err = slirpCmd.Start()
if err != nil {
log.WithError(err).Error("cannot start slirp4netns")
return
}
//nolint:errcheck
defer slirpCmd.Process.Kill()
client, err = connectToInWorkspaceDaemonService(ctx)
if err != nil {
log.WithError(err).Error("cannot connect to daemon")

View File

@ -2,17 +2,11 @@
# Licensed under the GNU Affero General Public License (AGPL).
# See License-AGPL.txt in the project root for license information.
FROM alpine:3.15 as download
ENV SLIRP4NETNS_VERSION=v1.1.12
WORKDIR /download
RUN wget https://github.com/rootless-containers/slirp4netns/releases/download/${SLIRP4NETNS_VERSION}/slirp4netns-x86_64 -O slirp4netns && chmod 755 slirp4netns
FROM scratch
COPY components-workspacekit--app/workspacekit \
components-workspacekit--fuse-overlayfs/fuse-overlayfs \
/.supervisor/
COPY --from=download /download/slirp4netns /.supervisor/
ARG __GIT_COMMIT
ARG VERSION

View File

@ -274,6 +274,10 @@ func main() {
IP: net.IPv4(10, 0, 5, 1),
Mask: mask,
}
cethIp := net.IPNet{
IP: net.IPv4(10, 0, 5, 2),
Mask: mask,
}
masqueradeAddr := net.IPNet{
IP: vethIp.IP.Mask(mask),
Mask: mask,
@ -351,56 +355,62 @@ func main() {
},
})
// TODO(toru): we can comment out here when we will remove the slirp4netns and set 10.0.5.1/24 as a default gw
// prerouting := nc.AddChain(&nftables.Chain{
// Name: "prerouting",
// Hooknum: nftables.ChainHookPrerouting,
// Priority: nftables.ChainPriorityFilter,
// Table: nat,
// Type: nftables.ChainTypeNAT,
// })
prerouting := nc.AddChain(&nftables.Chain{
Name: "prerouting",
Hooknum: nftables.ChainHookPrerouting,
Priority: nftables.ChainPriorityNATDest,
Table: nat,
Type: nftables.ChainTypeNAT,
})
// tcp dport 1-65535 dnat to $cethIp:tcp dport
// nc.AddRule(&nftables.Rule{
// Table: nat,
// Chain: prerouting,
// Exprs: []expr.Any{
// &expr.Meta{Key: expr.MetaKeyL4PROTO, Register: 1},
// &expr.Cmp{
// Op: expr.CmpOpEq,
// Register: 1,
// Data: []byte{unix.IPPROTO_TCP},
// },
// &expr.Payload{
// DestRegister: 1,
// Base: expr.PayloadBaseTransportHeader,
// Offset: 2,
// Len: 2,
// },
// iif $containerIf tcp dport 1-65535 dnat to $cethIp:tcp dport
nc.AddRule(&nftables.Rule{
Table: nat,
Chain: prerouting,
Exprs: []expr.Any{
&expr.Meta{Key: expr.MetaKeyIIFNAME, Register: 1},
&expr.Cmp{
Op: expr.CmpOpEq,
Register: 1,
Data: []byte(containerIf + "\x00"),
},
// &expr.Cmp{
// Op: expr.CmpOpGte,
// Register: 1,
// Data: []byte{0x00, 0x01},
// },
// &expr.Cmp{
// Op: expr.CmpOpLte,
// Register: 1,
// Data: []byte{0xff, 0xff},
// },
&expr.Meta{Key: expr.MetaKeyL4PROTO, Register: 1},
&expr.Cmp{
Op: expr.CmpOpEq,
Register: 1,
Data: []byte{unix.IPPROTO_TCP},
},
&expr.Payload{
DestRegister: 1,
Base: expr.PayloadBaseTransportHeader,
Offset: 2,
Len: 2,
},
// &expr.Immediate{
// Register: 2,
// Data: cethIp.IP.To4(),
// },
// &expr.NAT{
// Type: expr.NATTypeDestNAT,
// Family: unix.NFPROTO_IPV4,
// RegAddrMin: 2,
// RegProtoMin: 1,
// },
// },
// })
&expr.Cmp{
Op: expr.CmpOpGte,
Register: 1,
Data: []byte{0x00, 0x01},
},
&expr.Cmp{
Op: expr.CmpOpLte,
Register: 1,
Data: []byte{0xff, 0xff},
},
&expr.Immediate{
Register: 2,
Data: cethIp.IP.To4(),
},
&expr.NAT{
Type: expr.NATTypeDestNAT,
Family: unix.NFPROTO_IPV4,
RegAddrMin: 2,
RegProtoMin: 1,
},
},
})
if err := nc.Flush(); err != nil {
return xerrors.Errorf("failed to apply nftables: %v", err)
@ -419,6 +429,10 @@ func main() {
IP: net.IPv4(10, 0, 5, 2),
Mask: mask,
}
vethIp := net.IPNet{
IP: net.IPv4(10, 0, 5, 1),
Mask: mask,
}
cethLink, err := netlink.LinkByName(cethIf)
if err != nil {
@ -439,8 +453,14 @@ func main() {
return xerrors.Errorf("failed to enable lo: %v", err)
}
// TODO(toru): when we will complete implementing the dynamically ports exporsing,
// we have to implement changing default gw here.
defaultGw := netlink.Route{
Scope: netlink.SCOPE_UNIVERSE,
Gw: vethIp.IP,
}
if err := netlink.RouteReplace(&defaultGw); err != nil {
return xerrors.Errorf("failed to set up deafult gw: %v", err)
}
return nil
},
},

View File

@ -42,7 +42,7 @@ func main() {
Action: specs.ActAllow,
},
// slirp4netns requires setns, as do we for debugging
// Running docker on a workspace requires setns
// TODO(cw): find means to make this more precise, maybe an eBPF program that checks if
// arg zero is a child of this netns. The kernel already does that (from the setns(2) man page):
// In order to reassociate itself with a new network, IPC, time,