-
Notifications
You must be signed in to change notification settings - Fork 2.4k
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
Support publishing ports on specific network interfaces #14425
Comments
I agree that this would be useful. Not sure about the syntax why would this be the last option after the container port. What about That said implementing something like this is very complicated. They are at least 6 different ways that have to handle port forwarding.
These are just the current ones, they are likely more in the future:
Some of the projects are not maintained by us so it would be more difficult to get support for this or maybe they already have support it? |
I don't know if this is really possible for root Podman's network stack - there's really no firewall equivalent for that sockopt, so we'd basically be doing what we normally do, except looking up the IPs of the interface and using them instead of user-specified IPs. |
iptables has the |
A friendly reminder that this issue had no activity for 30 days. |
No, no work has been done as of yet |
A friendly reminder that this issue had no activity for 30 days. |
A friendly reminder that this issue had no activity for 30 days. |
By the way, I just submitted a patch for passt/pasta implementing this using Rationale: RFC 4007, section 11, introduces I actually plan to send a pull request for Podman integration of pasta soon (I'm still working on test scripts), based on the existing out-of-tree patch, now that some distribution packages are available, but I wouldn't include the possibility to specify this using Podman's own port forwarding configuration infrastructure yet, given that the handling of this feature for other networking modes isn't obvious at all. It would still be possible to configure this by passing opaque options directly to pasta. |
Since kernel version 5.7, commit c427bfec18f2 ("net: core: enable SO_BINDTODEVICE for non-root users"), we can bind sockets to interfaces, if they haven't been bound yet (as in bind()). Introduce an optional interface specification for forwarded ports, prefixed by %, that can be passed together with an address. Reported use case: running local services that use ports we want to have externally forwarded: containers/podman#14425 Signed-off-by: Stefano Brivio <[email protected]> Reviewed-by: David Gibson <[email protected]>
A side-note: An alternative to using the command-line option It's possible to use the systemd directive BindToDevice and combine it with socket activation of containers to publish a container port on a specific network interface. I verified that it works both for systemd system services (running as root) and for systemd user services (running as your regular user on the host). If the container image does not support socket activation, it's possible to create a work-around by using an additional container running The container image was built from this Containerfile
Here is a sketch
($myip is the host IP of the computer) I plan to write some more detailed step-by-step instructions. |
Erik, by the way:
while this looks elegant and it's probably a better fit for some use cases, you can do the same with Example from man page:
and this is also checked in tests. This is only available via opaque options at the moment ( |
Well we can add support to the As for other network backends we can just throw an error in podman that it is not supported. |
Yes, it makes sense to me, just:
I didn't think of this use case until now.
If you show me how/where or if you have some time to implement this, I can do the rest. |
First add a Then add it to the parsing logic here: podman/pkg/specgenutil/util.go Line 81 in 78f1ebb
And lastly make sure to throw an error if netmode != pasta and hostIp is not empty, do it somewhere in |
|
Somebody might want to bind listening sockets to a specific interface, but not a specific address, and there isn't really a reason to prevent that. For example: -t %eth0/2022 Alternatively, we support options such as -t 0.0.0.0%eth0/2022 and -t ::%eth0/2022, but not together, for the same port. Enable this kind of syntax and add examples to the man page. Reported-by: Paul Holzinger <[email protected]> Link: containers/podman#14425 (comment) Signed-off-by: Stefano Brivio <[email protected]>
What about binding a port/s from one container service to another container’s localhost kinda like a p2p link using Unix sockets? I imagine it should be much faster (pasta might be almost ready for this). |
This is a bit unrelated with the ticket at hand, but let me answer here for simplicity. I suppose the connections where you're looking for the megabazillion bits per second are TCP. You can indeed transfer data (not frames, not packets, just payload) between a TCP and a stream-oriented UNIX domain socket, for example with But you could also splice data (again, using a pipe) between two TCP sockets. This is what pasta already does between the container and its parent namespace: look at that orange appendage at the top left of the diagram. This is the implementation. It's not implemented between two arbitrary namespaces, because pasta at the moment takes care of a single network namespace or container, but you can already do this:
(you can pass equivalent options for Here we splice between four TCP sockets (first namespace to pasta, pasta to loopback in init namespace, loopback to pasta in init namespace, pasta to second namespace). If you want to splice between two sockets instead, you can probably write a separate tool doing that, but don't expect a big increase in throughput -- mind that the kernel copied exactly zero bytes for iperf3 above. However, sure, we have double syscall overhead compared to two sockets. Another alternative would be to let pasta take care of multiple namespaces, and then support a port forwarding specification where you don't just specify ports, addresses, interfaces, but also the target namespace. It requires a bit of rework, because at the moment the pasta implementation only supports the notion of "the detached namespace" as opposed to "wherever we run". If you want to work on this I'll be more than happy to give you pointers and assistance, let me know. |
/kind feature
Description
Right now we can publish a container’s port, or range of ports, to the host using
podman create … --publish [ip:][hostPort:]containerPort …
(et. al.). Even though we can indeed bind to a single IP address, we can't limit the binding to a single interface (usingSO_BINDTODEVICE
, see socket(7)). I suggest adding an option to support this, e.g.--publish [ip:][hostPort:]containerPort[@interface]
.Reasoning
Binding to an interface is used to limit the listener's scope to a single network interface, which can get quite important in VLAN setups. As we all know, this is different to listening to a single IP address which can, in fact, be used on multiple network interfaces at the same time.
However, personally I have another use case in mind: To better utilize
0.0.0.0
resp.::
. If I try publishing port 53 of a container running a DNS server, it will fail with a "bind: address already in use" error. This is expected behaviour, because Podman'sdnsname
plugin will start an Dnsmasq instance listening on0.0.0.0:53
, limited to the virtual network interface. Thus we can't bind to0.0.0.0
on all network interface, simply because the address is indeed partially in use by Podman's Dnsmasq. However, this doesn't have to be: If we could tell Podman to limit binding to a single interface usingSO_BINDTODEVICE
, we could indeed publish the container's port to0.0.0.0:53
, just limited to another device, e.g.enp1s0
. The option could be used likepodman create … --publish 53:53@enp1s0 …
.Side noteIsn't the documentation lacking info about limiting the protocol withedit: Fixed in #14451--publish ip:hostPort:containerPort/protocol
, e.g.80:80/tcp
?The text was updated successfully, but these errors were encountered: