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>

Anusha Ragunathan authored on 2016/03/25 01:18:03
Showing 13 changed files
... ...
@@ -243,7 +243,7 @@ RUN set -x \
243 243
 	&& rm -rf "$GOPATH"
244 244
 
245 245
 # Install runc
246
-ENV RUNC_COMMIT d563bd134293c1026976a8f5764d5df5612f1dbf
246
+ENV RUNC_COMMIT 5439bd2d95229c4e213a219174c7b9da284e3487
247 247
 RUN set -x \
248 248
 	&& export GOPATH="$(mktemp -d)" \
249 249
 	&& git clone git://github.com/opencontainers/runc.git "$GOPATH/src/github.com/opencontainers/runc" \
... ...
@@ -253,7 +253,7 @@ RUN set -x \
253 253
 	&& cp runc /usr/local/bin/docker-runc
254 254
 
255 255
 # Install containerd
256
-ENV CONTAINERD_COMMIT c761085e92be09df9d5298f852c328b538f5dc2f
256
+ENV CONTAINERD_COMMIT 471bb075214cf0ad85f74f003ca00c7651638c79
257 257
 RUN set -x \
258 258
 	&& export GOPATH="$(mktemp -d)" \
259 259
 	&& 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" \
... ...
@@ -57,7 +57,7 @@ ENV GOPATH /go:/go/src/github.com/docker/docker/vendor
57 57
 ENV CGO_LDFLAGS -L/lib
58 58
 
59 59
 # Install runc
60
-ENV RUNC_COMMIT d563bd134293c1026976a8f5764d5df5612f1dbf
60
+ENV RUNC_COMMIT 5439bd2d95229c4e213a219174c7b9da284e3487
61 61
 RUN set -x \
62 62
 	&& export GOPATH="$(mktemp -d)" \
63 63
 	&& git clone git://github.com/opencontainers/runc.git "$GOPATH/src/github.com/opencontainers/runc" \
... ...
@@ -67,7 +67,7 @@ RUN set -x \
67 67
 	&& cp runc /usr/local/bin/docker-runc
68 68
 
69 69
 # Install containerd
70
-ENV CONTAINERD_COMMIT c761085e92be09df9d5298f852c328b538f5dc2f
70
+ENV CONTAINERD_COMMIT 471bb075214cf0ad85f74f003ca00c7651638c79
71 71
 RUN set -x \
72 72
 	&& export GOPATH="$(mktemp -d)" \
73 73
 	&& git clone git://github.com/docker/containerd.git "$GOPATH/src/github.com/docker/containerd" \
