Browse code

When using systemd, pass expected cgroupsPath and cli options to runc.

runc expects a systemd cgroupsPath to be in slice:scopePrefix:containerName
format and the "--systemd-cgroup" option to be set. Update docker accordingly.

Fixes 21475

Signed-off-by: Anusha Ragunathan <anusha@docker.com>
(cherry picked from commit 7ed3d265a4499ec03f10537fea0aac3ebaa0cec6)

Anusha Ragunathan authored on 2016/03/25 01:18:03
Showing 13 changed files
... ...
@@ -247,7 +247,7 @@ RUN set -x \
247 247
 	&& rm -rf "$GOPATH"
248 248
 
249 249
 # Install runc
250
-ENV RUNC_COMMIT d563bd134293c1026976a8f5764d5df5612f1dbf
250
+ENV RUNC_COMMIT 5439bd2d95229c4e213a219174c7b9da284e3487
251 251
 RUN set -x \
252 252
 	&& export GOPATH="$(mktemp -d)" \
253 253
 	&& git clone git://github.com/opencontainers/runc.git "$GOPATH/src/github.com/opencontainers/runc" \
... ...
@@ -257,7 +257,7 @@ RUN set -x \
257 257
 	&& cp runc /usr/local/bin/docker-runc
258 258
 
259 259
 # Install containerd
260
-ENV CONTAINERD_COMMIT c761085e92be09df9d5298f852c328b538f5dc2f
260
+ENV CONTAINERD_COMMIT 471bb075214cf0ad85f74f003ca00c7651638c79
261 261
 RUN set -x \
262 262
 	&& export GOPATH="$(mktemp -d)" \
263 263
 	&& git clone git://github.com/docker/containerd.git "$GOPATH/src/github.com/docker/containerd" \
... ...
@@ -181,7 +181,7 @@ RUN set -x \
181 181
 	&& rm -rf "$GOPATH"
182 182
 
183 183
 # Install runc
184
-ENV RUNC_COMMIT d563bd134293c1026976a8f5764d5df5612f1dbf
184
+ENV RUNC_COMMIT 5439bd2d95229c4e213a219174c7b9da284e3487
185 185
 RUN set -x \
186 186
 	&& export GOPATH="$(mktemp -d)" \
187 187
 	&& git clone git://github.com/opencontainers/runc.git "$GOPATH/src/github.com/opencontainers/runc" \
... ...
@@ -191,7 +191,7 @@ RUN set -x \
191 191
 	&& cp runc /usr/local/bin/docker-runc
192 192
 
193 193
 # Install containerd
194
-ENV CONTAINERD_COMMIT c761085e92be09df9d5298f852c328b538f5dc2f
194
+ENV CONTAINERD_COMMIT 471bb075214cf0ad85f74f003ca00c7651638c79
195 195
 RUN set -x \
196 196
 	&& export GOPATH="$(mktemp -d)" \
197 197
 	&& git clone git://github.com/docker/containerd.git "$GOPATH/src/github.com/docker/containerd" \
... ...
@@ -198,7 +198,7 @@ RUN set -x \
198 198
 	&& rm -rf "$GOPATH"
199 199
 
200 200
 # Install runc
201
-ENV RUNC_COMMIT d563bd134293c1026976a8f5764d5df5612f1dbf
201
+ENV RUNC_COMMIT 5439bd2d95229c4e213a219174c7b9da284e3487
202 202
 RUN set -x \
203 203
 	&& export GOPATH="$(mktemp -d)" \
204 204
 	&& git clone git://github.com/opencontainers/runc.git "$GOPATH/src/github.com/opencontainers/runc" \
... ...
@@ -208,7 +208,7 @@ RUN set -x \
208 208
 	&& cp runc /usr/local/bin/docker-runc
209 209
 
210 210
 # Install containerd
