Browse code

Allow --hostname with --net=host

Docker creates a UTS namespace by default, even with --net=host, so it
is reasonable to let the user set the hostname. Note that --hostname is
forbidden if the user specifies --uts=host.

Closes #12076
Signed-off-by: Jason Heiss <jheiss@aput.net>

Jason Heiss authored on 2016/03/10 10:40:12
Showing 5 changed files
... ...
@@ -237,15 +237,13 @@ $ docker run -it --rm --pid=host myhtop
237 237
 The UTS namespace is for setting the hostname and the domain that is visible
238 238
 to running processes in that namespace.  By default, all containers, including
239 239
 those with `--net=host`, have their own UTS namespace.  The `host` setting will
240
-result in the container using the same UTS namespace as the host.
240
+result in the container using the same UTS namespace as the host.  Note that
241
+`--hostname` is invalid in `host` UTS mode.
241 242
 
242 243
 You may wish to share the UTS namespace with the host if you would like the
243 244
 hostname of the container to change as the hostname of the host changes.  A
244 245
 more advanced use case would be changing the host's hostname from a container.
245 246
 
246
-> **Note**: `--uts="host"` gives the container full access to change the
247
-> hostname of the host and is therefore considered insecure.
248
-
249 247
 ## IPC settings (--ipc)
250 248
 
251 249
     --ipc=""  : Set the IPC mode for the container,
... ...
@@ -365,8 +363,11 @@ name, they must be linked.
365 365
 With the network set to `host` a container will share the host's
366 366
 network stack and all interfaces from the host will be available to the
367 367
 container.  The container's hostname will match the hostname on the host
368
-system.  Note that `--add-host` `--hostname`  `--dns` `--dns-search`
369
-`--dns-opt` and `--mac-address` are invalid in `host` netmode.
368
+system.  Note that `--add-host` `--dns` `--dns-search`
369
+`--dns-opt` and `--mac-address` are invalid in `host` netmode. Even in `host`
370
+network mode a container has its own UTS namespace by default. As such
371
+`--hostname` is allowed in `host` network mode and will only change the
372
+hostname inside the container.
370 373
 
371 374
 Compared to the default `bridge` mode, the `host` mode gives *significantly*
372 375
 better networking performance since it uses the host's native networking stack
... ...
@@ -36,9 +36,6 @@ func (s *DockerSuite) TestNetHostname(c *check.C) {
36 36
 	out, _ = dockerCmd(c, "run", "-h=name", "--net=none", "busybox", "ps")
37 37
 	c.Assert(out, checker.Contains, stringCheckPS)
38 38
 
39
-	out, _ = dockerCmdWithFail(c, "run", "-h=name", "--net=host", "busybox", "ps")
40
-	c.Assert(out, checker.Contains, runconfig.ErrConflictNetworkHostname.Error())
41
-
42 39
 	out, _ = dockerCmdWithFail(c, "run", "-h=name", "--net=container:other", "busybox", "ps")
43 40
 	c.Assert(out, checker.Contains, runconfig.ErrConflictNetworkHostname.Error())
44 41
 
... ...
@@ -2539,6 +2539,9 @@ func (s *DockerSuite) TestRunModeUTSHost(c *check.C) {
2539 2539
 	if hostUTS == out {
2540 2540
 		c.Fatalf("UTS should be different without --uts=host %s == %s\n", hostUTS, out)
2541 2541
 	}
2542
+
2543
+	out, _ = dockerCmdWithFail(c, "run", "-h=name", "--uts=host", "busybox", "ps")
2544
+	c.Assert(out, checker.Contains, runconfig.ErrConflictUTSHostname.Error())
2542 2545
 }
2543 2546
 
2544 2547
 func (s *DockerSuite) TestRunTLSverify(c *check.C) {
... ...
@@ -35,4 +35,6 @@ var (
35 35
 	ErrUnsupportedNetworkNoSubnetAndIP = fmt.Errorf("User specified IP address is supported only when connecting to networks with user configured subnets")
36 36
 	// ErrUnsupportedNetworkAndAlias conflict between network mode and alias
37 37
 	ErrUnsupportedNetworkAndAlias = fmt.Errorf("Network-scoped alias is supported only for containers in user defined networks")
38
+	// ErrConflictUTSHostname conflict between the hostname and the UTS mode
39
+	ErrConflictUTSHostname = fmt.Errorf("Conflicting options: hostname and the UTS mode")
38 40
 )
... ...
@@ -36,10 +36,14 @@ func ValidateNetMode(c *container.Config, hc *container.HostConfig) error {
36 36
 		}
37 37
 	}
38 38
 
39
-	if (hc.NetworkMode.IsHost() || hc.NetworkMode.IsContainer()) && c.Hostname != "" {
39
+	if hc.NetworkMode.IsContainer() && c.Hostname != "" {
40 40
 		return ErrConflictNetworkHostname
41 41
 	}
42 42
 
43
+	if hc.UTSMode.IsHost() && c.Hostname != "" {
44
+		return ErrConflictUTSHostname
45
+	}
46
+
43 47
 	if hc.NetworkMode.IsHost() && len(hc.Links) > 0 {
44 48
 		return ErrConflictHostNetworkAndLinks
45 49
 	}