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"}, 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[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[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 return res
})(), })(),
Expectation: []WorkspaceAndDepth{ Expectation: []WorkspaceAndDepth{
{PID: 2, D: 1, K: ProcessSandbox, C: "/proc/self/exe", W: ws}, {PID: 2, D: 1, K: ProcessSandbox, C: "/proc/self/exe", W: ws},
{PID: 3, D: 2, K: ProcessSupervisor, C: "supervisor", 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) fsshift = api.FSShiftMethod(v)
} }
var (
slirp4netnsSocket string
)
type mnte struct { type mnte struct {
Target string Target string
Source string Source string
@ -319,7 +315,6 @@ var ring1Cmd = &cobra.Command{
return return
} }
slirp4netnsSocket = filepath.Join(f, "slirp4netns.sock")
mnts = append(mnts, mnte{Target: "/.supervisor/slirp4netns.sock", Source: f, Flags: unix.MS_BIND | unix.MS_REC}) mnts = append(mnts, mnte{Target: "/.supervisor/slirp4netns.sock", Source: f, Flags: unix.MS_BIND | unix.MS_REC})
for _, m := range mnts { for _, m := range mnts {
@ -475,26 +470,6 @@ var ring1Cmd = &cobra.Command{
return 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) client, err = connectToInWorkspaceDaemonService(ctx)
if err != nil { if err != nil {
log.WithError(err).Error("cannot connect to daemon") log.WithError(err).Error("cannot connect to daemon")

View File

@ -2,17 +2,11 @@
# Licensed under the GNU Affero General Public License (AGPL). # Licensed under the GNU Affero General Public License (AGPL).
# See License-AGPL.txt in the project root for license information. # 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 FROM scratch
COPY components-workspacekit--app/workspacekit \ COPY components-workspacekit--app/workspacekit \
components-workspacekit--fuse-overlayfs/fuse-overlayfs \ components-workspacekit--fuse-overlayfs/fuse-overlayfs \
/.supervisor/ /.supervisor/
COPY --from=download /download/slirp4netns /.supervisor/
ARG __GIT_COMMIT ARG __GIT_COMMIT
ARG VERSION ARG VERSION

View File

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

View File

@ -42,7 +42,7 @@ func main() {
Action: specs.ActAllow, 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 // 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): // 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, // In order to reassociate itself with a new network, IPC, time,