211
-ENV CONTAINERD_COMMIT c761085e92be09df9d5298f852c328b538f5dc2f
211
+ENV CONTAINERD_COMMIT 471bb075214cf0ad85f74f003ca00c7651638c79
212 212
 RUN set -x \
213 213
 	&& export GOPATH="$(mktemp -d)" \
214 214
 	&& git clone git://github.com/docker/containerd.git "$GOPATH/src/github.com/docker/containerd" \
... ...
@@ -74,7 +74,7 @@ WORKDIR /go/src/github.com/docker/docker
74 74
 ENV DOCKER_BUILDTAGS apparmor seccomp selinux
75 75
 
76 76
 # Install runc
77
-ENV RUNC_COMMIT d563bd134293c1026976a8f5764d5df5612f1dbf
77
+ENV RUNC_COMMIT 5439bd2d95229c4e213a219174c7b9da284e3487
78 78
 RUN set -x \
79 79
 	&& export GOPATH="$(mktemp -d)" \
80 80
 	&& git clone git://github.com/opencontainers/runc.git "$GOPATH/src/github.com/opencontainers/runc" \
... ...
@@ -84,7 +84,7 @@ RUN set -x \
84 84
 	&& cp runc /usr/local/bin/docker-runc
85 85
 
86 86
 # Install containerd
87
-ENV CONTAINERD_COMMIT c761085e92be09df9d5298f852c328b538f5dc2f
87
+ENV CONTAINERD_COMMIT 471bb075214cf0ad85f74f003ca00c7651638c79
88 88
 RUN set -x \
89 89
 	&& export GOPATH="$(mktemp -d)" \
90 90
 	&& git clone git://github.com/docker/containerd.git "$GOPATH/src/github.com/docker/containerd" \
... ...
@@ -199,7 +199,7 @@ RUN set -x \
199 199
 	&& rm -rf "$GOPATH"
200 200
 
201 201
 # Install runc
202
-ENV RUNC_COMMIT d563bd134293c1026976a8f5764d5df5612f1dbf
202
+ENV RUNC_COMMIT 5439bd2d95229c4e213a219174c7b9da284e3487
203 203
 RUN set -x \
204 204
 	&& export GOPATH="$(mktemp -d)" \
205 205
 	&& git clone git://github.com/opencontainers/runc.git "$GOPATH/src/github.com/opencontainers/runc" \
... ...
@@ -209,7 +209,7 @@ RUN set -x \
209 209
 	&& cp runc /usr/local/bin/docker-runc
210 210
 
211 211
 # Install containerd
212
-ENV CONTAINERD_COMMIT c761085e92be09df9d5298f852c328b538f5dc2f
212
+ENV CONTAINERD_COMMIT 471bb075214cf0ad85f74f003ca00c7651638c79
213 213
 RUN set -x \
214 214
 	&& export GOPATH="$(mktemp -d)" \
215 215
 	&& git clone git://github.com/docker/containerd.git "$GOPATH/src/github.com/docker/containerd" \
... ...
@@ -178,7 +178,7 @@ RUN set -x \
178 178
 	&& rm -rf "$GOPATH"
179 179
 
180 180
 # Install runc
181
-ENV RUNC_COMMIT d563bd134293c1026976a8f5764d5df5612f1dbf
181
+ENV RUNC_COMMIT 5439bd2d95229c4e213a219174c7b9da284e3487
182 182
 RUN set -x \
183 183
 	&& export GOPATH="$(mktemp -d)" \
184 184
 	&& git clone git://github.com/opencontainers/runc.git "$GOPATH/src/github.com/opencontainers/runc" \
... ...
@@ -188,7 +188,7 @@ RUN set -x \
188 188
 	&& cp runc /usr/local/bin/docker-runc
189 189
 
190 190
 # Install containerd
191
-ENV CONTAINERD_COMMIT c761085e92be09df9d5298f852c328b538f5dc2f
191
+ENV CONTAINERD_COMMIT 471bb075214cf0ad85f74f003ca00c7651638c79
192 192
 RUN set -x \
