From c56d34f4e3a5e5fa5f4a11b8b06188e611584e0e Mon Sep 17 00:00:00 2001 From: Shishir Mahajan Date: Wed, 31 Mar 2021 20:10:46 +0000 Subject: [PATCH] Add support for --runtime. Signed-off-by: Shishir Mahajan --- README.md | 13 +++++++++++-- containerd/containerd.go | 2 +- containerd/driver.go | 4 +++- containerd/utils.go | 31 ++++++++++++++++++++++++++++++ example/agent.hcl | 1 - tests/009-test-allow-privileged.sh | 2 +- 6 files changed, 47 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index bb2f794..ebf9f3e 100644 --- a/README.md +++ b/README.md @@ -77,17 +77,25 @@ will launch the job.
More detailed instructions are in the [`example README.md`](https://github.com/Roblox/nomad-driver-containerd/tree/master/example) -## Supported options +## Supported Options **Driver Config** | Option | Type | Required | Default | Description | | :---: | :---: | :---: | :---: | :--- | | **enabled** | bool | no | true | Enable/Disable task driver. | -| **containerd_runtime** | string | yes | N/A | Runtime for containerd e.g. `io.containerd.runc.v1` or `io.containerd.runc.v2`. | +| **containerd_runtime** | string | no | `io.containerd.runc.v2` | Runtime for containerd. | | **stats_interval** | string | no | 1s | Interval for collecting `TaskStats`. | | **allow_privileged** | bool | no | true | If set to `false`, driver will deny running privileged jobs. | +## Supported Runtimes + +Valid options for `containerd_runtime` (**Driver Config**). + +- `io.containerd.runc.v1`: `runc` runtime that supports a single container. +- `io.containerd.runc.v2` (Default): `runc` runtime that supports multiple containers per shim. +- `io.containerd.runsc.v1`: `gVisor` is an OCI compliant container runtime which provides better security than `runc`. They achieve this by implementing a user space kernel written in go, which implements a substantial portion of the Linux system call interface. For more details, please check their [`official documentation`](https://gvisor.dev/docs/) + **Task Config** | Option | Type | Required | Description | @@ -104,6 +112,7 @@ More detailed instructions are in the [`example README.md`](https://github.com/R | **seccomp_profile** | string | no | Path to custom seccomp profile. `seccomp` must be set to `true` in order to use `seccomp_profile`. The default `docker` seccomp profile found [`here`](https://github.com/moby/moby/blob/master/profiles/seccomp/default.json) can be used as a reference, and modified to create a custom seccomp profile. | | **sysctl** | map[string]string | no | A key-value map of sysctl configurations to set to the containers on start. | | **readonly_rootfs** | bool | no | Container root filesystem will be read-only. | +| **runtime** | string | no | A string representing a configured runtime to pass to containerd. This is equivalent to the `--runtime` argument in the docker CLI. | | **host_network** | bool | no | Enable host network. This is equivalent to `--net=host` in docker. | | **extra_hosts** | []string | no | A list of hosts, given as host:IP, to be added to /etc/hosts. | | **cap_add** | []string | no | Add individual capabilities. | diff --git a/containerd/containerd.go b/containerd/containerd.go index 4350688..c5ff6b6 100644 --- a/containerd/containerd.go +++ b/containerd/containerd.go @@ -262,7 +262,7 @@ func (d *Driver) createContainer(containerConfig *ContainerConfig, config *TaskC return d.client.NewContainer( ctxWithTimeout, containerConfig.ContainerName, - containerd.WithRuntime(d.config.ContainerdRuntime, nil), + buildRuntime(d.config.ContainerdRuntime, config.Runtime), containerd.WithNewSnapshot(containerConfig.ContainerSnapshotName, containerConfig.Image), containerd.WithNewSpec(opts...), ) diff --git a/containerd/driver.go b/containerd/driver.go index 6258c52..10d12b2 100644 --- a/containerd/driver.go +++ b/containerd/driver.go @@ -78,7 +78,7 @@ var ( hclspec.NewAttr("enabled", "bool", false), hclspec.NewLiteral("true"), ), - "containerd_runtime": hclspec.NewAttr("containerd_runtime", "string", true), + "containerd_runtime": hclspec.NewAttr("containerd_runtime", "string", false), "stats_interval": hclspec.NewAttr("stats_interval", "string", false), "allow_privileged": hclspec.NewDefault( hclspec.NewAttr("allow_privileged", "bool", false), @@ -110,6 +110,7 @@ var ( "seccomp_profile": hclspec.NewAttr("seccomp_profile", "string", false), "sysctl": hclspec.NewAttr("sysctl", "list(map(string))", false), "readonly_rootfs": hclspec.NewAttr("readonly_rootfs", "bool", false), + "runtime": hclspec.NewAttr("runtime", "string", false), "host_network": hclspec.NewAttr("host_network", "bool", false), "mounts": hclspec.NewBlockList("mounts", hclspec.NewObject(map[string]*hclspec.Spec{ "type": hclspec.NewDefault( @@ -168,6 +169,7 @@ type TaskConfig struct { HostDNS bool `codec:"host_dns"` ExtraHosts []string `codec:"extra_hosts"` Entrypoint []string `codec:"entrypoint"` + Runtime string `codec:"runtime"` ReadOnlyRootfs bool `codec:"readonly_rootfs"` HostNetwork bool `codec:"host_network"` Mounts []Mount `codec:"mounts"` diff --git a/containerd/utils.go b/containerd/utils.go index ef9c4e9..c190681 100644 --- a/containerd/utils.go +++ b/containerd/utils.go @@ -20,10 +20,14 @@ package containerd import ( "context" "os" + "strings" "syscall" + "github.com/containerd/containerd" "github.com/containerd/containerd/containers" "github.com/containerd/containerd/oci" + "github.com/containerd/containerd/plugin" + runcoptions "github.com/containerd/containerd/runtime/v2/runc/options" specs "github.com/opencontainers/runtime-spec/specs-go" ) @@ -60,3 +64,30 @@ func WithSysctls(sysctls map[string]string) oci.SpecOpts { return nil } } + +// buildRuntime sets the container runtime e.g. runc or runsc (gVisor). +func buildRuntime(pluginRuntime, jobRuntime string) containerd.NewContainerOpts { + var ( + runcOpts runcoptions.Options + runtimeOpts interface{} = &runcOpts + ) + + // plugin.RuntimeRuncV2 = io.containerd.runc.v2 + runtime := plugin.RuntimeRuncV2 + + if jobRuntime != "" { + if strings.HasPrefix(jobRuntime, "io.containerd.runc.") { + runtime = jobRuntime + } else { + runcOpts.BinaryName = jobRuntime + } + } else if pluginRuntime != "" { + if strings.HasPrefix(pluginRuntime, "io.containerd.runc.") { + runtime = pluginRuntime + } else { + runcOpts.BinaryName = pluginRuntime + } + } + + return containerd.WithRuntime(runtime, runtimeOpts) +} diff --git a/example/agent.hcl b/example/agent.hcl index 02fa770..756345a 100644 --- a/example/agent.hcl +++ b/example/agent.hcl @@ -3,7 +3,6 @@ log_level = "INFO" plugin "containerd-driver" { config { enabled = true - containerd_runtime = "io.containerd.runc.v2" stats_interval = "5s" } } diff --git a/tests/009-test-allow-privileged.sh b/tests/009-test-allow-privileged.sh index 87769c1..9bb0ce0 100755 --- a/tests/009-test-allow-privileged.sh +++ b/tests/009-test-allow-privileged.sh @@ -9,7 +9,7 @@ test_allow_privileged() { cp agent.hcl agent.hcl.bkp - sed -i '8 i \ allow_privileged = false' agent.hcl + sed -i '7 i \ allow_privileged = false' agent.hcl sudo systemctl restart nomad is_systemd_service_active "nomad.service" true