1.10.4 Container Placement

Each step in a build is executed inside a container. The web node distributes containers across the worker cluster depending on the configured strategy.

The volume-locality strategy

When using volume-locality, the web node places task step and put step containers on workers where a majority of their inputs are already present. This is the default strategy.

The advantage of this approach is that it reduces the likelihood that large artifacts will have to be streamed from one worker node, through the web node, and to the target worker node. For large artifacts, this can result in quite a bit of overhead.

The disadvantage of this approach is that it can sometimes result in builds "gravitating" to a particular worker and overloading it, at least until the resource caches warm across the worker pool.

If your builds tend to be light on artifacts and heavy on task execution, you may want to try the fewest-build-containers strategy instead.

The fewest-build-containers strategy

When using the fewest-build-containers strategy, step containers are placed on the worker that has the fewest build containers (i.e. containers for other steps of other builds).

To use this strategy, set the following env var on the web node:

CONCOURSE_CONTAINER_PLACEMENT_STRATEGY=fewest-build-containers

The random strategy

With the random strategy, the web node places get, put and task containers on any worker, ignoring any affinity.

As this is truly random, this will be fine until one day it's not fine.

To use this strategy, set the following env var on the web node:

CONCOURSE_CONTAINER_PLACEMENT_STRATEGY=random

The limit-active-tasks strategy

limit-active-tasks is an experimental feature.

When selecting the limit-active-tasks placement strategy, each task executed on a worker will increase the number of "active tasks" on that worker by one. When the task completes the number is decreased by one. The web node then places get, put and task containers on the worker that currently has the least amount of active tasks.

Additionally max-active-tasks-per-worker can be set to be an integer of 1 or more, in which case a worker will not execute more than that amount of tasks. A value of 0 means that there is no limit on the maximum number of active tasks on the workers. If no worker can be selected because all of them already have max-active-tasks-per-worker active tasks, then the task will wait for a free worker, periodically polling the pool. Note that the parameter does not apply to get and put steps which will always be scheduled on the worker with the fewest active tasks.

CONCOURSE_CONTAINER_PLACEMENT_STRATEGY=limit-active-tasks
and, optionally
CONCOURSE_MAX_ACTIVE_TASKS_PER_WORKER=1