mirror of https://github.com/docker/docs.git
Merge pull request #21383 from estesp/shared-userns-net-ipc
Allow net and IPC namespaces to be shared when userns=on
This commit is contained in:
commit
62d4556654
|
@ -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 New Issue