diff --git a/daemon/container_operations.go b/daemon/container_operations.go index c9db37dc3c..8a58f149aa 100644 --- a/daemon/container_operations.go +++ b/daemon/container_operations.go @@ -47,7 +47,9 @@ func (daemon *Daemon) buildSandboxOptions(container *container.Container, n libn if container.HostConfig.NetworkMode.IsHost() { 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 && len(container.HostConfig.DNSSearch) == 0 && len(daemon.configStore.DNSSearch) == 0 && len(container.HostConfig.DNSOptions) == 0 && len(daemon.configStore.DNSOptions) == 0 { diff --git a/docs/reference/run.md b/docs/reference/run.md index 9fd6d05f43..567d42b207 100644 --- a/docs/reference/run.md +++ b/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 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 -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 `--hostname` is allowed in `host` network mode and will only change the 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* better networking performance since it uses the host's native networking stack diff --git a/integration-cli/docker_cli_netmode_test.go b/integration-cli/docker_cli_netmode_test.go index 62d4198e8d..2bcbecca14 100644 --- a/integration-cli/docker_cli_netmode_test.go +++ b/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) { 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()) } diff --git a/integration-cli/docker_cli_run_test.go b/integration-cli/docker_cli_run_test.go index a001a0eb5c..095c79a1de 100644 --- a/integration-cli/docker_cli_run_test.go +++ b/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, 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)) +} diff --git a/runconfig/hostconfig_unix.go b/runconfig/hostconfig_unix.go index a4860c4da3..1e196f6831 100644 --- a/runconfig/hostconfig_unix.go +++ b/runconfig/hostconfig_unix.go @@ -56,7 +56,7 @@ func ValidateNetMode(c *container.Config, hc *container.HostConfig) error { return ErrConflictNetworkAndDNS } - if (hc.NetworkMode.IsContainer() || hc.NetworkMode.IsHost()) && len(hc.ExtraHosts) > 0 { + if hc.NetworkMode.IsContainer() && len(hc.ExtraHosts) > 0 { return ErrConflictNetworkHosts }