diff --git a/cmd/dockerd/config_unix.go b/cmd/dockerd/config_unix.go index 1817c1da271d9cd57f5780e61c2ea500a4cb27bf..8cc11ae0a9408b9c1d6d696fd6ce36849702bdac 100644 --- a/cmd/dockerd/config_unix.go +++ b/cmd/dockerd/config_unix.go @@ -9,6 +9,7 @@ import ( "github.com/docker/docker/opts" "github.com/docker/docker/rootless" units "github.com/docker/go-units" + "github.com/opencontainers/runc/libcontainer/cgroups" "github.com/pkg/errors" "github.com/spf13/pflag" ) @@ -64,6 +65,10 @@ func installConfigFlags(conf *config.Config, flags *pflag.FlagSet) error { // rootless needs to be explicitly specified for running "rootful" dockerd in rootless dockerd (#38702) // Note that defaultUserlandProxyPath and honorXDG are configured according to the value of rootless.RunningWithRootlessKit, not the value of --rootless. flags.BoolVar(&conf.Rootless, "rootless", rootless.RunningWithRootlessKit(), "Enable rootless mode; typically used with RootlessKit (experimental)") - flags.StringVar(&conf.CgroupNamespaceMode, "default-cgroupns-mode", config.DefaultCgroupNamespaceMode, `Default mode for containers cgroup namespace ("host" | "private")`) + defaultCgroupNamespaceMode := "host" + if cgroups.IsCgroup2UnifiedMode() { + defaultCgroupNamespaceMode = "private" + } + flags.StringVar(&conf.CgroupNamespaceMode, "default-cgroupns-mode", defaultCgroupNamespaceMode, `Default mode for containers cgroup namespace ("host" | "private")`) return nil } diff --git a/daemon/config/config_unix.go b/daemon/config/config_unix.go index 92076d4d7faa97a125053a3e99c1512bbaf8a32c..343b85fef7867635e7f4b607a2b07554cf54e9d1 100644 --- a/daemon/config/config_unix.go +++ b/daemon/config/config_unix.go @@ -11,8 +11,6 @@ import ( ) const ( - // DefaultCgroupNamespaceMode is the default for a container's CgroupnsMode, if not set otherwise - DefaultCgroupNamespaceMode = "host" // TODO: change to private // DefaultIpcMode is default for container's IpcMode, if not set otherwise DefaultIpcMode = "private" ) diff --git a/daemon/daemon_unix.go b/daemon/daemon_unix.go index 92d6a5440ffa30d7f55296e65a6c62264deb7ebb..fc3a25cf250599e449352e1baa38aed9a48e59f4 100644 --- a/daemon/daemon_unix.go +++ b/daemon/daemon_unix.go @@ -364,10 +364,15 @@ func (daemon *Daemon) adaptContainerSettings(hostConfig *containertypes.HostConf // Set default cgroup namespace mode, if unset for container if hostConfig.CgroupnsMode.IsEmpty() { - if hostConfig.Privileged { + // for cgroup v2: unshare cgroupns even for privileged containers + // https://github.com/containers/libpod/pull/4374#issuecomment-549776387 + if hostConfig.Privileged && !cgroups.IsCgroup2UnifiedMode() { hostConfig.CgroupnsMode = containertypes.CgroupnsMode("host") } else { - m := config.DefaultCgroupNamespaceMode + m := "host" + if cgroups.IsCgroup2UnifiedMode() { + m = "private" + } if daemon.configStore != nil { m = daemon.configStore.CgroupNamespaceMode } @@ -708,8 +713,8 @@ func verifyPlatformContainerSettings(daemon *Daemon, hostConfig *containertypes. warnings = append(warnings, "Your kernel does not support cgroup namespaces. Cgroup namespace setting discarded.") } - if hostConfig.Privileged { - return warnings, fmt.Errorf("privileged mode is incompatible with private cgroup namespaces. You must run the container in the host cgroup namespace when running privileged mode") + if hostConfig.Privileged && !cgroups.IsCgroup2UnifiedMode() { + return warnings, fmt.Errorf("privileged mode is incompatible with private cgroup namespaces on cgroup v1 host. You must run the container in the host cgroup namespace when running privileged mode") } } diff --git a/daemon/oci_linux.go b/daemon/oci_linux.go index 65d2e48ef7d6045945fa75eb131e510225fe0666..638696e121695c5f4b49162c1de9713272e0f31d 100644 --- a/daemon/oci_linux.go +++ b/daemon/oci_linux.go @@ -316,7 +316,9 @@ func WithNamespaces(daemon *Daemon, c *container.Container) coci.SpecOpts { return fmt.Errorf("invalid cgroup namespace mode: %v", cgroupNsMode) } - if cgroupNsMode.IsPrivate() && !c.HostConfig.Privileged { + // for cgroup v2: unshare cgroupns even for privileged containers + // https://github.com/containers/libpod/pull/4374#issuecomment-549776387 + if cgroupNsMode.IsPrivate() && (cgroups.IsCgroup2UnifiedMode() || !c.HostConfig.Privileged) { nsCgroup := specs.LinuxNamespace{Type: "cgroup"} setNamespace(s, nsCgroup) } diff --git a/integration/container/run_cgroupns_linux_test.go b/integration/container/run_cgroupns_linux_test.go index 64c18fa281601b9f4d7aebb8ee202439bc092cc2..f06d01e3dad71d5044ac920131c1fbfd365afe27 100644 --- a/integration/container/run_cgroupns_linux_test.go +++ b/integration/container/run_cgroupns_linux_test.go @@ -115,7 +115,7 @@ func TestCgroupNamespacesRunPrivilegedAndPrivate(t *testing.T) { skip.If(t, !requirement.CgroupNamespacesEnabled()) // Running with both privileged and cgroupns=private is not allowed - errStr := "privileged mode is incompatible with private cgroup namespaces. You must run the container in the host cgroup namespace when running privileged mode" + errStr := "privileged mode is incompatible with private cgroup namespaces on cgroup v1 host. You must run the container in the host cgroup namespace when running privileged mode" testCreateFailureWithCgroupNs(t, "private", errStr, container.WithPrivileged(true), container.WithCgroupnsMode("private")) }