This fix tries to address the issue raised in #21976 and allows
the options of `--dns`, `--dns-search`, `--dns-opt` 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>
| ... | ... |
@@ -48,7 +48,11 @@ func (daemon *Daemon) buildSandboxOptions(container *container.Container, n libn |
| 48 | 48 |
if container.HostConfig.NetworkMode.IsHost() {
|
| 49 | 49 |
sboxOptions = append(sboxOptions, libnetwork.OptionUseDefaultSandbox()) |
| 50 | 50 |
sboxOptions = append(sboxOptions, libnetwork.OptionOriginHostsPath("/etc/hosts"))
|
| 51 |
- sboxOptions = append(sboxOptions, libnetwork.OptionOriginResolvConfPath("/etc/resolv.conf"))
|
|
| 51 |
+ if len(container.HostConfig.DNS) == 0 && len(daemon.configStore.DNS) == 0 && |
|
| 52 |
+ len(container.HostConfig.DNSSearch) == 0 && len(daemon.configStore.DNSSearch) == 0 && |
|
| 53 |
+ len(container.HostConfig.DNSOptions) == 0 && len(daemon.configStore.DNSOptions) == 0 {
|
|
| 54 |
+ sboxOptions = append(sboxOptions, libnetwork.OptionOriginResolvConfPath("/etc/resolv.conf"))
|
|
| 55 |
+ } |
|
| 52 | 56 |
} else {
|
| 53 | 57 |
// OptionUseExternalKey is mandatory for userns support. |
| 54 | 58 |
// But optional for non-userns support |
| ... | ... |
@@ -382,11 +382,14 @@ name, they must be linked. |
| 382 | 382 |
With the network set to `host` a container will share the host's |
| 383 | 383 |
network stack and all interfaces from the host will be available to the |
| 384 | 384 |
container. The container's hostname will match the hostname on the host |
| 385 |
-system. Note that `--add-host` `--dns` `--dns-search` |
|
| 386 |
-`--dns-opt` and `--mac-address` are invalid in `host` netmode. Even in `host` |
|
| 385 |
+system. Note that `--add-host` and `--mac-address` are invalid in `host` netmode. Even in `host` |
|
| 387 | 386 |
network mode a container has its own UTS namespace by default. As such |
| 388 | 387 |
`--hostname` is allowed in `host` network mode and will only change the |
| 389 | 388 |
hostname inside the container. |
| 389 |
+Note also that `--dns`, `--dns-search` and `--dns-opt` are |
|
| 390 |
+valid in `host` mode and `/etc/resolv.conf` will be updated accordingly. However, the |
|
| 391 |
+update in `/etc/resolv.conf` only happens inside the container. No change will be |
|
| 392 |
+made for `/etc/resolv.conf` in host. |
|
| 390 | 393 |
|
| 391 | 394 |
Compared to the default `bridge` mode, the `host` mode gives *significantly* |
| 392 | 395 |
better networking performance since it uses the host's native networking stack |
| ... | ... |
@@ -2332,3 +2332,39 @@ func (s *DockerDaemonSuite) TestBuildOnDisabledBridgeNetworkDaemon(c *check.C) {
|
| 2332 | 2332 |
c.Assert(err, check.IsNil, comment) |
| 2333 | 2333 |
c.Assert(code, check.Equals, 0, comment) |
| 2334 | 2334 |
} |
| 2335 |
+ |
|
| 2336 |
+// Test case for #21976 |
|
| 2337 |
+func (s *DockerDaemonSuite) TestDaemonDnsInHostMode(c *check.C) {
|
|
| 2338 |
+ testRequires(c, SameHostDaemon, DaemonIsLinux) |
|
| 2339 |
+ |
|
| 2340 |
+ err := s.d.StartWithBusybox("--dns", "1.2.3.4")
|
|
| 2341 |
+ c.Assert(err, checker.IsNil) |
|
| 2342 |
+ |
|
| 2343 |
+ expectedOutput := "nameserver 1.2.3.4" |
|
| 2344 |
+ out, _ := s.d.Cmd("run", "--net=host", "busybox", "cat", "/etc/resolv.conf")
|
|
| 2345 |
+ c.Assert(out, checker.Contains, expectedOutput, check.Commentf("Expected '%s', but got %q", expectedOutput, out))
|
|
| 2346 |
+} |
|
| 2347 |
+ |
|
| 2348 |
+// Test case for #21976 |
|
| 2349 |
+func (s *DockerDaemonSuite) TestDaemonDnsSearchInHostMode(c *check.C) {
|
|
| 2350 |
+ testRequires(c, SameHostDaemon, DaemonIsLinux) |
|
| 2351 |
+ |
|
| 2352 |
+ err := s.d.StartWithBusybox("--dns-search", "example.com")
|
|
| 2353 |
+ c.Assert(err, checker.IsNil) |
|
| 2354 |
+ |
|
| 2355 |
+ expectedOutput := "search example.com" |
|
| 2356 |
+ out, _ := s.d.Cmd("run", "--net=host", "busybox", "cat", "/etc/resolv.conf")
|
|
| 2357 |
+ c.Assert(out, checker.Contains, expectedOutput, check.Commentf("Expected '%s', but got %q", expectedOutput, out))
|
|
| 2358 |
+} |
|
| 2359 |
+ |
|
| 2360 |
+// Test case for #21976 |
|
| 2361 |
+func (s *DockerDaemonSuite) TestDaemonDnsOptionsInHostMode(c *check.C) {
|
|
| 2362 |
+ testRequires(c, SameHostDaemon, DaemonIsLinux) |
|
| 2363 |
+ |
|
| 2364 |
+ err := s.d.StartWithBusybox("--dns-opt", "timeout:3")
|
|
| 2365 |
+ c.Assert(err, checker.IsNil) |
|
| 2366 |
+ |
|
| 2367 |
+ expectedOutput := "options timeout:3" |
|
| 2368 |
+ out, _ := s.d.Cmd("run", "--net=host", "busybox", "cat", "/etc/resolv.conf")
|
|
| 2369 |
+ c.Assert(out, checker.Contains, expectedOutput, check.Commentf("Expected '%s', but got %q", expectedOutput, out))
|
|
| 2370 |
+} |
| ... | ... |
@@ -67,10 +67,7 @@ func (s *DockerSuite) TestConflictContainerNetworkHostAndLinks(c *check.C) {
|
| 67 | 67 |
func (s *DockerSuite) TestConflictNetworkModeNetHostAndOptions(c *check.C) {
|
| 68 | 68 |
testRequires(c, DaemonIsLinux, NotUserNamespace) |
| 69 | 69 |
|
| 70 |
- out, _ := dockerCmdWithFail(c, "run", "--net=host", "--dns=8.8.8.8", "busybox", "ps") |
|
| 71 |
- c.Assert(out, checker.Contains, runconfig.ErrConflictNetworkAndDNS.Error()) |
|
| 72 |
- |
|
| 73 |
- out, _ = dockerCmdWithFail(c, "run", "--net=host", "--add-host=name:8.8.8.8", "busybox", "ps") |
|
| 70 |
+ out, _ := dockerCmdWithFail(c, "run", "--net=host", "--add-host=name:8.8.8.8", "busybox", "ps") |
|
| 74 | 71 |
c.Assert(out, checker.Contains, runconfig.ErrConflictNetworkHosts.Error()) |
| 75 | 72 |
|
| 76 | 73 |
out, _ = dockerCmdWithFail(c, "run", "--net=host", "--mac-address=92:d0:c6:0a:29:33", "busybox", "ps") |
| ... | ... |
@@ -4370,3 +4370,34 @@ func (s *DockerSuite) TestRunTooLongHostname(c *check.C) {
|
| 4370 | 4370 |
|
| 4371 | 4371 |
} |
| 4372 | 4372 |
} |
| 4373 |
+ |
|
| 4374 |
+// Test case for #21976 |
|
| 4375 |
+func (s *DockerSuite) TestRunDnsInHostMode(c *check.C) {
|
|
| 4376 |
+ testRequires(c, DaemonIsLinux, NotUserNamespace) |
|
| 4377 |
+ |
|
| 4378 |
+ expectedOutput := "nameserver 127.0.0.1" |
|
| 4379 |
+ expectedWarning := "Localhost DNS setting" |
|
| 4380 |
+ out, stderr, _ := dockerCmdWithStdoutStderr(c, "run", "--dns=127.0.0.1", "--net=host", "busybox", "cat", "/etc/resolv.conf") |
|
| 4381 |
+ c.Assert(out, checker.Contains, expectedOutput, check.Commentf("Expected '%s', but got %q", expectedOutput, out))
|
|
| 4382 |
+ c.Assert(stderr, checker.Contains, expectedWarning, check.Commentf("Expected warning on stderr about localhost resolver, but got %q", stderr))
|
|
| 4383 |
+ |
|
| 4384 |
+ expectedOutput = "nameserver 1.2.3.4" |
|
| 4385 |
+ out, _ = dockerCmd(c, "run", "--dns=1.2.3.4", "--net=host", "busybox", "cat", "/etc/resolv.conf") |
|
| 4386 |
+ c.Assert(out, checker.Contains, expectedOutput, check.Commentf("Expected '%s', but got %q", expectedOutput, out))
|
|
| 4387 |
+ |
|
| 4388 |
+ expectedOutput = "search example.com" |
|
| 4389 |
+ out, _ = dockerCmd(c, "run", "--dns-search=example.com", "--net=host", "busybox", "cat", "/etc/resolv.conf") |
|
| 4390 |
+ c.Assert(out, checker.Contains, expectedOutput, check.Commentf("Expected '%s', but got %q", expectedOutput, out))
|
|
| 4391 |
+ |
|
| 4392 |
+ expectedOutput = "options timeout:3" |
|
| 4393 |
+ out, _ = dockerCmd(c, "run", "--dns-opt=timeout:3", "--net=host", "busybox", "cat", "/etc/resolv.conf") |
|
| 4394 |
+ c.Assert(out, checker.Contains, expectedOutput, check.Commentf("Expected '%s', but got %q", expectedOutput, out))
|
|
| 4395 |
+ |
|
| 4396 |
+ expectedOutput1 := "nameserver 1.2.3.4" |
|
| 4397 |
+ expectedOutput2 := "search example.com" |
|
| 4398 |
+ expectedOutput3 := "options timeout:3" |
|
| 4399 |
+ out, _ = dockerCmd(c, "run", "--dns=1.2.3.4", "--dns-search=example.com", "--dns-opt=timeout:3", "--net=host", "busybox", "cat", "/etc/resolv.conf") |
|
| 4400 |
+ c.Assert(out, checker.Contains, expectedOutput1, check.Commentf("Expected '%s', but got %q", expectedOutput1, out))
|
|
| 4401 |
+ c.Assert(out, checker.Contains, expectedOutput2, check.Commentf("Expected '%s', but got %q", expectedOutput2, out))
|
|
| 4402 |
+ c.Assert(out, checker.Contains, expectedOutput3, check.Commentf("Expected '%s', but got %q", expectedOutput3, out))
|
|
| 4403 |
+} |
| ... | ... |
@@ -52,7 +52,7 @@ func ValidateNetMode(c *container.Config, hc *container.HostConfig) error {
|
| 52 | 52 |
return ErrConflictContainerNetworkAndLinks |
| 53 | 53 |
} |
| 54 | 54 |
|
| 55 |
- if (hc.NetworkMode.IsHost() || hc.NetworkMode.IsContainer()) && len(hc.DNS) > 0 {
|
|
| 55 |
+ if hc.NetworkMode.IsContainer() && len(hc.DNS) > 0 {
|
|
| 56 | 56 |
return ErrConflictNetworkAndDNS |
| 57 | 57 |
} |
| 58 | 58 |
|