open-nomad/website/content/docs/drivers/external/containerd.mdx
Shishir Mahajan 86e2a2be4f Update containerd task driver options.
- image_pull_timeout
- pids_limit
- sysctl
2021-04-16 13:18:33 -04:00

395 lines
11 KiB
Plaintext

---
layout: docs
page_title: 'Drivers: nomad-driver-containerd'
description: >-
The containerd driver is used
for launching containers using containerd.
---
# containerd Task Driver
Name: `containerd-driver`
Homepage: https://github.com/Roblox/nomad-driver-containerd
containerd ([`containerd.io`](https://containerd.io)) is a lightweight container
daemon for running and managing container lifecycle. Docker daemon also uses
containerd.
```hcl
dockerd (docker daemon) --> containerd --> containerd-shim --> runc
```
`nomad-driver-containerd` enables Nomad clients to launch containers directly
using containerd, without Docker. The Docker daemon is therefore not required on
the host system.
See the [project's homepage](https://github.com/Roblox/nomad-driver-containerd)
for more details.
## Client Requirements
The containerd task driver is not built into Nomad. It must be
[`downloaded`][releases] onto the client host in the configured plugin
directory.
- Linux (Ubuntu >=16.04) with [`containerd`](https://containerd.io/downloads/) (>=1.3) installed.
- [`containerd-driver`][releases] binary in Nomad's [plugin_dir][].
## Capabilities
The `containerd-driver` implements the following [capabilities](/docs/internals/plugins/task-drivers#capabilities-capabilities-error).
| Feature | Implementation |
| -------------------- | ----------------------- |
| send signals | true |
| exec | true |
| filesystem isolation | image |
| network isolation | host, group, task, none |
| volume mounting | true |
For sending signals, one can use `nomad alloc signal` command.<br/>
For exec'ing into the container, one can use `nomad alloc exec` command.
## Task Configuration
Since Docker also relies on containerd for managing container lifecycle, the
example job created by [`nomad init -short`][nomad-init] can easily be adapted
to use `containerd-driver` instead:
```hcl
job "redis" {
datacenters = ["dc1"]
group "redis-group" {
task "redis-task" {
driver = "containerd-driver"
config {
image = "docker.io/library/redis:alpine"
}
resources {
cpu = 500
memory = 256
}
}
}
}
```
The containerd task driver supports the following parameters:
- `image` - (Required) OCI image (Docker is also OCI compatible) for your
container.
```hcl
config {
image = "docker.io/library/redis:alpine"
}
```
- `image_pull_timeout` - (Optional) A time duration that controls how long
`containerd-driver` will wait before cancelling an in-progress pull of the
OCI image as specified in `image`. Defaults to `"5m"`.
- `command` - (Optional) Command to override command defined in the image.
```hcl
config {
command = "some-command"
}
```
- `args` - (Optional) Arguments to the command.
```hcl
config {
args = [
"arg1",
"arg2",
]
}
```
- `entrypoint` - (Optional) A string list overriding the image's entrypoint.
- `cwd` - (Optional) Specify the current working directory (cwd) for your container process.
If the directory does not exist, one will be created for you.
- `privileged` - (Optional) `true` or `false` (default) Run container in
privileged mode. Your container will have all Linux capabilities when running
in privileged mode.
```hcl
config {
privileged = true
}
```
- `pids_limit` - (Optional) An integer value that specifies the pid limit for
the container. Defaults to unlimited.
- `host_dns` - (Optional) `true` (default) or `false` By default, a container
launched using `containerd-driver` will use host `/etc/resolv.conf`. This is
similar to [Docker's behavior]. However, if you don't want to use
host DNS, you can turn off this flag by setting `host_dns=false`.
- `seccomp` - (Optional) Enable default seccomp profile. List of [allowed syscalls].
- `seccomp_profile` - (Optional) Path to custom seccomp profile.
`seccomp` must be set to `true` in order to use `seccomp_profile`.
The default `docker` seccomp profile found in the [Moby repository]
can be downloaded, and modified (by removing/adding syscalls) to create a custom seccomp profile.
The custom seccomp profile can then be saved under `/opt/seccomp/seccomp.json` on the Nomad client nodes.
```hcl
config {
seccomp = true
seccomp_profile = "/opt/seccomp/seccomp.json"
}
```
- `sysctl` - (Optional) A key-value map of sysctl configurations to set to the
containers on start.
```hcl
config {
sysctl = {
"net.core.somaxconn" = "16384"
"net.ipv4.ip_forward" = "1"
}
}
```
- `readonly_rootfs` - (Optional) `true` or `false` (default) Container root
filesystem will be read-only.
```hcl
config {
readonly_rootfs = true
}
```
- `host_network` ((#host_network)) - (Optional) `true` or `false` (default)
Enable host network. This is equivalent to `--net=host` in docker.
```hcl
config {
host_network = true
}
```
- `extra_hosts` - (Optional) A list of hosts, given as host:IP, to be added to
`/etc/hosts`.
- `cap_add` - (Optional) Add individual capabilities.
```hcl
config {
cap_add = [
"CAP_SYS_ADMIN",
"CAP_CHOWN",
"CAP_SYS_CHROOT"
]
}
```
- `cap_drop` - (Optional) Drop individual capabilities.
```hcl
config {
cap_drop = [
"CAP_SYS_ADMIN",
"CAP_CHOWN",
"CAP_SYS_CHROOT"
]
}
```
- `devices` - (Optional) A list of devices to be exposed to the container.
```hcl
config {
devices = [
"/dev/loop0",
"/dev/loop1"
]
}
```
- `mounts` - (Optional) A list of mounts to be mounted in the container. Volume,
bind and tmpfs type mounts are supported. fstab style [`mount options`][] are
supported.
- `type` - (Optional) Supported values are `volume`, `bind` or `tmpfs`.
**Default:** `volume`.
- `target` - (Required) Target path in the container.
- `source` - (Optional) Source path on the host.
- `options` - (Optional) fstab style [`mount options`][]. **NOTE:** For bind
mounts, at least `rbind` and `ro` are required.
```hcl
config {
mounts = [
{
type = "bind"
target = "/tmp/t1"
source = "/tmp/s1"
options = ["rbind", "ro"]
}
]
}
```
## Networking
`nomad-driver-containerd` supports **host** and **bridge** networks.
**NOTE:** `host` and `bridge` are mutually exclusive options, and only one of
them should be used at a time.
1. **Host** network can be enabled by setting `host_network` to `true` in task
config of the job spec (see [host_network][host-network] under Task
Configuration).
2. **Bridge** network can be enabled by setting the `network` stanza in the task
group section of the job spec.
```hcl
network {
mode = "bridge"
}
```
You need to install CNI plugins on Nomad client nodes under `/opt/cni/bin`
before you can use `bridge` networks.
**Instructions for installing CNI plugins.**
```hcl
$ curl -L -o cni-plugins.tgz "https://github.com/containernetworking/plugins/releases/download/v0.9.0/cni-plugins-linux-$( [ $(uname -m) = aarch64 ] && echo arm64 || echo amd64)"-v0.9.0.tgz
$ sudo mkdir -p /opt/cni/bin
$ sudo tar -C /opt/cni/bin -xzf cni-plugins.tgz
```
Also, ensure your Linux operating system distribution has been configured
to allow container traffic through the bridge network to be routed via iptables.
These tunables can be set as follows:
```hcl
$ echo 1 > /proc/sys/net/bridge/bridge-nf-call-arptables
$ echo 1 > /proc/sys/net/bridge/bridge-nf-call-ip6tables
$ echo 1 > /proc/sys/net/bridge/bridge-nf-call-iptables
```
To preserve these settings on startup of a Nomad client node, add a file
including the following to `/etc/sysctl.d/` or remove the file your Linux
distribution puts in that directory.
```hcl
net.bridge.bridge-nf-call-arptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
```
## Port Forwarding
Nomad supports both `static` and `dynamic` port mapping.
1. **Static ports**
Static port mapping can be added in the `network` stanza.
```hcl
network {
mode = "bridge"
port "lb" {
static = 8889
to = 8889
}
}
```
Here, `host` port `8889` is mapped to `container` port `8889`.<br/>
**NOTE:** static ports are usually not recommended, except for
`system` or specialized jobs like load balancers.
2. **Dynamic ports**
Dynamic port mapping is also enabled in the `network` stanza.
```hcl
network {
mode = "bridge"
port "http" {
to = 8080
}
}
```
Here, nomad will allocate a dynamic port on the `host` and that port
will be mapped to `8080` in the container.
You can read more about configuring networking under the [`network`] stanza documentation.
## Service discovery
Nomad schedules workloads of various types across a cluster of generic hosts.
Because of this, placement is not known in advance and you will need to use
service discovery to connect tasks to other services deployed across your cluster.
Nomad integrates with Consul to provide service discovery and monitoring.
A [`service`] block can be added to your job spec, to enable service discovery.
The service stanza instructs Nomad to register a service with Consul.
## Plugin Options ((#plugin_options))
- `enabled` - (Optional) The `containerd` driver may be disabled on hosts by
setting this option to `false` (defaults to `true`).
- `containerd_runtime` - (Required) Runtime for `containerd` e.g.
`io.containerd.runc.v1` or `io.containerd.runc.v2`
- `stats_interval` - (Optional) This value defines how frequently you want to
send `TaskStats` to nomad client. (defaults to `1 second`).
- `allow_privileged` - (Optional) If set to `false`, driver will deny running
privileged jobs. (defaults to `true`).
An example of using these plugin options with the new [plugin syntax][plugin] is
shown below:
```hcl
plugin "containerd-driver" {
config {
enabled = true
containerd_runtime = "io.containerd.runc.v2"
stats_interval = "5s"
}
}
```
Please note the plugin name should match whatever name you have specified for
the external driver in the [plugin_dir][plugin_dir] directory.
[nomad-driver-containerd]: https://github.com/Roblox/nomad-driver-containerd
[nomad-init]: /docs/commands/job/init
[plugin]: /docs/configuration/plugin
[plugin_dir]: /docs/configuration#plugin_dir
[plugin-options]: #plugin_options
[host-network]: #host_network
[`mount options`]: https://github.com/containerd/containerd/blob/9561d9389d3dd87ff6030bf1da4e705bbc024130/mount/mount_linux.go#L198-L222
[moby repository]: https://github.com/moby/moby/blob/master/profiles/seccomp/default.json
[docker's behavior]: https://docs.docker.com/config/containers/container-networking/#dns-services
[allowed syscalls]: https://github.com/containerd/containerd/blob/master/contrib/seccomp/seccomp_default.go#L51-L390
[`network`]: /docs/job-specification/network
[`service`]: /docs/job-specification/service
[releases]: https://github.com/Roblox/nomad-driver-containerd/releases/