From 2afcd10202283478cbafb21e8c5f90f1236acccc Mon Sep 17 00:00:00 2001 From: Jessica Frazelle Date: Mon, 6 Apr 2015 11:47:55 -0700 Subject: [PATCH] option to configure cgroups Signed-off-by: Jessica Frazelle --- daemon/config.go | 2 ++ daemon/daemon.go | 2 +- daemon/execdriver/execdrivers/execdrivers.go | 4 +-- daemon/execdriver/native/driver.go | 38 +++++++++++++++++++- docs/man/docker.1.md | 14 ++++---- docs/sources/reference/commandline/cli.md | 32 +++++++---------- 6 files changed, 62 insertions(+), 30 deletions(-) diff --git a/daemon/config.go b/daemon/config.go index 952fb5f743..43b08531b5 100644 --- a/daemon/config.go +++ b/daemon/config.go @@ -29,6 +29,7 @@ type Config struct { GraphDriver string GraphOptions []string ExecDriver string + ExecOptions []string Mtu int SocketGroup string EnableCors bool @@ -70,6 +71,7 @@ func (config *Config) InstallFlags() { flag.StringVar(&config.CorsHeaders, []string{"-api-cors-header"}, "", "Set CORS headers in the remote API") opts.IPVar(&config.Bridge.DefaultIp, []string{"#ip", "-ip"}, "0.0.0.0", "Default IP when binding container ports") opts.ListVar(&config.GraphOptions, []string{"-storage-opt"}, "Set storage driver options") + opts.ListVar(&config.ExecOptions, []string{"-exec-opt"}, "Set exec driver options") // FIXME: why the inconsistency between "hosts" and "sockets"? opts.IPListVar(&config.Dns, []string{"#dns", "-dns"}, "DNS server to use") opts.DnsSearchListVar(&config.DnsSearch, []string{"-dns-search"}, "DNS search domains to use") diff --git a/daemon/daemon.go b/daemon/daemon.go index 109ee35cb3..05de402174 100644 --- a/daemon/daemon.go +++ b/daemon/daemon.go @@ -942,7 +942,7 @@ func NewDaemonFromDirectory(config *Config, eng *engine.Engine, registryService sysInfo := sysinfo.New(false) const runDir = "/var/run/docker" - ed, err := execdrivers.NewDriver(config.ExecDriver, runDir, config.Root, sysInitPath, sysInfo) + ed, err := execdrivers.NewDriver(config.ExecDriver, config.ExecOptions, runDir, config.Root, sysInitPath, sysInfo) if err != nil { return nil, err } diff --git a/daemon/execdriver/execdrivers/execdrivers.go b/daemon/execdriver/execdrivers/execdrivers.go index f6f97c9302..dde0be1f0f 100644 --- a/daemon/execdriver/execdrivers/execdrivers.go +++ b/daemon/execdriver/execdrivers/execdrivers.go @@ -10,7 +10,7 @@ import ( "github.com/docker/docker/pkg/sysinfo" ) -func NewDriver(name, root, libPath, initPath string, sysInfo *sysinfo.SysInfo) (execdriver.Driver, error) { +func NewDriver(name string, options []string, root, libPath, initPath string, sysInfo *sysinfo.SysInfo) (execdriver.Driver, error) { switch name { case "lxc": // we want to give the lxc driver the full docker root because it needs @@ -18,7 +18,7 @@ func NewDriver(name, root, libPath, initPath string, sysInfo *sysinfo.SysInfo) ( // to be backwards compatible return lxc.NewDriver(root, libPath, initPath, sysInfo.AppArmor) case "native": - return native.NewDriver(path.Join(root, "execdriver", "native"), initPath) + return native.NewDriver(path.Join(root, "execdriver", "native"), initPath, options) } return nil, fmt.Errorf("unknown exec driver %s", name) } diff --git a/daemon/execdriver/native/driver.go b/daemon/execdriver/native/driver.go index ad13e1c1eb..afc3f1e45e 100644 --- a/daemon/execdriver/native/driver.go +++ b/daemon/execdriver/native/driver.go @@ -8,12 +8,14 @@ import ( "os" "os/exec" "path/filepath" + "strings" "sync" "syscall" "time" "github.com/Sirupsen/logrus" "github.com/docker/docker/daemon/execdriver" + "github.com/docker/docker/pkg/parsers" "github.com/docker/docker/pkg/reexec" sysinfo "github.com/docker/docker/pkg/system" "github.com/docker/docker/pkg/term" @@ -39,7 +41,7 @@ type driver struct { sync.Mutex } -func NewDriver(root, initPath string) (*driver, error) { +func NewDriver(root, initPath string, options []string) (*driver, error) { meminfo, err := sysinfo.ReadMemInfo() if err != nil { return nil, err @@ -52,11 +54,45 @@ func NewDriver(root, initPath string) (*driver, error) { if err := apparmor.InstallDefaultProfile(); err != nil { return nil, err } + + // choose cgroup manager + // this makes sure there are no breaking changes to people + // who upgrade from versions without native.cgroupdriver opt cgm := libcontainer.Cgroupfs if systemd.UseSystemd() { cgm = libcontainer.SystemdCgroups } + // parse the options + for _, option := range options { + key, val, err := parsers.ParseKeyValueOpt(option) + if err != nil { + return nil, err + } + key = strings.ToLower(key) + switch key { + case "native.cgroupdriver": + // override the default if they set options + switch val { + case "systemd": + if systemd.UseSystemd() { + cgm = libcontainer.SystemdCgroups + } else { + // warn them that they chose the wrong driver + logrus.Warn("You cannot use systemd as native.cgroupdriver, using cgroupfs instead") + } + case "cgroupfs": + cgm = libcontainer.Cgroupfs + default: + return nil, fmt.Errorf("Unknown native.cgroupdriver given %q. try cgroupfs or systemd", val) + } + default: + return nil, fmt.Errorf("Unknown option %s\n", key) + } + } + + logrus.Debugf("Using %v as native.cgroupdriver", cgm) + f, err := libcontainer.New( root, cgm, diff --git a/docs/man/docker.1.md b/docs/man/docker.1.md index 8ee5bc3cf8..794fb16883 100644 --- a/docs/man/docker.1.md +++ b/docs/man/docker.1.md @@ -324,15 +324,15 @@ for data and metadata: # EXEC DRIVER OPTIONS -Options to the exec-driver can be specified with the **--exec-opt** flags. The -only driver accepting options is the *native* (libcontainer) driver. Therefore -use these flags with **-s=**native. - -The following is the only *native* option: +Use the **--exec-opt** flags to specify options to the exec-driver. The only +driver that accepts this flag is the *native* (libcontainer) driver. As a +result, you must also specify **-s=**native for this option to have effect. The +following is the only *native* option: #### native.cgroupdriver -Specifies the management of the container's cgroups. As of now the only viable -options are `cgroupfs` and `systemd`. The option will always fallback to `cgroupfs`. +Specifies the management of the container's `cgroups`. You can specify +`cgroupfs` or `systemd`. If you specify `systemd` and it is not available, the +system uses `cgroupfs`. #### Client For specific client examples please see the man page for the specific Docker diff --git a/docs/sources/reference/commandline/cli.md b/docs/sources/reference/commandline/cli.md index e2d073a42d..2348ff549c 100644 --- a/docs/sources/reference/commandline/cli.md +++ b/docs/sources/reference/commandline/cli.md @@ -442,7 +442,7 @@ Currently supported options are: > Otherwise, set this flag for migrating existing Docker daemons to a > daemon with a supported environment. -### Docker exec-driver option +### Docker execdriver option The Docker daemon uses a specifically built `libcontainer` execution driver as its interface to the Linux kernel `namespaces`, `cgroups`, and `SELinux`. @@ -452,27 +452,21 @@ https://linuxcontainers.org/) via the `lxc` execution driver, however, this is not where the primary development of new functionality is taking place. Add `-e lxc` to the daemon flags to use the `lxc` execution driver. -#### Exec driver options +#### Options for the native execdriver -Particular exec-driver can be configured with options specified with -`--exec-opt` flags. The only driver accepting options is `native` -(libcontainer) as of now. All its options are prefixed with `native`. - -Currently supported options are: - - * `native.cgroupdriver` - - Specifies the management of the container's cgroups. As of now the only - viable options are `cgroupfs` and `systemd`. The option will always - fallback to `cgroupfs`. By default, if no option is specified, the - execdriver will try `systemd` and fallback to `cgroupfs`. Same applies if - `systemd` is passed as the `cgroupdriver` but is not capable of being used. - - Example use: - - $ sudo docker -d --exec-opt native.cgroupdriver=cgroupfs +You can configure the `native` (libcontainer) execdriver using options specified +with the `--exec-opt` flag. All the flag's options have the `native` prefix. A +single `native.cgroupdriver` option is available. +The `native.cgroupdriver` option specifies the management of the container's +cgroups. You can specify `cgroupfs` or `systemd`. If you specify `systemd` and +it is not available, the system uses `cgroupfs`. By default, if no option is +specified, the execdriver first tries `systemd` and falls back to `cgroupfs`. +This example sets the execdriver to `cgroupfs`: + $ sudo docker -d --exec-opt native.cgroupdriver=cgroupfs + +Setting this option applies to all containers the daemon launches. ### Daemon DNS options