Skip to content
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

rootless: use RootlessKit port forwarder #4592

Conversation

AkihiroSuda
Copy link
Collaborator

@AkihiroSuda AkihiroSuda commented Nov 28, 2019

RootlessKit port forwarder has a lot of advantages over the slirp4netns port forwarder:

RootlessKit port forwarder has been already adopted as the default port forwarder by Rootless Docker/Moby, and no issue has been reported AFAIK w.r.t. TCP forwarding.

As the port forwarder is imported as a Go package, no rootlesskit binary is required for Podman.

Fix #4586
May-fix #4559
Fix #4537
May-fix #4311
Fix #4804

See https://github.com/rootless-containers/rootlesskit/tree/v0.7.1/pkg/port/builtin

Signed-off-by: Akihiro Suda [email protected]

@openshift-ci-robot openshift-ci-robot added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Nov 28, 2019
@openshift-ci-robot openshift-ci-robot added the size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. label Nov 28, 2019
@AkihiroSuda AkihiroSuda force-pushed the rootlesskit-port-forwarder branch 2 times, most recently from fcdd90d to 1d2583b Compare November 28, 2019 18:33
@AkihiroSuda AkihiroSuda changed the title [WIP] rootless: use RootlessKit port forwarder rootless: use RootlessKit port forwarder Nov 28, 2019
@openshift-ci-robot openshift-ci-robot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Nov 28, 2019
@giuseppe giuseppe self-requested a review November 28, 2019 19:55
@AkihiroSuda
Copy link
Collaborator Author

Is CI failure related?

@mheon
Copy link
Member

mheon commented Nov 29, 2019

Search tests? Probably a registry flake, I'll restart

@AkihiroSuda AkihiroSuda added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Nov 29, 2019
@AkihiroSuda AkihiroSuda changed the title rootless: use RootlessKit port forwarder [WIP] rootless: use RootlessKit port forwarder Nov 29, 2019
@AkihiroSuda
Copy link
Collaborator Author

Reverted to WIP due to an UDP issue: rootless-containers/rootlesskit#86

@giuseppe
Copy link
Member

I am impressed by the results, good work!

Is RootlessKit copying the connection from the listen socket on the host to the socket in the network namespace?

Is that something slirp4netns should also handle so that every slirp4netns user can benefit from?

@AkihiroSuda
Copy link
Collaborator Author

Is RootlessKit copying the connection from the listen socket on the host to the socket in the network namespace?

Only the FD of accept-ed socket in the parent is transferred across the namespaces.
Inside the child namespace, bidirectional io.Copy occurs for copying data across the FD and the actual port in the namespace.

Is that something slirp4netns should also handle so that every slirp4netns user can benefit from?

Not easy

@TomSweeneyRedHat
Copy link
Member

I just restarted the failing test in hopes that it's a flake....

@AkihiroSuda AkihiroSuda force-pushed the rootlesskit-port-forwarder branch from 1d2583b to a9d9b31 Compare December 18, 2019 10:26
@AkihiroSuda AkihiroSuda changed the title [WIP] rootless: use RootlessKit port forwarder rootless: use RootlessKit port forwarder Dec 18, 2019
@AkihiroSuda AkihiroSuda removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Dec 18, 2019
@AkihiroSuda
Copy link
Collaborator Author

