From 5ad1d4d4c896f7afddd8e3e4ca0d838a1660e36a Mon Sep 17 00:00:00 2001 From: Rob Gulewich Date: Tue, 30 Jul 2019 10:10:03 -0700 Subject: [PATCH] docker run: specify cgroup namespace mode with --cgroupns Signed-off-by: Rob Gulewich --- cli/command/container/opts.go | 13 ++++ cli/command/system/info_test.go | 1 + cli/compose/schema/bindata.go | 72 +++++++++---------- .../schema/data/config_schema_v3.9.json | 1 + cli/compose/types/types.go | 2 + contrib/completion/bash/docker | 5 ++ contrib/completion/fish/docker.fish | 2 + contrib/completion/zsh/_docker | 1 + docs/reference/commandline/create.md | 4 ++ docs/reference/commandline/dockerd.md | 2 + docs/reference/commandline/run.md | 4 ++ e2e/container/run_test.go | 9 +++ internal/test/environment/testenv.go | 20 ++++++ man/docker-run.1.md | 7 ++ man/dockerd.8.md | 5 ++ 15 files changed, 112 insertions(+), 36 deletions(-) diff --git a/cli/command/container/opts.go b/cli/command/container/opts.go index c03c0ae698..f53ae5960d 100644 --- a/cli/command/container/opts.go +++ b/cli/command/container/opts.go @@ -70,6 +70,7 @@ type containerOptions struct { pidMode string utsMode string usernsMode string + cgroupnsMode string publishAll bool stdin bool tty bool @@ -198,6 +199,12 @@ func addFlags(flags *pflag.FlagSet) *containerOptions { flags.BoolVar(&copts.privileged, "privileged", false, "Give extended privileges to this container") flags.Var(&copts.securityOpt, "security-opt", "Security Options") flags.StringVar(&copts.usernsMode, "userns", "", "User namespace to use") + flags.StringVar(&copts.cgroupnsMode, "cgroupns", "", `Cgroup namespace to use (host|private) +'host': Run the container in the Docker host's cgroup namespace +'private': Run the container in its own private cgroup namespace +'': Use the cgroup namespace as configured by the + default-cgroupns-mode option on the daemon (default)`) + flags.SetAnnotation("cgroupns", "version", []string{"1.41"}) // Network and port publishing flag flags.Var(&copts.extraHosts, "add-host", "Add a custom host-to-IP mapping (host:ip)") @@ -469,6 +476,11 @@ func parse(flags *pflag.FlagSet, copts *containerOptions, serverOS string) (*con return nil, errors.Errorf("--userns: invalid USER mode") } + cgroupnsMode := container.CgroupnsMode(copts.cgroupnsMode) + if !cgroupnsMode.Valid() { + return nil, errors.Errorf("--cgroupns: invalid CGROUP mode") + } + restartPolicy, err := opts.ParseRestartPolicy(copts.restartPolicy) if err != nil { return nil, err @@ -620,6 +632,7 @@ func parse(flags *pflag.FlagSet, copts *containerOptions, serverOS string) (*con PidMode: pidMode, UTSMode: utsMode, UsernsMode: usernsMode, + CgroupnsMode: cgroupnsMode, CapAdd: strslice.StrSlice(copts.capAdd.GetAll()), CapDrop: strslice.StrSlice(copts.capDrop.GetAll()), GroupAdd: copts.groupAdd.GetAll(), diff --git a/cli/command/system/info_test.go b/cli/command/system/info_test.go index f9301c86dd..2d0d2bbc83 100644 --- a/cli/command/system/info_test.go +++ b/cli/command/system/info_test.go @@ -65,6 +65,7 @@ var sampleInfoNoSwarm = types.Info{ NEventsListener: 0, KernelVersion: "4.4.0-87-generic", OperatingSystem: "Ubuntu 16.04.3 LTS", + OSVersion: "", OSType: "linux", Architecture: "x86_64", IndexServerAddress: "https://index.docker.io/v1/", diff --git a/cli/compose/schema/bindata.go b/cli/compose/schema/bindata.go index bb04e48002..0d1621e019 100644 --- a/cli/compose/schema/bindata.go +++ b/cli/compose/schema/bindata.go @@ -583,45 +583,45 @@ ean7MQBPP+U4w19V/z+t/hsAAP//Fd/bF0ZHAAA= "/data/config_schema_v3.9.json": { name: "config_schema_v3.9.json", local: "data/config_schema_v3.9.json", - size: 18246, + size: 18291, modtime: 1518458244, compressed: ` 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 -vNT9GICnn3Kc4a+q/59W/w0AAP//CCwovkZHAAA= +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 `, }, diff --git a/cli/compose/schema/data/config_schema_v3.9.json b/cli/compose/schema/data/config_schema_v3.9.json index f6b3e9c1bc..77abb87463 100644 --- a/cli/compose/schema/data/config_schema_v3.9.json +++ b/cli/compose/schema/data/config_schema_v3.9.json @@ -96,6 +96,7 @@ }, "cap_add": {"type": "array", "items": {"type": "string"}, "uniqueItems": true}, "cap_drop": {"type": "array", "items": {"type": "string"}, "uniqueItems": true}, + "cgroupns_mode": {"type": "string"}, "cgroup_parent": {"type": "string"}, "command": { "oneOf": [ diff --git a/cli/compose/types/types.go b/cli/compose/types/types.go index 2578b8cf00..f980032eea 100644 --- a/cli/compose/types/types.go +++ b/cli/compose/types/types.go @@ -11,6 +11,7 @@ var UnsupportedProperties = []string{ "build", "cap_add", "cap_drop", + "cgroupns_mode", "cgroup_parent", "devices", "domainname", @@ -159,6 +160,7 @@ type ServiceConfig struct { Build BuildConfig `yaml:",omitempty" json:"build,omitempty"` CapAdd []string `mapstructure:"cap_add" yaml:"cap_add,omitempty" json:"cap_add,omitempty"` CapDrop []string `mapstructure:"cap_drop" yaml:"cap_drop,omitempty" json:"cap_drop,omitempty"` + CgroupNSMode string `mapstructure:"cgroupns_mode" yaml:"cgroupns_mode,omitempty" json:"cgroupns_mode,omitempty"` CgroupParent string `mapstructure:"cgroup_parent" yaml:"cgroup_parent,omitempty" json:"cgroup_parent,omitempty"` Command ShellCommand `yaml:",omitempty" json:"command,omitempty"` Configs []ServiceConfigObjConfig `yaml:",omitempty" json:"configs,omitempty"` diff --git a/contrib/completion/bash/docker b/contrib/completion/bash/docker index 39f3397d0c..0d8cfe4d98 100644 --- a/contrib/completion/bash/docker +++ b/contrib/completion/bash/docker @@ -1865,6 +1865,7 @@ _docker_container_run_and_create() { --blkio-weight-device --cap-add --cap-drop + --cgroupns --cgroup-parent --cidfile --cpu-period @@ -2022,6 +2023,10 @@ _docker_container_run_and_create() { _filedir return ;; + --cgroupns) + COMPREPLY=( $( compgen -W "host private" -- "$cur" ) ) + return + ;; --device|--tmpfs|--volume|-v) case "$cur" in *:*) diff --git a/contrib/completion/fish/docker.fish b/contrib/completion/fish/docker.fish index 30959e12c1..e7be9743f8 100644 --- a/contrib/completion/fish/docker.fish +++ b/contrib/completion/fish/docker.fish @@ -183,6 +183,7 @@ complete -c docker -A -f -n '__fish_seen_subcommand_from create' -l blkio-weight complete -c docker -A -f -n '__fish_seen_subcommand_from create' -l blkio-weight-device -d 'Block IO weight (relative device weight)' complete -c docker -A -f -n '__fish_seen_subcommand_from create' -l cap-add -d 'Add Linux capabilities' complete -c docker -A -f -n '__fish_seen_subcommand_from create' -l cap-drop -d 'Drop Linux capabilities' +complete -c docker -A -f -n '__fish_seen_subcommand_from create' -l cgroupns -d 'Cgroup namespace mode to use' complete -c docker -A -f -n '__fish_seen_subcommand_from create' -l cgroup-parent -d 'Optional parent cgroup for the container' complete -c docker -A -f -n '__fish_seen_subcommand_from create' -l cidfile -d 'Write the container ID to the file' complete -c docker -A -f -n '__fish_seen_subcommand_from create' -l cpu-count -d 'CPU count (Windows only)' @@ -458,6 +459,7 @@ complete -c docker -A -f -n '__fish_seen_subcommand_from run' -s c -l cpu-shares complete -c docker -A -f -n '__fish_seen_subcommand_from run' -l cap-add -d 'Add Linux capabilities' complete -c docker -A -f -n '__fish_seen_subcommand_from run' -l cap-drop -d 'Drop Linux capabilities' complete -c docker -A -f -n '__fish_seen_subcommand_from run' -l cidfile -d 'Write the container ID to the file' +complete -c docker -A -f -n '__fish_seen_subcommand_from run' -l cgroupns -d 'Cgroup namespace mode to use' complete -c docker -A -f -n '__fish_seen_subcommand_from run' -l cpuset -d 'CPUs in which to allow execution (0-3, 0,1)' complete -c docker -A -f -n '__fish_seen_subcommand_from run' -s d -l detach -d 'Detached mode: run the container in the background and print the new container ID' complete -c docker -A -f -n '__fish_seen_subcommand_from run' -l device -d 'Add a host device to the container (e.g. --device=/dev/sdc:/dev/xvdc:rwm)' diff --git a/contrib/completion/zsh/_docker b/contrib/completion/zsh/_docker index 32a9a9db20..5048c5ee66 100644 --- a/contrib/completion/zsh/_docker +++ b/contrib/completion/zsh/_docker @@ -605,6 +605,7 @@ __docker_container_subcommand() { "($help)*--blkio-weight-device=[Block IO (relative device weight)]:device:Block IO weight: " "($help)*--cap-add=[Add Linux capabilities]:capability: " "($help)*--cap-drop=[Drop Linux capabilities]:capability: " + "($help)--cgroupns=[Cgroup namespace mode to use]:cgroup namespace mode: " "($help)--cgroup-parent=[Parent cgroup for the container]:cgroup: " "($help)--cidfile=[Write the container ID to the file]:CID file:_files" "($help)--cpus=[Number of CPUs (default 0.000)]:cpus: " diff --git a/docs/reference/commandline/create.md b/docs/reference/commandline/create.md index c829dbb3e5..2d01689301 100644 --- a/docs/reference/commandline/create.md +++ b/docs/reference/commandline/create.md @@ -29,6 +29,10 @@ Options: --blkio-weight-device value Block IO weight (relative device weight) (default []) --cap-add value Add Linux capabilities (default []) --cap-drop value Drop Linux capabilities (default []) + --cgroupns string Cgroup namespace to use + 'host': Run the container in the Docker host's cgroup namespace + 'private': Run the container in its own private cgroup namespace + '': Use the default Docker daemon cgroup namespace specified by the `--default-cgroupns-mode` option --cgroup-parent string Optional parent cgroup for the container --cidfile string Write the container ID to the file --cpu-count int The number of CPUs available for execution by the container. diff --git a/docs/reference/commandline/dockerd.md b/docs/reference/commandline/dockerd.md index b4a71dd466..4206f1cf46 100644 --- a/docs/reference/commandline/dockerd.md +++ b/docs/reference/commandline/dockerd.md @@ -38,6 +38,7 @@ Options: --cpu-rt-runtime int Limit the CPU real-time runtime in microseconds --data-root string Root directory of persistent Docker state (default "/var/lib/docker") -D, --debug Enable debug mode + --default-cgroupns-mode string Container default cgroup namespace mode (default "host") --default-gateway ip Container default gateway IPv4 address --default-gateway-v6 ip Container default gateway IPv6 address --default-address-pool Set the default address pool for local node networks @@ -1299,6 +1300,7 @@ This is a full example of the allowed configuration options on Linux: { "authorization-plugins": [], "data-root": "", + "default-cgroupns-mode": "private", "dns": [], "dns-opts": [], "dns-search": [], diff --git a/docs/reference/commandline/run.md b/docs/reference/commandline/run.md index b007042bde..ecee2953a5 100644 --- a/docs/reference/commandline/run.md +++ b/docs/reference/commandline/run.md @@ -27,6 +27,10 @@ Options: --blkio-weight-device value Block IO weight (relative device weight) (default []) --cap-add value Add Linux capabilities (default []) --cap-drop value Drop Linux capabilities (default []) + --cgroupns string Cgroup namespace to use + 'host': Run the container in the Docker host's cgroup namespace + 'private': Run the container in its own private cgroup namespace + '': Use the default Docker daemon cgroup namespace specified by the `--default-cgroupns-mode` option --cgroup-parent string Optional parent cgroup for the container --cidfile string Write the container ID to the file --cpu-count int The number of CPUs available for execution by the container. diff --git a/e2e/container/run_test.go b/e2e/container/run_test.go index 1c809eb0d5..5097af911b 100644 --- a/e2e/container/run_test.go +++ b/e2e/container/run_test.go @@ -135,3 +135,12 @@ func createRemoteImage(t *testing.T) string { icmd.RunCommand("docker", "rmi", image).Assert(t, icmd.Success) return image } + +func TestRunWithCgroupNamespace(t *testing.T) { + environment.SkipIfDaemonNotLinux(t) + environment.SkipIfCgroupNamespacesNotSupported(t) + + result := icmd.RunCommand("docker", "run", "--cgroupns=private", "--rm", fixtures.AlpineImage, + "/bin/grep", "-q", "':memory:/$'", "/proc/1/cgroup") + result.Assert(t, icmd.Success) +} diff --git a/internal/test/environment/testenv.go b/internal/test/environment/testenv.go index a6e16814fa..46fe79da52 100644 --- a/internal/test/environment/testenv.go +++ b/internal/test/environment/testenv.go @@ -1,6 +1,7 @@ package environment import ( + "fmt" "os" "strings" "testing" @@ -88,3 +89,22 @@ func SkipIfNotExperimentalDaemon(t *testing.T) { experimentalBuild := strings.TrimSpace(result.Stdout()) == "true" skip.If(t, !experimentalBuild, "running against a non-experimental daemon") } + +// SkipIfDaemonNotLinux skips the test unless the running docker daemon is on Linux +func SkipIfDaemonNotLinux(t *testing.T) { + t.Helper() + result := icmd.RunCmd(icmd.Command("docker", "info", "--format", "{{.OSType}}")) + result.Assert(t, icmd.Expected{Err: icmd.None}) + isLinux := strings.TrimSpace(result.Stdout()) == "linux" + skip.If(t, !isLinux, "running against a Linux daemon") +} + +// SkipIfCgroupNamespacesNotSupported skips the test if the running docker daemon doesn't support cgroup namespaces +func SkipIfCgroupNamespacesNotSupported(t *testing.T) { + t.Helper() + result := icmd.RunCmd(icmd.Command("docker", "info", "--format", "{{.SecurityOptions}}")) + result.Assert(t, icmd.Expected{Err: icmd.None}) + cgroupNsFound := strings.Contains(result.Stdout(), "name=cgroupns") + + skip.If(t, !cgroupNsFound, fmt.Sprintf("running against a daemon that doesn't support cgroup namespaces (security options: %s)", result.Stdout())) +} diff --git a/man/docker-run.1.md b/man/docker-run.1.md index 5a2218d5bf..8b71569cd8 100644 --- a/man/docker-run.1.md +++ b/man/docker-run.1.md @@ -13,6 +13,7 @@ docker-run - Run a command in a new container [**--cpu-shares**[=*0*]] [**--cap-add**[=*[]*]] [**--cap-drop**[=*[]*]] +[**--cgroupns**[=*[]*]] [**--cgroup-parent**[=*CGROUP-PATH*]] [**--cidfile**[=*CIDFILE*]] [**--cpu-count**[=*0*]] @@ -173,6 +174,12 @@ division of CPU shares: **--cap-drop**=[] Drop Linux capabilities +**--cgroupns**="" + Set the cgroup namespace mode for the container. + **host**: run the container in the host's cgroup namespace + **private**: run the container in its own private cgroup namespace + **""**: (unset) run the container in the host's cgroup namespace + **--cgroup-parent**="" Path to cgroups under which the cgroup for the container will be created. If the path is not absolute, the path is considered to be relative to the cgroups path of the init process. Cgroups will be created if they do not already exist. diff --git a/man/dockerd.8.md b/man/dockerd.8.md index 837e28508e..39ddc5ea30 100644 --- a/man/dockerd.8.md +++ b/man/dockerd.8.md @@ -20,6 +20,7 @@ dockerd - Enable daemon mode [**--containerd**[=*SOCKET-PATH*]] [**--data-root**[=*/var/lib/docker*]] [**-D**|**--debug**] +[**--default-cgroupns-mode**[=*host*]] [**--default-gateway**[=*DEFAULT-GATEWAY*]] [**--default-gateway-v6**[=*DEFAULT-GATEWAY-V6*]] [**--default-address-pool**[=*DEFAULT-ADDRESS-POOL*]] @@ -178,6 +179,10 @@ $ sudo dockerd --add-runtime runc=runc --add-runtime custom=/usr/local/bin/my-ru **-D**, **--debug**=*true*|*false* Enable debug mode. Default is false. +**--default-cgroupns-mode**="**host**|**private**" + Set the default cgroup namespace mode for newly created containers. The argument + can either be **host** or **private**. If unset, this defaults to `host`. + **--default-gateway**="" IPv4 address of the container default gateway; this address must be part of the bridge subnet (which is defined by \-b or \--bip)