diff --git a/client/driver/docker.go b/client/driver/docker.go index bea4a3501342..e108f68eff96 100644 --- a/client/driver/docker.go +++ b/client/driver/docker.go @@ -161,6 +161,7 @@ type DockerDriverConfig struct { Volumes []string `mapstructure:"volumes"` // Host-Volumes to mount in, syntax: /path/to/host/directory:/destination/path/in/container VolumeDriver string `mapstructure:"volume_driver"` // Docker volume driver used for the container's volumes ForcePull bool `mapstructure:"force_pull"` // Always force pull before running image, useful if your tags are mutable + SecurityOpt []string `mapstructure:"security_opt"` // Flags to pass directly to security-opt } // Validate validates a docker driver config @@ -204,6 +205,7 @@ func NewDockerDriverConfig(task *structs.Task, env *env.TaskEnvironment) (*Docke dconf.DNSServers = env.ParseAndReplace(dconf.DNSServers) dconf.DNSSearchDomains = env.ParseAndReplace(dconf.DNSSearchDomains) dconf.ExtraHosts = env.ParseAndReplace(dconf.ExtraHosts) + dconf.SecurityOpt = env.ParseAndReplace(dconf.SecurityOpt) for _, m := range dconf.LabelsRaw { for k, v := range m { @@ -416,6 +418,9 @@ func (d *DockerDriver) Validate(config map[string]interface{}) error { "force_pull": &fields.FieldSchema{ Type: fields.TypeBool, }, + "security_opt": &fields.FieldSchema{ + Type: fields.TypeArray, + }, }, } @@ -831,6 +836,7 @@ func (d *DockerDriver) createContainerConfig(ctx *ExecContext, task *structs.Tas hostConfig.PidMode = driverConfig.PidMode hostConfig.UTSMode = driverConfig.UTSMode hostConfig.UsernsMode = driverConfig.UsernsMode + hostConfig.SecurityOpt = driverConfig.SecurityOpt hostConfig.NetworkMode = driverConfig.NetworkMode if hostConfig.NetworkMode == "" { diff --git a/client/driver/docker_test.go b/client/driver/docker_test.go index e3fdabbd81cb..a9e5471ed07a 100644 --- a/client/driver/docker_test.go +++ b/client/driver/docker_test.go @@ -745,6 +745,25 @@ func TestDockerDriver_ForcePull(t *testing.T) { } } +func TestDockerDriver_SecurityOpt(t *testing.T) { + task, _, _ := dockerTask() + task.Config["security_opt"] = []string{"seccomp=unconfined"} + + client, handle, cleanup := dockerSetup(t, task) + defer cleanup() + + waitForExist(t, client, handle.(*DockerHandle)) + + container, err := client.InspectContainer(handle.(*DockerHandle).ContainerID()) + if err != nil { + t.Fatalf("err: %v", err) + } + + if !reflect.DeepEqual(task.Config["security_opt"], container.HostConfig.SecurityOpt) { + t.Errorf("Security Opts don't match.\nExpected:\n%s\nGot:\n%s\n", task.Config["security_opt"], container.HostConfig.SecurityOpt) + } +} + func TestDockerDriver_DNS(t *testing.T) { task, _, _ := dockerTask() task.Config["dns_servers"] = []string{"8.8.8.8", "8.8.4.4"} diff --git a/website/source/docs/drivers/docker.html.md b/website/source/docs/drivers/docker.html.md index 093c77dcc6e8..fc1c30beff25 100644 --- a/website/source/docs/drivers/docker.html.md +++ b/website/source/docs/drivers/docker.html.md @@ -29,7 +29,8 @@ task "webservice" { } ``` -The `docker` driver supports the following configuration in the job spec: +The `docker` driver supports the following configuration in the job spec. Only +`image` is required. * `image` - The Docker image to run. The image may include a tag or custom URL and should include `https://` if required. By default it will be fetched from @@ -44,30 +45,6 @@ The `docker` driver supports the following configuration in the job spec: } ``` -* `load` - (Optional) A list of paths to image archive files. If - this key is not specified, Nomad assumes the `image` is hosted on a repository - and attempts to pull the image. The `artifact` blocks can be specified to - download each of the archive files. The equivalent of `docker load -i path` - would be run on each of the archive files. - - ```hcl - artifact { - source = "http://path.to/redis.tar" - } - config { - load = ["redis.tar"] - image = "redis" - } - ``` - -* `command` - (Optional) The command to run when starting the container. - - ```hcl - config { - command = "my-command" - } - ``` - * `args` - (Optional) A list of arguments to the optional `command`. If no `command` is specified, the args are passed directly to the container. References to environment variables or any [interpretable Nomad @@ -85,22 +62,35 @@ The `docker` driver supports the following configuration in the job spec: } ``` -* `labels` - (Optional) A key-value map of labels to set to the containers on - start. +* `auth` - (Optional) Provide authentication for a private registry (see below). + +* `command` - (Optional) The command to run when starting the container. ```hcl config { - labels { - foo = "bar" - zip = "zap" - } + command = "my-command" } ``` -* `privileged` - (Optional) `true` or `false` (default). Privileged mode gives - the container access to devices on the host. Note that this also requires the - nomad agent and docker daemon to be configured to allow privileged - containers. +* `dns_search_domains` - (Optional) A list of DNS search domains for the container + to use. + +* `dns_servers` - (Optional) A list of DNS servers for the container to use + (e.g. ["8.8.8.8", "8.8.4.4"]). *Docker API v1.10 and above only* + +* `extra_hosts` - (Optional) A list of hosts, given as host:IP, to be added to + `/etc/hosts`. + +* `force_pull` - (Optional) `true` or `false` (default). Always pull latest image + instead of using existing local image. Should be set to `true` if repository tags + are mutable. + +* `hostname` - (Optional) The hostname to assign to the container. When + launching more than one of a task (using `count`) with this option set, every + container the task starts will have the same hostname. + +* `interactive` - (Optional) `true` or `false` (default). Keep STDIN open on + the container. * `ipc_mode` - (Optional) The IPC mode to be used for the container. The default is `none` for a private IPC namespace. Other values are `host` for sharing @@ -109,25 +99,54 @@ The `docker` driver supports the following configuration in the job spec: names are not known in advance. Note that setting this option also requires the Nomad agent to be configured to allow privileged containers. -* `pid_mode` - (Optional) `host` or not set (default). Set to `host` to share - the PID namespace with the host. Note that this also requires the Nomad agent - to be configured to allow privileged containers. +* `ipv4_address` - (Optional) The IPv4 address to be used for the container when + using user defined networks. Requires docker 1.13.0 or greater. -* `uts_mode` - (Optional) `host` or not set (default). Set to `host` to share - the UTS namespace with the host. Note that this also requires the Nomad agent - to be configured to allow privileged containers. +* `ipv6_address` - (Optional) The IPv6 address to be used for the container when + using user defined networks. Requires docker 1.13.0 or greater. -* `userns_mode` - (Optional) `host` or not set (default). Set to `host` to use - the host's user namespace when user namespace remapping is enabled on the - docker daemon. +* `labels` - (Optional) A key-value map of labels to set to the containers on + start. -* `network_mode` - (Optional) The network mode to be used for the container. In - order to support userspace networking plugins in Docker 1.9 this accepts any - value. The default is `bridge` for all operating systems but Windows, which - defaults to `nat`. Other networking modes may not work without additional - configuration on the host (which is outside the scope of Nomad). Valid values - pre-docker 1.9 are `default`, `bridge`, `host`, `none`, or `container:name`. - See below for more details. + ```hcl + config { + labels { + foo = "bar" + zip = "zap" + } + } + ``` + +* `load` - (Optional) A list of paths to image archive files. If + this key is not specified, Nomad assumes the `image` is hosted on a repository + and attempts to pull the image. The `artifact` blocks can be specified to + download each of the archive files. The equivalent of `docker load -i path` + would be run on each of the archive files. + + ```hcl + artifact { + source = "http://path.to/redis.tar" + } + config { + load = ["redis.tar"] + image = "redis" + } + ``` + +* `logging` - (Optional) A key-value map of Docker logging options. The default + value is `syslog`. + + ```hcl + config { + logging { + type = "fluentd" + config { + fluentd-address = "localhost:24224" + tag = "your_tag" + } + } + } + ``` * `network_aliases` - (Optional) A list of network-scoped aliases, provide a way for a container to be discovered by an alternate name by any other container within @@ -144,58 +163,52 @@ The `docker` driver supports the following configuration in the job spec: } ``` -* `ipv4_address` - (Optional) The IPv4 address to be used for the container when - using user defined networks. Requires docker 1.13.0 or greater. +* `network_mode` - (Optional) The network mode to be used for the container. In + order to support userspace networking plugins in Docker 1.9 this accepts any + value. The default is `bridge` for all operating systems but Windows, which + defaults to `nat`. Other networking modes may not work without additional + configuration on the host (which is outside the scope of Nomad). Valid values + pre-docker 1.9 are `default`, `bridge`, `host`, `none`, or `container:name`. -* `ipv6_address` - (Optional) The IPv6 address to be used for the container when - using user defined networks. Requires docker 1.13.0 or greater. +* `pid_mode` - (Optional) `host` or not set (default). Set to `host` to share + the PID namespace with the host. Note that this also requires the Nomad agent + to be configured to allow privileged containers. + See below for more details. -* `hostname` - (Optional) The hostname to assign to the container. When - launching more than one of a task (using `count`) with this option set, every - container the task starts will have the same hostname. +* `port_map` - (Optional) A key-value map of port labels (see below). -* `dns_servers` - (Optional) A list of DNS servers for the container to use - (e.g. ["8.8.8.8", "8.8.4.4"]). *Docker API v1.10 and above only* +* `privileged` - (Optional) `true` or `false` (default). Privileged mode gives + the container access to devices on the host. Note that this also requires the + nomad agent and docker daemon to be configured to allow privileged + containers. -* `dns_search_domains` - (Optional) A list of DNS search domains for the container - to use. +* `security_opt` - (Optional) A list of string flags to pass directly to + [`--security-opt`](https://docs.docker.com/engine/reference/run/#security-configuration). + For example: -* `extra_hosts` - (Optional) A list of hosts, given as host:IP, to be added to - `/etc/hosts`. + ```hcl + config { + security_opt = [ + "credentialspec=file://gmsaUser.json", + ] + } + ``` + +* `shm_size` - (Optional) The size (bytes) of /dev/shm for the container. * `SSL` - (Optional) If this is set to true, Nomad uses SSL to talk to the repository. The default value is `true`. **Deprecated as of 0.5.3** -* `port_map` - (Optional) A key-value map of port labels (see below). - -* `auth` - (Optional) Provide authentication for a private registry (see below). - * `tty` - (Optional) `true` or `false` (default). Allocate a pseudo-TTY for the container. -* `interactive` - (Optional) `true` or `false` (default). Keep STDIN open on - the container. - -* `force_pull` - (Optional) `true` or `false` (default). Always pull latest image - instead of using existing local image. Should be set to `true` if repository tags - are mutable. - -* `shm_size` - (Optional) The size (bytes) of /dev/shm for the container. - -* `logging` - (Optional) A key-value map of Docker logging options. The default - value is `syslog`. +* `uts_mode` - (Optional) `host` or not set (default). Set to `host` to share + the UTS namespace with the host. Note that this also requires the Nomad agent + to be configured to allow privileged containers. - ```hcl - config { - logging { - type = "fluentd" - config { - fluentd-address = "localhost:24224" - tag = "your_tag" - } - } - } - ``` +* `userns_mode` - (Optional) `host` or not set (default). Set to `host` to use + the host's user namespace when user namespace remapping is enabled on the + docker daemon. * `volumes` - (Optional) A list of `host_path:container_path` strings to bind host paths to container paths. Mounting host paths outside of the allocation