UDP issue (rootless-containers/rootlesskit#86) was resolved in RootlessKit v0.7.1 (rootless-containers/rootlesskit#87).

Updated PR.

@AkihiroSuda
Copy link
Collaborator Author

Is CI passing or not?

@mheon
Copy link
Member

mheon commented Dec 18, 2019

Seems green to me

@mheon
Copy link
Member

mheon commented Dec 18, 2019

Hm. SPECIAL_TESTING_ROOTLESS failed, according to Cirrus

@AkihiroSuda
Copy link
Collaborator Author

Where is the failure log?

@mheon
Copy link
Member

mheon commented Dec 18, 2019

It should show up in Github automatically. I re-triggered the tests to hopefully fix things. If that doesn't work you might want to make a trivial change and force-push to retrigger CI

@rh-atomic-bot
Copy link
Collaborator

☔ The latest upstream changes (presumably #4730) made this pull request unmergeable. Please resolve the merge conflicts.

@AkihiroSuda AkihiroSuda force-pushed the rootlesskit-port-forwarder branch 2 times, most recently from b63d50e to aca41f8 Compare December 31, 2019 20:17
@AkihiroSuda
Copy link
Collaborator Author

AkihiroSuda commented Dec 31, 2019

reexec stuff doesn't seem working with podman run -d and hence CI is failing.
Anyone can help me?

@rhatdan
Copy link
Member

rhatdan commented Jan 2, 2020

@mheon @giuseppe PTAL

@giuseppe
Copy link
Member

giuseppe commented Jan 7, 2020

one thing to do is to inject the childQuit pipe into conmon, so that the process is not killed when podman exits:

diff --git a/libpod/container.go b/libpod/container.go
index 4f7fc067..d65fe4d1 100644
--- a/libpod/container.go
+++ b/libpod/container.go
@@ -133,6 +133,7 @@ type Container struct {
 
        rootlessSlirpSyncR *os.File
        rootlessSlirpSyncW *os.File
+       injectFDs []*os.File
 
        // A restored container should have the same IP address as before
        // being checkpointed. If requestedIP is set it will be used instead
diff --git a/libpod/networking_linux.go b/libpod/networking_linux.go
index df554d9b..83ba2f7b 100644
--- a/libpod/networking_linux.go
+++ b/libpod/networking_linux.go
@@ -342,9 +342,6 @@ func (r *Runtime) setupRootlessPortMapping(ctr *Container, netnsPath string) (er
        if err != nil {
                return err
        }
-       r.rootlessTeardown = append(r.rootlessTeardown, func() error {
-               return childQuitW.Close()
-       })
        // reexec the child process in the child netns
        cmd := exec.Command(fmt.Sprintf("/proc/%d/exe", os.Getpid()))
        cmd.Args = []string{reexecKeyRootlessPortChild}
@@ -362,6 +359,7 @@ func (r *Runtime) setupRootlessPortMapping(ctr *Container, netnsPath string) (er
        }); err != nil {
                return err
        }
        logrus.Debugf("rootless port: waiting for initComplete")
        // wait for the child to connect to the parent
        select {
@@ -374,6 +372,7 @@ func (r *Runtime) setupRootlessPortMapping(ctr *Container, netnsPath string) (er
                quit <- struct{}{}
                return nil
        })
+       ctr.injectFDs = append(ctr.injectFDs, childQuitW)
        // add ports
        ctx := context.TODO()
        for _, i := range ctr.config.PortMappings {
diff --git a/libpod/oci_conmon_linux.go b/libpod/oci_conmon_linux.go
index 026b1312..2a5dc65f 100644
--- a/libpod/oci_conmon_linux.go
+++ b/libpod/oci_conmon_linux.go
@@ -51,6 +51,7 @@ type ConmonOCIRuntime struct {
        supportsJSON      bool
        supportsNoCgroups bool
        sdNotify          bool
+       injectFiles       []*os.File
 }
 
 // Make a new Conmon-based OCI runtime with the given options.
@@ -949,6 +950,7 @@ func (r *ConmonOCIRuntime) createOCIContainer(ctr *Container, restoreOptions *Co
        cmd.Env = append(cmd.Env, conmonEnv...)
        cmd.ExtraFiles = append(cmd.ExtraFiles, childSyncPipe, childStartPipe)
        cmd.ExtraFiles = append(cmd.ExtraFiles, envFiles...)
+       cmd.ExtraFiles = append(cmd.ExtraFiles, ctr.injectFDs...)
 
        if r.reservePorts && !ctr.config.NetMode.IsSlirp4netns() {
                ports, err := bindPorts(ctr.config.PortMappings)

that is not enough though, as the RunParentDriver won't be running.

@AkihiroSuda could we move the RunParentDriver inside the new process? Something like passing down the open fd and let the new process do the handling?

@AkihiroSuda
Copy link
Collaborator Author

thanks, I'll look into that.

so that the process is not killed when podman exits:

How is this implemented to keep the process alive?
Couldn't find corresponding code in conmon.c .

@giuseppe
Copy link
Member

giuseppe commented Jan 7, 2020

How is this implemented to keep the process alive?
Couldn't find corresponding code in conmon.c .

the patch I've provided above does that. It passes a FD to conmon that will be kept open until conmon runs. When it exits, the FD passed down to conmon will be closed as well:

https://github.com/containers/conmon/blob/master/src/conmon.c#L1763-L1780

@AkihiroSuda AkihiroSuda force-pushed the rootlesskit-port-forwarder branch from aca41f8 to 8201f12 Compare January 8, 2020 09:31
@AkihiroSuda AkihiroSuda added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Jan 8, 2020
@AkihiroSuda AkihiroSuda force-pushed the rootlesskit-port-forwarder branch from 8201f12 to f7bfdce Compare January 8, 2020 10:31
@AkihiroSuda AkihiroSuda removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Jan 8, 2020
@AkihiroSuda AkihiroSuda force-pushed the rootlesskit-port-forwarder branch from f7bfdce to 0e248da Compare January 8, 2020 10:33
RootlessKit port forwarder has a lot of advantages over the slirp4netns port forwarder:

* Very high throughput.
  Benchmark result on Travis: socat: 5.2 Gbps, slirp4netns: 8.3 Gbps, RootlessKit: 27.3 Gbps
  (https://travis-ci.org/rootless-containers/rootlesskit/builds/597056377)

* Connections from the host are treated as 127.0.0.1 rather than 10.0.2.2 in the namespace.
  No UDP issue (containers#4586)

* No tcp_rmem issue (containers#4537)

* Probably works with IPv6. Even if not, it is trivial to support IPv6.  (containers#4311)

* Easily extensible for future support of SCTP

* Easily extensible for future support of `lxc-user-nic` SUID network

RootlessKit port forwarder has been already adopted as the default port forwarder by Rootless Docker/Moby,
and no issue has been reported AFAIK.

As the port forwarder is imported as a Go package, no `rootlesskit` binary is required for Podman.

Fix containers#4586
May-fix containers#4559
Fix containers#4537
May-fix containers#4311

See https://github.com/rootless-containers/rootlesskit/blob/v0.7.0/pkg/port/builtin/builtin.go

Signed-off-by: Akihiro Suda <[email protected]>
@AkihiroSuda
Copy link
Collaborator Author

Thanks, now it works with podman run -d

Copy link
Member

@giuseppe giuseppe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@openshift-ci-robot
Copy link
Collaborator

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: AkihiroSuda, giuseppe

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-ci-robot openshift-ci-robot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Jan 8, 2020
Copy link
Member

@vrothberg vrothberg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/lgtm

@openshift-ci-robot openshift-ci-robot added the lgtm Indicates that a PR is ready to be merged. label Jan 8, 2020
@vrothberg
Copy link
Member

@baude @mheon do we need to do a manual merge?

@openshift-merge-robot openshift-merge-robot merged commit b33c774 into containers:master Jan 8, 2020
@github-actions github-actions bot added the locked - please file new issue/PR Assist humans wanting to comment on an old issue or PR with locked comments. label Sep 25, 2023
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Sep 25, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files. lgtm Indicates that a PR is ready to be merged. locked - please file new issue/PR Assist humans wanting to comment on an old issue or PR with locked comments. size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files.
Projects
None yet
9 participants