193 193
 	&& export GOPATH="$(mktemp -d)" \
194 194
 	&& git clone git://github.com/docker/containerd.git "$GOPATH/src/github.com/docker/containerd" \
... ...
@@ -30,7 +30,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
30 30
 	&& rm -rf /var/lib/apt/lists/*
31 31
 
32 32
 # Install runc
33
-ENV RUNC_COMMIT d563bd134293c1026976a8f5764d5df5612f1dbf
33
+ENV RUNC_COMMIT 5439bd2d95229c4e213a219174c7b9da284e3487
34 34
 RUN set -x \
35 35
 	&& export GOPATH="$(mktemp -d)" \
36 36
 	&& git clone git://github.com/opencontainers/runc.git "$GOPATH/src/github.com/opencontainers/runc" \
... ...
@@ -40,7 +40,7 @@ RUN set -x \
40 40
 	&& cp runc /usr/local/bin/docker-runc
41 41
 
42 42
 # Install containerd
43
-ENV CONTAINERD_COMMIT c761085e92be09df9d5298f852c328b538f5dc2f
43
+ENV CONTAINERD_COMMIT 471bb075214cf0ad85f74f003ca00c7651638c79
44 44
 RUN set -x \
45 45
 	&& export GOPATH="$(mktemp -d)" \
46 46
 	&& git clone git://github.com/docker/containerd.git "$GOPATH/src/github.com/docker/containerd" \
... ...
@@ -466,28 +466,36 @@ func verifyContainerResources(resources *containertypes.Resources, sysInfo *sysi
466 466
 func (daemon *Daemon) getCgroupDriver() string {
467 467
 	cgroupDriver := cgroupFsDriver
468 468
 
469
-	// No other cgroup drivers are supported at the moment. Warn the
470
-	// user if they tried to set one other than cgroupfs
471
-	for _, option := range daemon.configStore.ExecOptions {
469
+	if UsingSystemd(daemon.configStore) {
470
+		cgroupDriver = cgroupSystemdDriver
471
+	}
472
+	return cgroupDriver
473
+}
474
+
475
+// getCD gets the raw value of the native.cgroupdriver option, if set.
476
+func getCD(config *Config) string {
477
+	for _, option := range config.ExecOptions {
472 478
 		key, val, err := parsers.ParseKeyValueOpt(option)
473 479
 		if err != nil || !strings.EqualFold(key, "native.cgroupdriver") {
474 480
 			continue
475 481
 		}
476
-		if val != cgroupFsDriver {
477
-			logrus.Warnf("cgroupdriver '%s' is not supported", val)
478
-		}
482
+		return val
479 483
 	}
480
-
481
-	return cgroupDriver
484
+	return ""
482 485
 }
483 486
 
484
-func usingSystemd(config *Config) bool {
485
-	// No support for systemd cgroup atm
486
-	return false
487
+// VerifyCgroupDriver validates native.cgroupdriver
488
+func VerifyCgroupDriver(config *Config) error {
489
+	cd := getCD(config)
490
+	if cd == "" || cd == cgroupFsDriver || cd == cgroupSystemdDriver {
491
+		return nil
492
+	}
493
+	return fmt.Errorf("native.cgroupdriver option %s not supported", cd)
487 494
 }
488 495
 
489
-func (daemon *Daemon) usingSystemd() bool {
490
-	return daemon.getCgroupDriver() == cgroupSystemdDriver
496
+// UsingSystemd returns true if cli option includes native.cgroupdriver=systemd
497
+func UsingSystemd(config *Config) bool {
498
+	return getCD(config) == cgroupSystemdDriver
491 499
 }
492 500
 
493 501
 // verifyPlatformContainerSettings performs platform-specific validation of the
... ...
@@ -533,7 +541,7 @@ func verifyPlatformContainerSettings(daemon *Daemon, hostConfig *containertypes.
533 533
 			return warnings, fmt.Errorf("Cannot use the --read-only option when user namespaces are enabled")
534 534
 		}
535 535
 	}
536
-	if hostConfig.CgroupParent != "" && daemon.usingSystemd() {
536
+	if hostConfig.CgroupParent != "" && UsingSystemd(daemon.configStore) {
537 537
 		// CgroupParent for systemd cgroup should be named as "xxx.slice"
538 538
 		if len(hostConfig.CgroupParent) <= 6 || !strings.HasSuffix(hostConfig.CgroupParent, ".slice") {
539 539
 			return warnings, fmt.Errorf("cgroup-parent for systemd cgroup should be a valid slice named as \"xxx.slice\"")
... ...
@@ -554,7 +562,10 @@ func verifyDaemonSettings(config *Config) error {
554 554
 	if !config.bridgeConfig.EnableIPTables && config.bridgeConfig.EnableIPMasq {
555 555
 		config.bridgeConfig.EnableIPMasq = false
556 556
 	}
557
-	if config.CgroupParent != "" && usingSystemd(config) {
557
+	if err := VerifyCgroupDriver(config); err != nil {
558
+		return err
559
+	}
560
+	if config.CgroupParent != "" && UsingSystemd(config) {
558 561
 		if len(config.CgroupParent) <= 6 || !strings.HasSuffix(config.CgroupParent, ".slice") {
559 562
 			return fmt.Errorf("cgroup-parent for systemd cgroup should be a valid slice named as \"xxx.slice\"")
560 563
 		}
... ...
@@ -8,6 +8,7 @@ import (
8 8
 	"strconv"
9 9
 	"strings"
10 10
 
11
+	"github.com/Sirupsen/logrus"
11 12
 	"github.com/docker/docker/container"
12 13
 	"github.com/docker/docker/daemon/caps"
13 14
 	"github.com/docker/docker/libcontainerd"
... ...
@@ -583,16 +584,24 @@ func (daemon *Daemon) createSpec(c *container.Container) (*libcontainerd.Spec, e
583 583
 	}
584 584
 
585 585
 	var cgroupsPath string
586
+	scopePrefix := "docker"
587
+	parent := "/docker"
588
+	useSystemd := UsingSystemd(daemon.configStore)
589
+	if useSystemd {
590
+		parent = "system.slice"
591
+	}
592
+
586 593
 	if c.HostConfig.CgroupParent != "" {
587
-		cgroupsPath = filepath.Join(c.HostConfig.CgroupParent, c.ID)
594
+		parent = c.HostConfig.CgroupParent
595
+	} else if daemon.configStore.CgroupParent != "" {
596
+		parent = daemon.configStore.CgroupParent
597
+	}
598
+
599
+	if useSystemd {
600
+		cgroupsPath = parent + ":" + scopePrefix + ":" + c.ID
601
+		logrus.Debugf("createSpec: cgroupsPath: %s", cgroupsPath)
588 602
 	} else {
589
-		defaultCgroupParent := "/docker"
590
-		if daemon.configStore.CgroupParent != "" {
591
-			defaultCgroupParent = daemon.configStore.CgroupParent
592
-		} else if daemon.usingSystemd() {
593
-			defaultCgroupParent = "system.slice"
594
-		}
595
-		cgroupsPath = filepath.Join(defaultCgroupParent, c.ID)
603
+		cgroupsPath = filepath.Join(parent, c.ID)
596 604
 	}
597 605
 	s.Linux.CgroupsPath = &cgroupsPath
598 606
 
... ...
@@ -74,5 +74,9 @@ func (cli *DaemonCli) getPlatformRemoteOptions() []libcontainerd.RemoteOption {
74 74
 	} else {
75 75
 		opts = append(opts, libcontainerd.WithStartDaemon(true))
76 76
 	}
77
+	if daemon.UsingSystemd(cli.Config) {
78
+		args := []string{"--systemd-cgroup=true"}
79
+		opts = append(opts, libcontainerd.WithRuntimeArgs(args))
80
+	}
77 81
 	return opts
78 82
 }
... ...
@@ -491,12 +491,13 @@ with the `--exec-opt` flag. All the flag's options have the `native` prefix. A
491 491
 single `native.cgroupdriver` option is available.
492 492
 
493 493
 The `native.cgroupdriver` option specifies the management of the container's
494
-cgroups. You can specify only specify `cgroupfs` at the moment.  If you omit the
494
+cgroups. You can specify only specify `cgroupfs` or `systemd`. If you specify
495
+`systemd` and it is not available, the system errors out. If you omit the
495 496
 `native.cgroupdriver` option,` cgroupfs` is used.
496 497
 
497
-This example explicitely sets the `cgroupdriver` to `cgroupfs`:
498
+This example sets the `cgroupdriver` to `systemd`:
498 499
 
499
-    $ sudo docker daemon --exec-opt native.cgroupdriver=cgroupfs
500
+    $ sudo docker daemon --exec-opt native.cgroupdriver=systemd
500 501
 
501 502
 Setting this option applies to all containers the daemon launches.
502 503
 
... ...
@@ -46,6 +46,7 @@ type remote struct {
46 46
 	clients     []*client
47 47
 	eventTsPath string
48 48
 	pastEvents  map[string]*containerd.Event
49
+	runtimeArgs []string
49 50
 }
50 51
 
51 52
 // New creates a fresh instance of libcontainerd remote.
... ...
@@ -341,7 +342,14 @@ func (r *remote) runContainerdDaemon() error {
341 341
 	// Start a new instance
342 342
 	args := []string{"-l", r.rpcAddr, "--runtime", "docker-runc"}
343 343
 	if r.debugLog {
344
-		args = append(args, "--debug", "true")
344
+		args = append(args, "--debug")
345
+	}
346
+	if len(r.runtimeArgs) > 0 {
347
+		for _, v := range r.runtimeArgs {
348
+			args = append(args, "--runtime-args")
349
+			args = append(args, v)
350
+		}
351
+		logrus.Debugf("runContainerdDaemon: runtimeArgs: %s", args)
345 352
 	}
346 353
 	cmd := exec.Command(containerdBinary, args...)
347 354
 	// TODO: store logs?
... ...
@@ -376,6 +384,21 @@ func (a rpcAddr) Apply(r Remote) error {
376 376
 	return fmt.Errorf("WithRemoteAddr option not supported for this remote")
377 377
 }
378 378
 
379
+// WithRuntimeArgs sets the list of runtime args passed to containerd
380
+func WithRuntimeArgs(args []string) RemoteOption {
381
+	return runtimeArgs(args)
382
+}
383
+
384
+type runtimeArgs []string
385
+
386
+func (rt runtimeArgs) Apply(r Remote) error {
387
+	if remote, ok := r.(*remote); ok {
388
+		remote.runtimeArgs = rt
389
+		return nil
390
+	}
391
+	return fmt.Errorf("WithRuntimeArgs option not supported for this remote")
392
+}
393
+
379 394
 // WithStartDaemon defines if libcontainerd should also run containerd daemon.
380 395
 func WithStartDaemon(start bool) RemoteOption {
381 396
 	return startDaemon(start)
... ...
@@ -230,8 +230,9 @@ Use the **--exec-opt** flags to specify options to the execution driver.
230 230
 The following options are available:
231 231
 
232 232
 #### native.cgroupdriver
233
-Specifies the management of the container's `cgroups`. Only `cgroupfs` can be specified
234
-`cgroupfs` at the moment.
233
+Specifies the management of the container's `cgroups`. You can specify `cgroupfs`
234
+or `systemd`. If you specify `systemd` and it is not available, the system errors
235
+out.
235 236
 
236 237
 #### Client
237 238
 For specific client examples please see the man page for the specific Docker