mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Allow net and IPC namespaces to be shared when userns=on
Now that the namespace sharing code via runc is vendored with the containerd changes, we can disable the restrictions on container to container net and IPC namespace sharing when the daemon has user namespaces enabled. Docker-DCO-1.1-Signed-off-by: Phil Estes <estesp@linux.vnet.ibm.com> (github: estesp)
This commit is contained in:
parent
c22d09f563
commit
2b278f4846
3 changed files with 27 additions and 18 deletions
|
@ -518,15 +518,12 @@ func verifyPlatformContainerSettings(daemon *Daemon, hostConfig *containertypes.
|
||||||
if hostConfig.Privileged {
|
if hostConfig.Privileged {
|
||||||
return warnings, fmt.Errorf("Privileged mode is incompatible with user namespaces")
|
return warnings, fmt.Errorf("Privileged mode is incompatible with user namespaces")
|
||||||
}
|
}
|
||||||
if hostConfig.NetworkMode.IsHost() || hostConfig.NetworkMode.IsContainer() {
|
if hostConfig.NetworkMode.IsHost() {
|
||||||
return warnings, fmt.Errorf("Cannot share the host or a container's network namespace when user namespaces are enabled")
|
return warnings, fmt.Errorf("Cannot share the host's network namespace when user namespaces are enabled")
|
||||||
}
|
}
|
||||||
if hostConfig.PidMode.IsHost() {
|
if hostConfig.PidMode.IsHost() {
|
||||||
return warnings, fmt.Errorf("Cannot share the host PID namespace when user namespaces are enabled")
|
return warnings, fmt.Errorf("Cannot share the host PID namespace when user namespaces are enabled")
|
||||||
}
|
}
|
||||||
if hostConfig.IpcMode.IsContainer() {
|
|
||||||
return warnings, fmt.Errorf("Cannot share a container's IPC namespace when user namespaces are enabled")
|
|
||||||
}
|
|
||||||
if hostConfig.ReadonlyRootfs {
|
if hostConfig.ReadonlyRootfs {
|
||||||
return warnings, fmt.Errorf("Cannot use the --read-only option when user namespaces are enabled")
|
return warnings, fmt.Errorf("Cannot use the --read-only option when user namespaces are enabled")
|
||||||
}
|
}
|
||||||
|
|
|
@ -230,6 +230,18 @@ func delNamespace(s *specs.Spec, nsType specs.NamespaceType) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func setNamespaces(daemon *Daemon, s *specs.Spec, c *container.Container) error {
|
func setNamespaces(daemon *Daemon, s *specs.Spec, c *container.Container) error {
|
||||||
|
userNS := false
|
||||||
|
// user
|
||||||
|
if c.HostConfig.UsernsMode.IsPrivate() {
|
||||||
|
uidMap, gidMap := daemon.GetUIDGIDMaps()
|
||||||
|
if uidMap != nil {
|
||||||
|
userNS = true
|
||||||
|
ns := specs.Namespace{Type: "user"}
|
||||||
|
setNamespace(s, ns)
|
||||||
|
s.Linux.UIDMappings = specMapping(uidMap)
|
||||||
|
s.Linux.GIDMappings = specMapping(gidMap)
|
||||||
|
}
|
||||||
|
}
|
||||||
// network
|
// network
|
||||||
if !c.Config.NetworkDisabled {
|
if !c.Config.NetworkDisabled {
|
||||||
ns := specs.Namespace{Type: "network"}
|
ns := specs.Namespace{Type: "network"}
|
||||||
|
@ -240,6 +252,12 @@ func setNamespaces(daemon *Daemon, s *specs.Spec, c *container.Container) error
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
ns.Path = fmt.Sprintf("/proc/%d/ns/net", nc.State.GetPID())
|
ns.Path = fmt.Sprintf("/proc/%d/ns/net", nc.State.GetPID())
|
||||||
|
if userNS {
|
||||||
|
// to share a net namespace, they must also share a user namespace
|
||||||
|
nsUser := specs.Namespace{Type: "user"}
|
||||||
|
nsUser.Path = fmt.Sprintf("/proc/%d/ns/user", nc.State.GetPID())
|
||||||
|
setNamespace(s, nsUser)
|
||||||
|
}
|
||||||
} else if c.HostConfig.NetworkMode.IsHost() {
|
} else if c.HostConfig.NetworkMode.IsHost() {
|
||||||
ns.Path = c.NetworkSettings.SandboxKey
|
ns.Path = c.NetworkSettings.SandboxKey
|
||||||
}
|
}
|
||||||
|
@ -254,6 +272,12 @@ func setNamespaces(daemon *Daemon, s *specs.Spec, c *container.Container) error
|
||||||
}
|
}
|
||||||
ns.Path = fmt.Sprintf("/proc/%d/ns/ipc", ic.State.GetPID())
|
ns.Path = fmt.Sprintf("/proc/%d/ns/ipc", ic.State.GetPID())
|
||||||
setNamespace(s, ns)
|
setNamespace(s, ns)
|
||||||
|
if userNS {
|
||||||
|
// to share an IPC namespace, they must also share a user namespace
|
||||||
|
nsUser := specs.Namespace{Type: "user"}
|
||||||
|
nsUser.Path = fmt.Sprintf("/proc/%d/ns/user", ic.State.GetPID())
|
||||||
|
setNamespace(s, nsUser)
|
||||||
|
}
|
||||||
} else if c.HostConfig.IpcMode.IsHost() {
|
} else if c.HostConfig.IpcMode.IsHost() {
|
||||||
delNamespace(s, specs.NamespaceType("ipc"))
|
delNamespace(s, specs.NamespaceType("ipc"))
|
||||||
} else {
|
} else {
|
||||||
|
@ -269,16 +293,6 @@ func setNamespaces(daemon *Daemon, s *specs.Spec, c *container.Container) error
|
||||||
delNamespace(s, specs.NamespaceType("uts"))
|
delNamespace(s, specs.NamespaceType("uts"))
|
||||||
s.Hostname = ""
|
s.Hostname = ""
|
||||||
}
|
}
|
||||||
// user
|
|
||||||
if c.HostConfig.UsernsMode.IsPrivate() {
|
|
||||||
uidMap, gidMap := daemon.GetUIDGIDMaps()
|
|
||||||
if uidMap != nil {
|
|
||||||
ns := specs.Namespace{Type: "user"}
|
|
||||||
setNamespace(s, ns)
|
|
||||||
s.Linux.UIDMappings = specMapping(uidMap)
|
|
||||||
s.Linux.GIDMappings = specMapping(gidMap)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -792,11 +792,9 @@ The following standard Docker features are currently incompatible when
|
||||||
running a Docker daemon with user namespaces enabled:
|
running a Docker daemon with user namespaces enabled:
|
||||||
|
|
||||||
- sharing PID or NET namespaces with the host (`--pid=host` or `--net=host`)
|
- sharing PID or NET namespaces with the host (`--pid=host` or `--net=host`)
|
||||||
- sharing a network namespace with an existing container (`--net=container:*other*`)
|
|
||||||
- sharing an IPC namespace with an existing container (`--ipc=container:*other*`)
|
|
||||||
- A `--readonly` container filesystem (this is a Linux kernel restriction against remounting with modified flags of a currently mounted filesystem when inside a user namespace)
|
- A `--readonly` container filesystem (this is a Linux kernel restriction against remounting with modified flags of a currently mounted filesystem when inside a user namespace)
|
||||||
- external (volume or graph) drivers which are unaware/incapable of using daemon user mappings
|
- external (volume or graph) drivers which are unaware/incapable of using daemon user mappings
|
||||||
- Using `--privileged` mode flag on `docker run`
|
- Using `--privileged` mode flag on `docker run` (unless also specifying `--userns=host`)
|
||||||
|
|
||||||
In general, user namespaces are an advanced feature and will require
|
In general, user namespaces are an advanced feature and will require
|
||||||
coordination with other capabilities. For example, if volumes are mounted from
|
coordination with other capabilities. For example, if volumes are mounted from
|
||||||
|
|
Loading…
Reference in a new issue