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

allow switching of port-forward approaches in rootless/using slirp4netns #6965

Merged
merged 4 commits into from
Jul 17, 2020

Conversation

giuseppe
Copy link
Member

As of podman 1.8.0, because of commit da7595a, the default approach of providing
port-forwarding in rootless mode has switched (and been hard-coded) to rootlessport,
for the purpose of providing super performance. The side-effect of this switch is
source within the container to the port-forwarded service always appears to originate
from 127.0.0.1 (see issue #5138).

This commit allows a user to specify if they want to revert to the previous approach
of leveraging slirp4netns add_hostfwd() api which, although not as stellar performance,
restores usefulness of seeing incoming traffic origin IP addresses.

The change should be transparent; when not specified, rootlessport will continue to be
used, however if specifying --net slirp4netns:slirplisten the old approach will be used.

Note: the above may imply the restored port-forwarding via slirp4netns is not as
performant as the new rootlessport approach, however the figures shared in the original
commit that introduced rootlessport are as follows:
slirp4netns: 8.3 Gbps,
RootlessKit: 27.3 Gbps,
which are more than sufficient for many use cases where the origin of traffic is more
important than limits that cannot be reached due to bottlenecks elsewhere.

Signed-off-by: Aleks Mariusz m.k@alek.cx
Signed-off-by: Giuseppe Scrivano gscrivan@redhat.com

Follow up for #6324

@openshift-ci-robot openshift-ci-robot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Jul 14, 2020
@aleks-mariusz
Copy link
Contributor

Hi @giuseppe to answer the question from the other thread (where i thought @AkihiroSuda was waiting for a @mheon as he last posted the review), i am interested in this feature still, however i'd be more interested if this was config file driven rather than command line parameter.. someone offered to look into doing this after the command line support was in, as it's beyond my famliarity with the code base (not to mention this is the first golang code i've ever touched).

@@ -70,7 +70,7 @@ func (c *Container) validate() error {

// Rootless has some requirements, compared to networks.
if rootless.IsRootless() {
if len(c.config.Networks) > 0 {
if !c.config.NetMode.IsSlirp4netns() {
Copy link
Member

Choose a reason for hiding this comment

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

I'm still against merging with this here - there's probably something on the frontend that's erroneously detecting slirp4netns:rootlesskit as a CNI network and adding it.

Copy link
Contributor

@aleks-mariusz aleks-mariusz Jul 14, 2020

Choose a reason for hiding this comment

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

understood, and i'm open to ideas what/where else may need to be adjusted to not need this "enabling" snippet in container_validate.go..

i don't however quite understand what is wrong with the logic applied here, why would the length of networks given ever be a non-empty array, networks shouldn't be able to be specified when rootless.. the fixing of the erroneous detection of that parameter seems like a separate bug that needs to be fixed/handled in a different PR, no ?

Copy link
Member Author

Choose a reason for hiding this comment

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

@mheon sorry my mistake. I had fixed the detection but forgot to switch the condition here. Pushed a new version with if len(c.config.Networks) > 0.

I am currently experimenting running CNI plugins inside of the rootless environment. So I cannot promise this line will stay around for long :-)

Copy link
Member

Choose a reason for hiding this comment

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

Fair enough - I'd be extremely interested to see proper rootless CNI!

Copy link
Member Author

Choose a reason for hiding this comment

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

it will still be limited. We first need to create a network namespace managed by slirp, and from that network namespace create new ones using CNI. I am still unsure how to handle its UX nicely

As of podman 1.8.0, because of commit da7595a, the default approach of providing
port-forwarding in rootless mode has switched (and been hard-coded) to rootlessport,
for the purpose of providing super performance. The side-effect of this switch is
source within the container to the port-forwarded service always appears to originate
from 127.0.0.1 (see issue containers#5138).

This commit allows a user to specify if they want to revert to the previous approach
of leveraging slirp4netns add_hostfwd() api which, although not as stellar performance,
restores usefulness of seeing incoming traffic origin IP addresses.

The change should be transparent; when not specified, rootlessport will continue to be
used, however if specifying --net slirp4netns:slirplisten the old approach will be used.

Note: the above may imply the restored port-forwarding via slirp4netns is not as
performant as the new rootlessport approach, however the figures shared in the original
commit that introduced rootlessport are as follows:
slirp4netns: 8.3 Gbps,
RootlessKit: 27.3 Gbps,
which are more than sufficient for many use cases where the origin of traffic is more
important than limits that cannot be reached due to bottlenecks elsewhere.

Signed-off-by: Aleks Mariusz <m.k@alek.cx>
Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
@giuseppe
Copy link
Member Author

tests are green

@mheon
Copy link
Member

mheon commented Jul 15, 2020

I'm still a little iffy on the throwing options in the namespace itself. We have other requests to allow setting arbitrary options on networks (#6912) - what would you think about having a separate entry (map[string][]string - map of network name (slirp4netns, bridge, etc) to options) in the database for network options? We can keep the existing CLI, but split on the : and anything after that is split on , and turns into a network option?

@giuseppe
Copy link
Member Author

@mheon is it something we can add to NetOptions?

@mheon
Copy link
Member

mheon commented Jul 15, 2020

@giuseppe That would work for me - I basically want a way to handle the next request after this one without duplicating all the plumbing.

@giuseppe
Copy link
Member Author

@giuseppe That would work for me - I basically want a way to handle the next request after this one without duplicating all the plumbing.

thanks. That was indeed a great idea. It looks much cleaner and it was easy to add a new option on top of it.

@AkihiroSuda
Copy link
Collaborator

LGTM but a nit in the man page. Thanks!

@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

@rhatdan
Copy link
Member

rhatdan commented Jul 16, 2020

@mheon PTAL

@@ -164,11 +165,17 @@ func NetFlagsToNetOptions(cmd *cobra.Command) (*entities.NetOptions, error) {
return nil, err
}

parts := strings.SplitN(network, ":", 2)
Copy link
Member

Choose a reason for hiding this comment

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

Recommendation: If length on this is 2, we should probably throw away cniNets below (options should only be given if you're not specifying more than 1 seems reasonable)

Copy link
Member Author

Choose a reason for hiding this comment

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

fixed

@mheon
Copy link
Member

mheon commented Jul 16, 2020

One comment, and it would be nice to have a test; otherwise LGTM

@giuseppe
Copy link
Member Author

One comment, and it would be nice to have a test; otherwise LGTM

took care of the comment and added tests

giuseppe added 3 commits July 16, 2020 22:37
do not pass network specific options through the network namespace.

Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
Closes: containers#6912

Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
@rhatdan
Copy link
Member

rhatdan commented Jul 16, 2020

/lgtm

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

mheon commented Jul 16, 2020

/hold
One flake

@openshift-ci-robot openshift-ci-robot added the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Jul 16, 2020
@giuseppe
Copy link
Member Author

tests are green now

/hold cancel

@openshift-ci-robot openshift-ci-robot removed the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Jul 17, 2020
@openshift-merge-robot openshift-merge-robot merged commit d86bae2 into containers:master Jul 17, 2020
@aleks-mariusz
Copy link
Contributor

@giuseppe thanks so much for driving this forward and finally getting it all preped, perfected, and merged!

quick follow up question, did this implement config-file handling as well? if so what params would need to go into which conf file to fix the original source-ip=127.0.0.1 issue that spawned this?

@giuseppe
Copy link
Member Author

quick follow up question, did this implement config-file handling as well? if so what params would need to go into which conf file to fix the original source-ip=127.0.0.1 issue that spawned this?

no, that part is not implemented yet, it is possible to specify the new option only through the CLI

@mheon
Copy link
Member

mheon commented Jul 17, 2020

Yes - we'll need a separate field for this in containers.conf

@andrewgdunn
Copy link

Did this make it into 2.0.3?

@mheon
Copy link
Member

mheon commented Jul 26, 2020

Negative - 2.0.3 is bugfixes only, this is a new feature.

I think we'll probably start cutting 2.1.0 release candidates soon, though - this week or next.

@DavidePrincipi
Copy link

Thanks for this PR!

The jvb component of Jitsi is an UDP server that needs IP addresses are preserved.

On podman 2.2.1 I can run

$ podman pod create --network=slirp4netns:port_handler=slirp4netns --publish 2086:80 --publish 10000:10000/udp --name=jitsi ...

https://gist.github.com/DavidePrincipi/6a45a7cfaf367115931eff3f50d1a681

@aleks-mariusz
Copy link
Contributor

aleks-mariusz commented Dec 15, 2020

Negative - 2.0.3 is bugfixes only, this is a new feature.

I think we'll probably start cutting 2.1.0 release candidates soon, though - this week or next.

@mheon does this imply the conf support is available as well? if so can you please point to the param needed and which file it needs to go into? this is a follow up to my previous ask (in July) to @giuseppe

@mheon
Copy link
Member

mheon commented Dec 15, 2020

The netns field in containers.conf should be what you want - setting that to slirp4netns:port_handler=slirp4netns should enable this by default

@barosl
Copy link

barosl commented Jan 1, 2021

The netns field in containers.conf should be what you want - setting that to slirp4netns:port_handler=slirp4netns should enable this by default

This doesn't seem to work. I tried the following:

[containers]
netns = 'slirp4netns:port_handler=slirp4netns'

@rktjmp
Copy link

rktjmp commented Jan 17, 2022

Edit: Sorry for the necro, got my years mixed up thinking the last post was only a few days ago, not ... a year ago...

The netns field in containers.conf should be what you want - setting that to slirp4netns:port_handler=slirp4netns should enable this by default

This doesn't seem to work. I tried the following:

[containers]
netns = 'slirp4netns:port_handler=slirp4netns'

I believe you want to use

[engine]
network_cmd_options=["port_handler=slirp4netns"]

Which sets Default options to pass to the slirp4netns binary.

The manpage also shows network_cmd_options["enable_ipv6=true",], for the option, which implies to me it's the default value, but the actual description for enable_ipv6 says the default is false, so... not sure. I guess just be aware that the option exists if something breaks.

Also be aware that unfortunately you cant mix the port_handler with user-defined networks, so the option might not apply in your case:

• port_handler=slirp4netns:
Use  the  slirp4netns  port forwarding, it is slower than
rootlesskit but preserves the correct source IP address.
This port handler cannot be used for user-defined networks.

@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 21, 2023
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Sep 21, 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.
Projects
None yet
Development

Successfully merging this pull request may close these issues.