Browse Source

The option --add-host and --net=host should not be mutually exclusive.

This fix tries to address the issue raised in #21976 and allows
the options of `--add-host` and `--net=host` to work at the same time.

The documentation has been updated and additional tests have been
added to cover this change.

This fix fixes #21976.

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
Yong Tang 9 năm trước cách đây
mục cha
commit
90bd41a74d

+ 3 - 1
daemon/container_operations.go

@@ -47,7 +47,9 @@ func (daemon *Daemon) buildSandboxOptions(container *container.Container, n libn
 
 
 	if container.HostConfig.NetworkMode.IsHost() {
 	if container.HostConfig.NetworkMode.IsHost() {
 		sboxOptions = append(sboxOptions, libnetwork.OptionUseDefaultSandbox())
 		sboxOptions = append(sboxOptions, libnetwork.OptionUseDefaultSandbox())
-		sboxOptions = append(sboxOptions, libnetwork.OptionOriginHostsPath("/etc/hosts"))
+		if len(container.HostConfig.ExtraHosts) == 0 {
+			sboxOptions = append(sboxOptions, libnetwork.OptionOriginHostsPath("/etc/hosts"))
+		}
 		if len(container.HostConfig.DNS) == 0 && len(daemon.configStore.DNS) == 0 &&
 		if len(container.HostConfig.DNS) == 0 && len(daemon.configStore.DNS) == 0 &&
 			len(container.HostConfig.DNSSearch) == 0 && len(daemon.configStore.DNSSearch) == 0 &&
 			len(container.HostConfig.DNSSearch) == 0 && len(daemon.configStore.DNSSearch) == 0 &&
 			len(container.HostConfig.DNSOptions) == 0 && len(daemon.configStore.DNSOptions) == 0 {
 			len(container.HostConfig.DNSOptions) == 0 && len(daemon.configStore.DNSOptions) == 0 {

+ 5 - 5
docs/reference/run.md

@@ -382,14 +382,14 @@ name, they must be linked.
 With the network set to `host` a container will share the host's
 With the network set to `host` a container will share the host's
 network stack and all interfaces from the host will be available to the
 network stack and all interfaces from the host will be available to the
 container.  The container's hostname will match the hostname on the host
 container.  The container's hostname will match the hostname on the host
-system.  Note that `--add-host` and `--mac-address` are invalid in `host` netmode. Even in `host`
+system. Note that `--mac-address` is invalid in `host` netmode. Even in `host`
 network mode a container has its own UTS namespace by default. As such
 network mode a container has its own UTS namespace by default. As such
 `--hostname` is allowed in `host` network mode and will only change the
 `--hostname` is allowed in `host` network mode and will only change the
 hostname inside the container.
 hostname inside the container.
-Note also that `--dns`, `--dns-search` and `--dns-opt` are
-valid in `host` mode and `/etc/resolv.conf` will be updated accordingly. However, the
-update in `/etc/resolv.conf` only happens inside the container. No change will be
-made for `/etc/resolv.conf` in host.
+Similar to `--hostname`, the `--add-host`, `--dns`, `--dns-search`, and
+`--dns-opt` options can be used in `host` network mode. These options update
+`/etc/hosts` or `/etc/resolv.conf` inside the container. No change are made to
+`/etc/hosts` and `/etc/resolv.conf` on the host.
 
 
 Compared to the default `bridge` mode, the `host` mode gives *significantly*
 Compared to the default `bridge` mode, the `host` mode gives *significantly*
 better networking performance since it uses the host's native networking stack
 better networking performance since it uses the host's native networking stack

+ 1 - 4
integration-cli/docker_cli_netmode_test.go

@@ -67,10 +67,7 @@ func (s *DockerSuite) TestConflictContainerNetworkHostAndLinks(c *check.C) {
 func (s *DockerSuite) TestConflictNetworkModeNetHostAndOptions(c *check.C) {
 func (s *DockerSuite) TestConflictNetworkModeNetHostAndOptions(c *check.C) {
 	testRequires(c, DaemonIsLinux, NotUserNamespace)
 	testRequires(c, DaemonIsLinux, NotUserNamespace)
 
 
-	out, _ := dockerCmdWithFail(c, "run", "--net=host", "--add-host=name:8.8.8.8", "busybox", "ps")
-	c.Assert(out, checker.Contains, runconfig.ErrConflictNetworkHosts.Error())
-
-	out, _ = dockerCmdWithFail(c, "run", "--net=host", "--mac-address=92:d0:c6:0a:29:33", "busybox", "ps")
+	out, _ := dockerCmdWithFail(c, "run", "--net=host", "--mac-address=92:d0:c6:0a:29:33", "busybox", "ps")
 	c.Assert(out, checker.Contains, runconfig.ErrConflictContainerNetworkAndMac.Error())
 	c.Assert(out, checker.Contains, runconfig.ErrConflictContainerNetworkAndMac.Error())
 }
 }
 
 

+ 9 - 0
integration-cli/docker_cli_run_test.go

@@ -4401,3 +4401,12 @@ func (s *DockerSuite) TestRunDnsInHostMode(c *check.C) {
 	c.Assert(out, checker.Contains, expectedOutput2, check.Commentf("Expected '%s', but got %q", expectedOutput2, out))
 	c.Assert(out, checker.Contains, expectedOutput2, check.Commentf("Expected '%s', but got %q", expectedOutput2, out))
 	c.Assert(out, checker.Contains, expectedOutput3, check.Commentf("Expected '%s', but got %q", expectedOutput3, out))
 	c.Assert(out, checker.Contains, expectedOutput3, check.Commentf("Expected '%s', but got %q", expectedOutput3, out))
 }
 }
+
+// Test case for #21976
+func (s *DockerSuite) TestRunAddHostInHostMode(c *check.C) {
+	testRequires(c, DaemonIsLinux, NotUserNamespace)
+
+	expectedOutput := "1.2.3.4\textra"
+	out, _ := dockerCmd(c, "run", "--add-host=extra:1.2.3.4", "--net=host", "busybox", "cat", "/etc/hosts")
+	c.Assert(out, checker.Contains, expectedOutput, check.Commentf("Expected '%s', but got %q", expectedOutput, out))
+}

+ 1 - 1
runconfig/hostconfig_unix.go

@@ -56,7 +56,7 @@ func ValidateNetMode(c *container.Config, hc *container.HostConfig) error {
 		return ErrConflictNetworkAndDNS
 		return ErrConflictNetworkAndDNS
 	}
 	}
 
 
-	if (hc.NetworkMode.IsContainer() || hc.NetworkMode.IsHost()) && len(hc.ExtraHosts) > 0 {
+	if hc.NetworkMode.IsContainer() && len(hc.ExtraHosts) > 0 {
 		return ErrConflictNetworkHosts
 		return ErrConflictNetworkHosts
 	}
 	}