-
Notifications
You must be signed in to change notification settings - Fork 881
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
fix port forwarding with ipv6.disable=1 #2635
Conversation
a4a3ac7
to
5e6322b
Compare
drivers/bridge/port_mapping.go
Outdated
@@ -50,6 +51,12 @@ func (n *bridgeNetwork) allocatePortsInternal(bindings []types.PortBinding, cont | |||
bs = append(bs, bIPv4) | |||
} | |||
|
|||
// skip adding v6 addr when the kernel was booted with `ipv6.disable=1` | |||
// https://github.com/moby/moby/issues/42288 | |||
if !IsV6Listenable() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The only case we need to fix here (I think...) is when 0.0.0.0 is passed.
If someone specifies a v6 address and we can't do that I don't think we should ignore it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand what was fixed.
I think the check for IsV6Listenable()
(or whwatever its called now) should go into https://github.com/moby/libnetwork/pull/2635/files#diff-5e6a1e1b6a7570d4362c2cfd293b0f05b409b6c9b1c8157b9832f427f6e0cf56L109 explicitly where we are checking if the bind address is 0.0.0.0
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
isV6Binding := c.HostIP != nil && c.HostIP.To4() == nil
is set to false when the bind address is 0.0.0.0
, and set to true when the bind address is set to IPv6 explicitly, so the issue was fixed IIUC.
Test matrix:
docker run -p 80:80
: listens on 0.0.0.0:80, without an errordocker run -p 0.0.0.0:80:80
: listens on 0.0.0.0:80, without an errordocker run -p [::]:80:80
: raises an error
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My point is we are already checking for 0.0.0.0 when validating the bind address, why not add the check when we do that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's also a bit less confusing because it is checking net.IPv4zero
specifically.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried that, but couldn't make it work
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry to be a stickler but I don't understand the check you have in place and how it works.
Meanwhile: https://play.golang.org/p/jtQGBQ4yzWd
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It should be able to implicitBinding := hostIP != nil && hostIp.Equal(net.IPv4zero)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@tianon helped me unbreak my brain here.
This seems like it's ok because we are checking if it is a v4 binding and only continuing if it is a v6-only binding which makes sense. It may also be that we actually have a nil host IP...
Make `docker run -p 80:80` functional again on environments with kernel boot parameter `ipv6.disable=1`. Fix moby/moby issue 42288 Signed-off-by: Akihiro Suda <[email protected]>
5e6322b
to
7b9c290
Compare
@moby/libnetwork @thaJeztah @tiborvass PTAL |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe a unit test for this?
Probably need to hijack the v6ListenableOnce in the test.
libnetwork/drivers/bridge/port_mapping.go Line 118 in b5dc370
IsV6Listenable
|
Help wanted for testing. Anyway, would it be possible to release v20.10.7 to provide the quick fix, and revisit the testing plan later? |
@AkihiroSuda could you have a look at @arkodg 's suggestion? If we're able to move the check inside that function, we can probably add a unit test for it at least |
docker-engine 20.10.6 broke container port forwarding for hosts without IPv6 support: docker: Error response from daemon: driver failed programming external connectivity on endpoint naughty_moore (038e9ed4b5ea77e1c52462d6d04ad001fbad9beb185a6511aadc217c8a271608): Error starting userland proxy: listen tcp6 [::]:80: socket: address family not supported by protocol. Add a libnetwork patch from an upstream pull request to fix this, after adjusting the patch to apply to docker-engine (which has libnetwork vendored under vendor/github.com/docker/libnetwork): - moby/libnetwork#2635, - moby/moby#42322 Signed-off-by: Peter Korsgaard <[email protected]>
docker-engine 20.10.6 broke container port forwarding for hosts without IPv6 support: docker: Error response from daemon: driver failed programming external connectivity on endpoint naughty_moore (038e9ed4b5ea77e1c52462d6d04ad001fbad9beb185a6511aadc217c8a271608): Error starting userland proxy: listen tcp6 [::]:80: socket: address family not supported by protocol. Add a libnetwork patch from an upstream pull request to fix this, after adjusting the patch to apply to docker-engine (which has libnetwork vendored under vendor/github.com/docker/libnetwork): - moby/libnetwork#2635, - moby/moby#42322 Signed-off-by: Peter Korsgaard <[email protected]> (cherry picked from commit 2fd3390) Signed-off-by: Peter Korsgaard <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM to get the fix in, but we should have a look at cleaning up in a follow up
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did some manual validation here to at least check the logic.
let me bring this one in and open a vendor PR in moby |
Since moby/libnetwork#2635 has been merged, allocatePortsInternal() checks if IPv6 is enabled by calling IsV6Listenable(). This function calls `net.Listen("tcp6", "[::1]:0")` and returns false when net.Listen() fails. TestPortMappingV6Config() starts by setting up a new net ns to run into it. The loopback interface is not bring up in this net ns, thus net.Listen() fails and IsV6Listenable() returns false. This change takes care of bringing loopback iface up right after moving to the new net ns. This test has been reported has flaky on s390x in moby#42468. For some reason, this test seems to be consistently green on the CI (on amd64 arch) and when running `hack/test/unit` locally. However it consistently fails when running `TESTFLAGS='-shuffle on' hack/test/unit` locally. Signed-off-by: Albin Kerouanton <[email protected]>
Since moby/libnetwork#2635 has been merged, allocatePortsInternal() checks if IPv6 is enabled by calling IsV6Listenable(). This function calls `net.Listen("tcp6", "[::1]:0")` and returns false when net.Listen() fails. TestPortMappingV6Config() starts by setting up a new net ns to run into it. The loopback interface is not bring up in this net ns, thus net.Listen() fails and IsV6Listenable() returns false. This change takes care of bringing loopback iface up right after moving to the new net ns. This test has been reported has flaky on s390x in moby#42468. For some reason, this test seems to be consistently green on the CI (on amd64 arch) and when running `hack/test/unit` locally. However it consistently fails when running `TESTFLAGS='-shuffle on' hack/test/unit` locally. Signed-off-by: Albin Kerouanton <[email protected]>
Since moby/libnetwork#2635 has been merged, allocatePortsInternal() checks if IPv6 is enabled by calling IsV6Listenable(). This function calls `net.Listen("tcp6", "[::1]:0")` and returns false when net.Listen() fails. TestPortMappingV6Config() starts by setting up a new net ns to run into it. The loopback interface is not bring up in this net ns, thus net.Listen() fails and IsV6Listenable() returns false. This change takes care of bringing loopback iface up right after moving to the new net ns. This test has been reported has flaky on s390x in #42468. For some reason, this test seems to be consistently green on the CI (on amd64 arch) and when running `hack/test/unit` locally. However it consistently fails when running `TESTFLAGS='-shuffle on' hack/test/unit` locally. Signed-off-by: Albin Kerouanton <[email protected]> Upstream-commit: c721bad8ccddeb353e71d4b4b26ad878d1ae8bee Component: engine
Since moby/libnetwork#2635 has been merged, allocatePortsInternal() checks if IPv6 is enabled by calling IsV6Listenable(). This function calls `net.Listen("tcp6", "[::1]:0")` and returns false when net.Listen() fails. TestPortMappingV6Config() starts by setting up a new net ns to run into it. The loopback interface is not bring up in this net ns, thus net.Listen() fails and IsV6Listenable() returns false. This change takes care of bringing loopback iface up right after moving to the new net ns. This test has been reported has flaky on s390x in moby#42468. For some reason, this test seems to be consistently green on the CI (on amd64 arch) and when running `hack/test/unit` locally. However it consistently fails when running `TESTFLAGS='-shuffle on' hack/test/unit` locally. Signed-off-by: Albin Kerouanton <[email protected]>
docker-engine 20.10.6 broke container port forwarding for hosts without IPv6 support: docker: Error response from daemon: driver failed programming external connectivity on endpoint naughty_moore (038e9ed4b5ea77e1c52462d6d04ad001fbad9beb185a6511aadc217c8a271608): Error starting userland proxy: listen tcp6 [::]:80: socket: address family not supported by protocol. Add a libnetwork patch from an upstream pull request to fix this, after adjusting the patch to apply to docker-engine (which has libnetwork vendored under vendor/github.com/docker/libnetwork): - moby/libnetwork#2635, - moby/moby#42322 Signed-off-by: Peter Korsgaard <[email protected]> (cherry picked from commit 2fd3390) Signed-off-by: Peter Korsgaard <[email protected]>
Make
docker run -p 80:80
functional again on environments with kernel boot parameteripv6.disable=1
.Fix moby/moby#42288
fixes #2629 Network issue with IPv6 following update to version 20.10.6
Tested on Ubuntu 21.04.
Previously,
docker run -p 80:80
withipv6.disable=1
was failing with an error:docker: Error response from daemon: driver failed programming external connectivity on endpoint naughty_moore (038e9ed4b5ea77e1c52462d6d04ad001fbad9beb185a6511aadc217c8a271608): Error starting userland proxy: listen tcp6 [::]:80: socket: address family not supported by protocol.