Explorar el Código

Merge pull request #12667 from ibuildthecloud/host-uts

Add --uts=host to allow sharing the UTS namespace
Sebastiaan van Stijn hace 10 años
padre
commit
ed25742002

+ 5 - 0
daemon/container.go

@@ -335,6 +335,10 @@ func populateCommand(c *Container, env []string) error {
 	pid := &execdriver.Pid{}
 	pid.HostPid = c.hostConfig.PidMode.IsHost()
 
+	uts := &execdriver.UTS{
+		HostUTS: c.hostConfig.UTSMode.IsHost(),
+	}
+
 	// Build lists of devices allowed and created within the container.
 	var userSpecifiedDevices []*configs.Device
 	for _, deviceMapping := range c.hostConfig.Devices {
@@ -410,6 +414,7 @@ func populateCommand(c *Container, env []string) error {
 		Network:            en,
 		Ipc:                ipc,
 		Pid:                pid,
+		UTS:                uts,
 		Resources:          resources,
 		AllowedDevices:     allowedDevices,
 		AutoCreatedDevices: autoCreatedDevices,

+ 6 - 0
daemon/execdriver/driver.go

@@ -86,6 +86,11 @@ type Pid struct {
 	HostPid bool `json:"host_pid"`
 }
 
+// UTS settings of the container
+type UTS struct {
+	HostUTS bool `json:"host_uts"`
+}
+
 type NetworkInterface struct {
 	Gateway              string `json:"gateway"`
 	IPAddress            string `json:"ip"`
@@ -155,6 +160,7 @@ type Command struct {
 	Network            *Network          `json:"network"`
 	Ipc                *Ipc              `json:"ipc"`
 	Pid                *Pid              `json:"pid"`
+	UTS                *UTS              `json:"uts"`
 	Resources          *Resources        `json:"resources"`
 	Mounts             []Mount           `json:"mounts"`
 	AllowedDevices     []*configs.Device `json:"allowed_devices"`

+ 14 - 0
daemon/execdriver/native/create.go

@@ -29,6 +29,10 @@ func (d *driver) createContainer(c *execdriver.Command) (*configs.Config, error)
 		return nil, err
 	}
 
+	if err := d.createUTS(container, c); err != nil {
+		return nil, err
+	}
+
 	if err := d.createNetwork(container, c); err != nil {
 		return nil, err
 	}
@@ -173,6 +177,16 @@ func (d *driver) createPid(container *configs.Config, c *execdriver.Command) err
 	return nil
 }
 
+func (d *driver) createUTS(container *configs.Config, c *execdriver.Command) error {
+	if c.UTS.HostUTS {
+		container.Namespaces.Remove(configs.NEWUTS)
+		container.Hostname = ""
+		return nil
+	}
+
+	return nil
+}
+
 func (d *driver) setPrivileged(container *configs.Config) (err error) {
 	container.Capabilities = execdriver.GetAllCapabilities()
 	container.Cgroups.AllowAllDevices = true

+ 6 - 0
docs/man/docker-create.1.md

@@ -42,6 +42,7 @@ docker-create - Create a new container
 [**-P**|**--publish-all**[=*false*]]
 [**-p**|**--publish**[=*[]*]]
 [**--pid**[=*[]*]]
+[**--uts**[=*[]*]]
 [**--privileged**[=*false*]]
 [**--read-only**[=*false*]]
 [**--restart**[=*RESTART*]]
@@ -193,6 +194,11 @@ This value should always larger than **-m**, so you should alway use this with *
      **host**: use the host's PID namespace inside the container.
      Note: the host mode gives the container full access to local PID and is therefore considered insecure.
 
+**--uts**=host
+   Set the UTS mode for the container
+     **host**: use the host's UTS namespace inside the container.
+     Note: the host mode gives the container access to changing the host's hostname and is therefore considered insecure.
+
 **--privileged**=*true*|*false*
    Give extended privileges to this container. The default is *false*.
 

+ 6 - 0
docs/man/docker-run.1.md

@@ -43,6 +43,7 @@ docker-run - Run a command in a new container
 [**-P**|**--publish-all**[=*false*]]
 [**-p**|**--publish**[=*[]*]]
 [**--pid**[=*[]*]]
+[**--uts**[=*[]*]]
 [**--privileged**[=*false*]]
 [**--read-only**[=*false*]]
 [**--restart**[=*RESTART*]]
@@ -323,6 +324,11 @@ ports and the exposed ports, use `docker port`.
      **host**: use the host's PID namespace inside the container.
      Note: the host mode gives the container full access to local PID and is therefore considered insecure.
 
+**--uts**=host
+   Set the UTS mode for the container
+     **host**: use the host's UTS namespace inside the container.
+     Note: the host mode gives the container access to changing the host's hostname and is therefore considered insecure.
+
 **--privileged**=*true*|*false*
    Give extended privileges to this container. The default is *false*.
 

+ 3 - 0
docs/sources/reference/commandline/cli.md

@@ -991,6 +991,8 @@ Creates a new container.
       --oom-kill-disable=false   Whether to disable OOM Killer for the container or not
       -P, --publish-all=false    Publish all exposed ports to random ports
       -p, --publish=[]           Publish a container's port(s) to the host
+      --pid=""                   PID namespace to use
+      --uts=""                   UTS namespace to use
       --privileged=false         Give extended privileges to this container
       --read-only=false          Mount the container's root filesystem as read only
       --restart="no"             Restart policy (no, on-failure[:max-retry], always)
@@ -1958,6 +1960,7 @@ To remove an image using its digest:
       -P, --publish-all=false    Publish all exposed ports to random ports
       -p, --publish=[]           Publish a container's port(s) to the host
       --pid=""                   PID namespace to use
+      --uts=""                   UTS namespace to use
       --privileged=false         Give extended privileges to this container
       --read-only=false          Mount the container's root filesystem as read only
       --restart="no"             Restart policy (no, on-failure[:max-retry], always)

+ 18 - 0
docs/sources/reference/run.md

@@ -157,6 +157,7 @@ called a digest. As long as the input used to generate the image is unchanged,
 the digest value is predictable and referenceable.
 
 ## PID settings (--pid)
+
     --pid=""  : Set the PID (Process) Namespace mode for the container,
            'host': use the host's PID namespace inside the container
 
@@ -177,6 +178,23 @@ within the container.
 This command would allow you to use `strace` inside the container on pid 1234 on
 the host.
 
+## UTS settings (--uts)
+
+    --uts=""  : Set the UTS namespace mode for the container,
+           'host': use the host's UTS namespace inside the container
+
+The UTS namespace is for setting the hostname and the domain that is visible
+to running processes in that namespace.  By default, all containers, including
+those with `--net=host`, have their own UTS namespace.  The `host` setting will
+result in the container using the same UTS namespace as the host.
+
+You may wish to share the UTS namespace with the host if you would like the
+hostname of the container to change as the hostname of the host changes.  A
+more advanced use case would be changing the host's hostname from a container.
+
+> **Note**: `--uts="host"` gives the container full access to change the
+> hostname of the host and is therefore considered insecure.
+
 ## IPC settings (--ipc)
 
     --ipc=""  : Set the IPC mode for the container,

+ 32 - 0
integration-cli/docker_cli_run_test.go

@@ -2765,6 +2765,38 @@ func (s *DockerSuite) TestRunModePidHost(c *check.C) {
 	}
 }
 
+func (s *DockerSuite) TestRunModeUTSHost(c *check.C) {
+	testRequires(c, NativeExecDriver, SameHostDaemon)
+	defer deleteAllContainers()
+
+	hostUTS, err := os.Readlink("/proc/1/ns/uts")
+	if err != nil {
+		c.Fatal(err)
+	}
+
+	cmd := exec.Command(dockerBinary, "run", "--uts=host", "busybox", "readlink", "/proc/self/ns/uts")
+	out2, _, err := runCommandWithOutput(cmd)
+	if err != nil {
+		c.Fatal(err, out2)
+	}
+
+	out2 = strings.Trim(out2, "\n")
+	if hostUTS != out2 {
+		c.Fatalf("UTS different with --uts=host %s != %s\n", hostUTS, out2)
+	}
+
+	cmd = exec.Command(dockerBinary, "run", "busybox", "readlink", "/proc/self/ns/uts")
+	out2, _, err = runCommandWithOutput(cmd)
+	if err != nil {
+		c.Fatal(err, out2)
+	}
+
+	out2 = strings.Trim(out2, "\n")
+	if hostUTS == out2 {
+		c.Fatalf("UTS should be different without --uts=host %s == %s\n", hostUTS, out2)
+	}
+}
+
 func (s *DockerSuite) TestRunTLSverify(c *check.C) {
 	cmd := exec.Command(dockerBinary, "ps")
 	out, ec, err := runCommandWithOutput(cmd)

+ 22 - 0
runconfig/hostconfig.go

@@ -76,6 +76,27 @@ func (n IpcMode) Container() string {
 	return ""
 }
 
+type UTSMode string
+
+// IsPrivate indicates whether container use it's private UTS namespace
+func (n UTSMode) IsPrivate() bool {
+	return !(n.IsHost())
+}
+
+func (n UTSMode) IsHost() bool {
+	return n == "host"
+}
+
+func (n UTSMode) Valid() bool {
+	parts := strings.Split(string(n), ":")
+	switch mode := parts[0]; mode {
+	case "", "host":
+	default:
+		return false
+	}
+	return true
+}
+
 type PidMode string
 
 // IsPrivate indicates whether container use it's private pid stack
@@ -187,6 +208,7 @@ type HostConfig struct {
 	NetworkMode     NetworkMode
 	IpcMode         IpcMode
 	PidMode         PidMode
+	UTSMode         UTSMode
 	CapAdd          []string
 	CapDrop         []string
 	RestartPolicy   RestartPolicy

+ 7 - 0
runconfig/parse.go

@@ -52,6 +52,7 @@ func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSe
 		flNetwork         = cmd.Bool([]string{"#n", "#-networking"}, true, "Enable networking for this container")
 		flPrivileged      = cmd.Bool([]string{"#privileged", "-privileged"}, false, "Give extended privileges to this container")
 		flPidMode         = cmd.String([]string{"-pid"}, "", "PID namespace to use")
+		flUTSMode         = cmd.String([]string{"-uts"}, "", "UTS namespace to use")
 		flPublishAll      = cmd.Bool([]string{"P", "-publish-all"}, false, "Publish all exposed ports to random ports")
 		flStdin           = cmd.Bool([]string{"i", "-interactive"}, false, "Keep STDIN open even if not attached")
 		flTty             = cmd.Bool([]string{"t", "-tty"}, false, "Allocate a pseudo-TTY")
@@ -281,6 +282,11 @@ func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSe
 		return nil, nil, cmd, fmt.Errorf("--pid: invalid PID mode")
 	}
 
+	utsMode := UTSMode(*flUTSMode)
+	if !utsMode.Valid() {
+		return nil, nil, cmd, fmt.Errorf("--uts: invalid UTS mode")
+	}
+
 	restartPolicy, err := ParseRestartPolicy(*flRestartPolicy)
 	if err != nil {
 		return nil, nil, cmd, err
@@ -337,6 +343,7 @@ func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSe
 		NetworkMode:     netMode,
 		IpcMode:         ipcMode,
 		PidMode:         pidMode,
+		UTSMode:         utsMode,
 		Devices:         deviceMappings,
 		CapAdd:          flCapAdd.GetAll(),
 		CapDrop:         flCapDrop.GetAll(),