Add --uts=host to allow sharing the UTS namespace

Signed-off-by: Darren Shepherd <darren@rancher.com>
This commit is contained in:
Darren Shepherd 2015-05-05 15:32:36 -07:00
parent 8eac7d0779
commit f2e5207fc9
10 changed files with 119 additions and 0 deletions

View file

@ -337,6 +337,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 {
@ -412,6 +416,7 @@ func populateCommand(c *Container, env []string) error {
Network: en,
Ipc: ipc,
Pid: pid,
UTS: uts,
Resources: resources,
AllowedDevices: allowedDevices,
AutoCreatedDevices: autoCreatedDevices,

View file

@ -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"`

View file

@ -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

View file

@ -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*.

View file

@ -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*.

View file

@ -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)

View file

@ -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,

View file

@ -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)

View file

@ -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

View file

@ -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(),