... ...
@@ -472,28 +472,36 @@ func verifyContainerResources(resources *containertypes.Resources, sysInfo *sysi
472 472
 func (daemon *Daemon) getCgroupDriver() string {
473 473
 	cgroupDriver := cgroupFsDriver
474 474
 
475
-	// No other cgroup drivers are supported at the moment. Warn the
476
-	// user if they tried to set one other than cgroupfs
477
-	for _, option := range daemon.configStore.ExecOptions {
475
+	if UsingSystemd(daemon.configStore) {
476
+		cgroupDriver = cgroupSystemdDriver
477
+	}
478
+	return cgroupDriver
479
+}
480
+
481
+// getCD gets the raw value of the native.cgroupdriver option, if set.
482
+func getCD(config *Config) string {
483
+	for _, option := range config.ExecOptions {
478 484
 		key, val, err := parsers.ParseKeyValueOpt(option)
479 485
 		if err != nil || !strings.EqualFold(key, "native.cgroupdriver") {
480 486
 			continue
481 487
 		}
482
-		if val != cgroupFsDriver {
483
-			logrus.Warnf("cgroupdriver '%s' is not supported", val)
484
-		}
488
+		return val
485 489
 	}
486
-
487
-	return cgroupDriver
490
+	return ""
488 491
 }
489 492
 
490
-func usingSystemd(config *Config) bool {
491
-	// No support for systemd cgroup atm
492
-	return false
493
+// VerifyCgroupDriver validates native.cgroupdriver
494
+func VerifyCgroupDriver(config *Config) error {
495
+	cd := getCD(config)
496
+	if cd == "" || cd == cgroupFsDriver || cd == cgroupSystemdDriver {
497
+		return nil
498
+	}
499
+	return fmt.Errorf("native.cgroupdriver option %s not supported", cd)
493 500
 }
494 501
 
495
-func (daemon *Daemon) usingSystemd() bool {
496
-	return daemon.getCgroupDriver() == cgroupSystemdDriver
502
+// UsingSystemd returns true if cli option includes native.cgroupdriver=systemd
503
+func UsingSystemd(config *Config) bool {
504
+	return getCD(config) == cgroupSystemdDriver
497 505
 }
498 506
 
499 507
 // verifyPlatformContainerSettings performs platform-specific validation of the
... ...
@@ -539,7 +547,7 @@ func verifyPlatformContainerSettings(daemon *Daemon, hostConfig *containertypes.
539 539
 			return warnings, fmt.Errorf("Cannot use the --read-only option when user namespaces are enabled")
540 540
 		}
541 541
 	}
542
-	if hostConfig.CgroupParent != "" && daemon.usingSystemd() {
542
+	if hostConfig.CgroupParent != "" && UsingSystemd(daemon.configStore) {
543 543
 		// CgroupParent for systemd cgroup should be named as "xxx.slice"
544 544
 		if len(hostConfig.CgroupParent) <= 6 || !strings.HasSuffix(hostConfig.CgroupParent, ".slice") {
545 545
 			return warnings, fmt.Errorf("cgroup-parent for systemd cgroup should be a valid slice named as \"xxx.slice\"")
... ...
@@ -560,7 +568,10 @@ func verifyDaemonSettings(config *Config) error {
560 560
 	if !config.bridgeConfig.EnableIPTables && config.bridgeConfig.EnableIPMasq {
561 561
 		config.bridgeConfig.EnableIPMasq = false
562 562
 	}
563
-	if config.CgroupParent != "" && usingSystemd(config) {
563
+	if err := VerifyCgroupDriver(config); err != nil {
564
+		return err
565
+	}
566
+	if config.CgroupParent != "" && UsingSystemd(config) {
564 567
 		if len(config.CgroupParent) <= 6 || !strings.HasSuffix(config.CgroupParent, ".slice") {
565 568
 			return fmt.Errorf("cgroup-parent for systemd cgroup should be a valid slice named as \"xxx.slice\"")
566 569
 		}
... ...
@@ -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
 
... ...
@@ -75,6 +75,10 @@ func (cli *DaemonCli) getPlatformRemoteOptions() []libcontainerd.RemoteOption {
75 75
 	} else {
76 76
 		opts = append(opts, libcontainerd.WithStartDaemon(true))
77 77
 	}
78
+	if daemon.UsingSystemd(cli.Config) {
79
+		args := []string{"--systemd-cgroup=true"}
80
+		opts = append(opts, libcontainerd.WithRuntimeArgs(args))
81
+	}
78 82
 	return opts
79 83
 }
80 84
 
... ...
@@ -490,12 +490,13 @@ with the `--exec-opt` flag. All the flag's options have the `native` prefix. A
490 490
 single `native.cgroupdriver` option is available.
491 491
 
492 492
 The `native.cgroupdriver` option specifies the management of the container's
493
-cgroups. You can specify only specify `cgroupfs` at the moment.  If you omit the
493
+cgroups. You can specify only specify `cgroupfs` or `systemd`. If you specify
494
+`systemd` and it is not available, the system errors out. If you omit the
494 495
 `native.cgroupdriver` option,` cgroupfs` is used.
495 496
 
496
-This example explicitely sets the `cgroupdriver` to `cgroupfs`:
497
+This example sets the `cgroupdriver` to `systemd`:
497 498
 
498
-    $ sudo docker daemon --exec-opt native.cgroupdriver=cgroupfs
499
+    $ sudo docker daemon --exec-opt native.cgroupdriver=systemd
499 500
 
500 501
 Setting this option applies to all containers the daemon launches.
501 502
 
... ...
@@ -45,6 +45,7 @@ type remote struct {
45 45
 	clients     []*client
46 46
 	eventTsPath string
47 47
 	pastEvents  map[string]*containerd.Event
48
+	runtimeArgs []string
48 49
 }
49 50
 
50 51
 // New creates a fresh instance of libcontainerd remote.
... ...
@@ -340,7 +341,14 @@ func (r *remote) runContainerdDaemon() error {
340 340
 	// Start a new instance
341 341
 	args := []string{"-l", r.rpcAddr, "--runtime", "docker-runc"}
342 342
 	if r.debugLog {
343
-		args = append(args, "--debug", "true")
343
+		args = append(args, "--debug")
344
+	}
345
+	if len(r.runtimeArgs) > 0 {
346
+		for _, v := range r.runtimeArgs {
347
+			args = append(args, "--runtime-args")
348
+			args = append(args, v)
349
+		}
350
+		logrus.Debugf("runContainerdDaemon: runtimeArgs: %s", args)
344 351
 	}
345 352
 	cmd := exec.Command(containerdBinary, args...)
346 353
 	// TODO: store logs?
... ...
@@ -375,6 +383,21 @@ func (a rpcAddr) Apply(r Remote) error {
375 375
 	return fmt.Errorf("WithRemoteAddr option not supported for this remote")
376 376
 }
377 377
 
378
+// WithRuntimeArgs sets the list of runtime args passed to containerd
379
+func WithRuntimeArgs(args []string) RemoteOption {
380
+	return runtimeArgs(args)
381
+}
382
+
383
+type runtimeArgs []string
384
+
385
+func (rt runtimeArgs) Apply(r Remote) error {
386
+	if remote, ok := r.(*remote); ok {
387
+		remote.runtimeArgs = rt
388
+		return nil
389
+	}
390
+	return fmt.Errorf("WithRuntimeArgs option not supported for this remote")
391
+}
392
+
378 393
 // WithStartDaemon defines if libcontainerd should also run containerd daemon.
379 394
 func WithStartDaemon(start bool) RemoteOption {
380 395
 	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