| Avassa application specification | Ref. |
|---|
Essentials |
|---|
services:
<name>:
image: hello-world
| Image name without host prefix can be used if the default registry is configured. Fully prefixed image name is
preferable: services:
containers:
image: registry-1.docker.io/library/hello-world
| link |
docker run hello-world /hello
services:
<name>:
command:
- /hello
| services:
containers:
cmd:
- /hello
| link |
docker run --entrypoint /hello
services:
<name>:
entrypoint:
- /hello
| services:
containers:
entrypoint:
- /hello
| link |
services:
<name>:
init: true
| On by default. To disable: services:
containers:
no-builtin-init: true
| link |
docker run --env VAR1=value1
services:
<name>:
environment:
VAR1: value1
| services:
containers:
env:
VAR1: value1
| link |
docker run --user 1000:1000
services:
<name>:
user: 1000:1000
| Note: only integer UID and GID allowed, no username from image resolution. services:
containers:
user: 1000:1000
| link |
Network |
|---|
Default behaviour is to allow all outbound connections. | By default all outbound connections from a container are forbidden. To
allow all outbound connections: services:
network:
outbound-access:
allow-all: true
| link |
docker run --network host
services:
<name>:
network_mode: host
| services:
network:
host: true
| link |
docker run --network container:other --name this
services:
this:
network_mode: service:other
| Containers running in the same network namespace should be members of the
same service. services:
containers:
- name: this
- name: other
| |
docker run --publish 80:80/tcp
services:
<name>:
publish:
- 80:80/tcp
| services:
network:
ingress-ip-per-instance:
protocols:
name: tcp
port-ranges: "80"
| link |
Volumes and mounts |
|---|
docker run --volume data:/data
or docker run --mount \
type=volume,source=data,target=/data
services:
<name>:
volumes:
- type: volume
source: data
target: /data
| There are two different types of volumes: persistent-volume and
ephemeral-volume, with different lifecycles. Learn more from
the Application persistent storage document. services:
volumes:
- name: data
persistent-volume:
size: 10 GiB
containers:
mounts:
- volume-name: data
mount-path: /data
| link link |
docker run --mount \
type=bind,source=/var/run/dbus/system_bus_socket,target=/var/run/dbus/system_bus_socket
services:
<name>:
volumes:
- type: bind
source: /var/run/dbus/system_bus_socket
target: /var/run/dbus/system_bus_socket
| services:
volumes:
- name: system_dbus_socket
system-volume:
reference: system_dbus
containers:
mounts:
- volume-name: system_dbus
mount-path: /var/run/dbus/system_bus_socket
The system volume must be defined by the site provider either in the global system settings or in the site settings: system-volumes:
- name: system_dbus
path: /var/run/dbus/system_bus_socket
| link link |
Devices and GPU |
|---|
docker run --device /dev/sdc
services:
<name>:
devices:
- /dev/sdc:/dev/sdc
| services:
containers:
devices:
device-labels:
- sdc
The device label must be defined by the site provider either in the global system settings or in the site settings: device-labels:
- label: sdc
udev-patterns:
- KERNEL=="sdc"
| link |
docker run --gpus '"device=0"'
or docker run --device nvidia.com/gpu=0
services:
<name>:
resources:
reservations:
devices:
- driver: nvidia
count: 1
capabilities: [gpu]
or services:
<name>:
devices:
- nvidia.com/gpu=0
| services:
gpu:
labels:
- nvidia
number-gpus: 1
The GPU label must be defined by the site provider either in the global system settings or in the site settings: gpu-labels:
- label: nvidia
gpu-patterns:
- vendor == "NVIDIA"
| link |
Common way to pass Intel GPUs into the container: docker run --device /dev/dri
services:
<name>:
devices:
- /dev/dri:/dev/dri
| services:
gpu:
labels:
- intel
The GPU label must be defined by the site provider either in the global system settings or in the site settings: gpu-labels:
- label: intel
gpu-patterns:
- vendor == "Intel"
| link |
docker run --device-cgroup-rule 'c 250:* rwm'
services:
<name>:
device_cgroup_rules:
- 'c 250:* rwm'
| services:
containers:
devices:
dynamic:
rules:
- type: character
major: 250
minor: any
permissions: read,write,mknod
| link |
Resources |
|---|
services:
<name>:
cpus: 1.5
or services:
<name>:
resources:
limits:
cpus: "1.5"
| services:
containers:
cpus: 1.5
| link |
services:
<name>:
mem_limit: 2GB
or services:
<name>:
resources:
limits:
memory: 2GB
| services:
containers:
memory: 2 GiB
| link |
services:
<name>:
read_only: true
| services:
containers:
container-layer-size: 0 B
| link |
docker run --storage-opt size=10G
services:
<name>:
storage_opt:
size: 10G
| See prerequisites services:
containers:
container-layer-size: 10 GiB
| link |
User and PID namespaces |
|---|
services:
<name>:
userns_mode: host
| services:
containers:
user-namespace:
host: true
| link |
docker run --pid container:other --name this
services:
this:
pid: service:other
| services:
share-pid-namespace: true
containers:
- name: this
- name: other
| link |
Security features |
|---|
docker run --cap-add SYS_ADMIN
services:
<name>:
cap_add:
- SYS_ADMIN
| services:
containers:
additional-capabilities:
- sys-admin
| link |
docker run --security-opt \
apparmor=unconfined
services:
<name>:
security_opt:
- apparmor=unconfined
| services:
containers:
security:
apparmor:
disabled: true
| link |
docker run --security-opt \
label=disable
services:
<name>:
security_opt:
- label=disable
| services:
containers:
security:
selinux:
disabled: true
| link |
services:
<name>:
privileged: true
| There is no support for privileged container mode in the Avassa system. A
better approach from the security point of view is to identify the
individual privileges the application is lacking to perform its task and
grant only these privileges. To identify the privileges the application
might need think about the following:
- does the container need additional capabilities, such as
SYS_ADMIN
or NET_ADMIN?
- which devices does the container require for its operation?
- are there any system paths masked by the container engine that need
to be accessed by the application?
If the answer to these questions is not immediately clear, one possible
approach to debug an application it could be a good idea to look at the
strace tool output when run inside the container and identify the calls
the application fails to make. It may hint at the resources the
application is lacking access to.
| |
Config and secrets |
|---|
docker service create --config \
source=cfg.yaml,target=/etc/cfg.yaml,mode=0440
services:
<name>:
configs:
- source: cfg.yaml
target: /etc/cfg.yaml
mode: 0440
| services:
volumes:
- name: cfg
config-map:
items:
- name: cfg.yaml
data: |
hello: world
file-mode: "440"
containers:
mounts:
- volume-name: cfg
files:
- name: cfg.yaml
mount-path: /etc/cfg.yaml
| link link |
docker service create \
--secret password
services:
<name>:
secrets:
- password
| In the Avassa system secrets are stored in strongbox vaults. In order to mount a vault secret: services:
volumes:
- name: secret
vault-secret:
vault: secret
secret: userpass
file-mode: "400"
containers:
mounts:
- volume-name: secret
files:
- name: password
mount-path: /run/secrets/password
| link link |
Replicas and placement |
|---|
docker service create \
--replicas 2
services:
<name>:
scale: 2
or services:
<name>:
deploy:
mode: replicated
replicas: 2
| services:
mode: replicated
replicas: 2
| link link |
docker service create \
--mode global
services:
<name>:
deploy:
mode: global
| services:
mode: one-per-matching-host
| link |
docker service create --constraint \
node.labels.security==high
services:
<name>:
deploy:
placement:
constraints:
- node.labels.security==high
| services:
placement:
match-host-labels: security = high
| link |