浏览代码

Add ability to set cgroup parent for all containers

Fix #18022

Signed-off-by: Alexander Morozov <lk4d4@docker.com>
Alexander Morozov 9 年之前
父节点
当前提交
2e3186ab06

+ 2 - 0
daemon/config_unix.go

@@ -28,6 +28,7 @@ type Config struct {
 	EnableSelinuxSupport bool
 	RemappedRoot         string
 	SocketGroup          string
+	CgroupParent         string
 	Ulimits              map[string]*units.Ulimit
 }
 
@@ -77,6 +78,7 @@ func (config *Config) InstallFlags(cmd *flag.FlagSet, usageFn func(string) strin
 	cmd.BoolVar(&config.Bridge.EnableUserlandProxy, []string{"-userland-proxy"}, true, usageFn("Use userland proxy for loopback traffic"))
 	cmd.BoolVar(&config.EnableCors, []string{"#api-enable-cors", "#-api-enable-cors"}, false, usageFn("Enable CORS headers in the remote API, this is deprecated by --api-cors-header"))
 	cmd.StringVar(&config.CorsHeaders, []string{"-api-cors-header"}, "", usageFn("Set CORS headers in the remote API"))
+	cmd.StringVar(&config.CgroupParent, []string{"-cgroup-parent"}, "/docker", usageFn("Set parent cgroup for all containers"))
 
 	config.attachExperimentalFlags(cmd, usageFn)
 }

+ 4 - 1
daemon/container_operations_unix.go

@@ -258,7 +258,7 @@ func (daemon *Daemon) populateCommand(c *container.Container, env []string) erro
 		AutoCreatedDevices: autoCreatedDevices,
 		CapAdd:             c.HostConfig.CapAdd.Slice(),
 		CapDrop:            c.HostConfig.CapDrop.Slice(),
-		CgroupParent:       c.HostConfig.CgroupParent,
+		CgroupParent:       daemon.configStore.CgroupParent,
 		GIDMapping:         gidMap,
 		GroupAdd:           c.HostConfig.GroupAdd,
 		Ipc:                ipc,
@@ -270,6 +270,9 @@ func (daemon *Daemon) populateCommand(c *container.Container, env []string) erro
 		UIDMapping:         uidMap,
 		UTS:                uts,
 	}
+	if c.HostConfig.CgroupParent != "" {
+		c.Command.CgroupParent = c.HostConfig.CgroupParent
+	}
 
 	return nil
 }

+ 17 - 0
docs/reference/commandline/daemon.md

@@ -20,6 +20,7 @@ weight = -1
       --authz-plugin=[]                     Set authorization plugins to load
       -b, --bridge=""                        Attach containers to a network bridge
       --bip=""                               Specify network bridge IP
+      --cgroup-parent=/docker                Set parent cgroup for all containers
       -D, --debug                            Enable debug mode
       --default-gateway=""                   Container default gateway IPv4 address
       --default-gateway-v6=""                Container default gateway IPv6 address
@@ -643,4 +644,20 @@ set like this:
     /usr/local/bin/docker daemon -D -g /var/lib/docker -H unix:// > /var/lib/docker-machine/docker.log 2>&1
 
 
+# Default cgroup parent
 
+The `--cgroup-parent` option allows you to set the default cgroup parent
+to use for containers. If this option is not set, it defaults to `/docker`.
+
+If the cgroup has a leading forward slash (`/`), the cgroup is created
+under the root cgroup, otherwise the cgroup is created under the daemon
+cgroup.
+
+Assuming the daemon is running in cgroup `daemoncgroup`,
+`--cgroup-parent=/foobar` creates a cgroup in
+`/sys/fs/cgroup/memory/foobar`, wheras using `--cgroup-parent=foobar`
+creates the cgroup in `/sys/fs/cgroup/memory/daemoncgroup/foobar`
+
+This setting can also be set per container, using the `--cgroup-parent`
+option on `docker create` and `docker run`, and takes precedence over
+the `--cgroup-parent` option on the daemon.

+ 29 - 0
integration-cli/docker_cli_daemon_test.go

@@ -10,6 +10,7 @@ import (
 	"net"
 	"os"
 	"os/exec"
+	"path"
 	"path/filepath"
 	"regexp"
 	"strconv"
@@ -1931,3 +1932,31 @@ func (s *DockerDaemonSuite) TestDaemonRestartContainerLinksRestart(c *check.C) {
 		}
 	}
 }
+
+func (s *DockerDaemonSuite) TestDaemonCgroupParent(c *check.C) {
+	testRequires(c, DaemonIsLinux)
+
+	cgroupParent := "test"
+	name := "cgroup-test"
+
+	err := s.d.StartWithBusybox("--cgroup-parent", cgroupParent)
+	c.Assert(err, check.IsNil)
+	defer s.d.Restart()
+
+	out, err := s.d.Cmd("run", "--name", name, "busybox", "cat", "/proc/self/cgroup")
+	c.Assert(err, checker.IsNil)
+	cgroupPaths := parseCgroupPaths(string(out))
+	c.Assert(len(cgroupPaths), checker.Not(checker.Equals), 0, check.Commentf("unexpected output - %q", string(out)))
+	out, err = s.d.Cmd("inspect", "-f", "{{.Id}}", name)
+	c.Assert(err, checker.IsNil)
+	id := strings.TrimSpace(string(out))
+	expectedCgroup := path.Join(cgroupParent, id)
+	found := false
+	for _, path := range cgroupPaths {
+		if strings.HasSuffix(path, expectedCgroup) {
+			found = true
+			break
+		}
+	}
+	c.Assert(found, checker.True, check.Commentf("Cgroup path for container (%s) doesn't found in cgroups file: %s", expectedCgroup, cgroupPaths))
+}

+ 4 - 0
man/docker-daemon.8.md

@@ -10,6 +10,7 @@ docker-daemon - Enable daemon mode
 [**--authz-plugin**[=*[]*]]
 [**-b**|**--bridge**[=*BRIDGE*]]
 [**--bip**[=*BIP*]]
+[**--cgroup-parent**[=*/docker*]]
 [**--cluster-store**[=*[]*]]
 [**--cluster-advertise**[=*[]*]]
 [**--cluster-store-opt**[=*map[]*]]
@@ -80,6 +81,9 @@ format.
 **--bip**=""
   Use the provided CIDR notation address for the dynamically created bridge (docker0); Mutually exclusive of \-b
 
+**--cgroup-parent**=""
+  Set parent cgroup for all containers. Default is "/docker".
+
 **--cluster-store**=""
   URL of the distributed storage backend