Docker Autoscaler executor
- Introduced in GitLab Runner 15.11.0 as an experiment.
- Changed to beta in GitLab Runner 16.6.
- Generally available in GitLab Runner 17.1.
Before you use the Docker Autoscaler executor, see the feedback issue about GitLab Runner autoscaling for a list of known issues.
The Docker Autoscaler executor is an autoscale-enabled Docker executor that creates instances on demand to accommodate the jobs that the runner manager processes. It wraps the Docker executor so that all Docker executor options and features are supported.
The Docker Autoscaler uses fleeting plugins to autoscale. Fleeting is an abstraction for a group of autoscaled instances, which uses plugins that support cloud providers, like Google Cloud, AWS, and Azure.
Install a fleeting plugin
To install a plugin for your target platform, see Install the fleeting plugin.
Configure Docker Autoscaler
The Docker Autoscaler executor wraps the Docker executor so that all Docker executor options and features are supported.
To configure the Docker Autoscaler, in the config.toml
:
- In the
[runners]
section, specify theexecutor
asdocker-autoscaler
. - In the following sections, configure the Docker Autoscaler based on your requirements:
Example: AWS autoscaling for 1 job per instance
Prerequisites:
- An AMI with Docker Engine installed. To enable Runner Manager’s access to the Docker socket on the AMI, the user must be part of the
docker
group. - An AWS Autoscaling group. For the scaling policy use “none”, as Runner handles the scaling.
- An IAM Policy with the correct permissions
This configuration supports:
- A capacity per instance of 1
- A use count of 1
- An idle scale of 5
- An idle time of 20 minutes
- A maximum instance count of 10
By setting the capacity and use count to both 1, each job is given a secure ephemeral instance that cannot be affected by other jobs. As soon the job is complete the instance it was executed on is immediately deleted.
With an idle scale of 5, the runner tries to keep 5 whole instances (because the capacity per instance is 1) available for future demand. These instances stay for at least 20 minutes.
The runner concurrent
field is set to 10 (maximum number instances * capacity per instance).
concurrent = 10
[[runners]]
name = "docker autoscaler example"
url = "https://gitlab.com"
token = "<token>"
shell = "sh" # use powershell or pwsh for Windows AMIs
# uncomment for Windows AMIs when the Runner manager is hosted on Linux
# environment = ["FF_USE_POWERSHELL_PATH_RESOLVER=1"]
executor = "docker-autoscaler"
# Docker Executor config
[runners.docker]
image = "busybox:latest"
# Autoscaler config
[runners.autoscaler]
plugin = "aws" # in GitLab 16.11 and later, ensure you run `gitlab-runner fleeting install` to automatically install the plugin
# in GitLab 16.10 and earlier, manually install the plugin and use:
# plugin = "fleeting-plugin-aws"
capacity_per_instance = 1
max_use_count = 1
max_instances = 10
[runners.autoscaler.plugin_config] # plugin specific configuration (see plugin documentation)
name = "my-docker-asg" # AWS Autoscaling Group name
profile = "default" # optional, default is 'default'
config_file = "/home/user/.aws/config" # optional, default is '~/.aws/config'
credentials_file = "/home/user/.aws/credentials" # optional, default is '~/.aws/credentials'
[runners.autoscaler.connector_config]
username = "ec2-user"
use_external_addr = true
[[runners.autoscaler.policy]]
idle_count = 5
idle_time = "20m0s"
Example: Google Cloud instance group for 1 job per instance
Prerequisites:
- A VM image with Docker Engine installed, such as COS.
- A Google Cloud instance group. For Autoscaling mode, select Do not autoscale. The runner handles autoscaling, not the Google Cloud instance group.
- An IAM policy with the correct permissions.
If you’re deploying your runner in a GKE cluster, you can add an IAM binding
between the Kubernetes service account and the GCP service account.
You can add this binding with the
iam.workloadIdentityUser
role to authenticate to GCP instead of using a key file withcredentials_file
.
This configuration supports:
- A capacity per instance of 1
- A use count of 1
- An idle scale of 5
- An idle time of 20 minutes
- A maximum instance count of 10
By setting the capacity and use count to both 1, each job is given a secure ephemeral instance that cannot be affected by other jobs. As soon the job is complete the instance it was executed on is immediately deleted.
With an idle scale of 5, the runner tries to keep 5 whole instances (because the capacity per instance is 1) available for future demand. These instances stay for at least 20 minutes.
The runner concurrent
field is set to 10 (maximum number instances * capacity per instance).
concurrent = 10
[[runners]]
name = "docker autoscaler example"
url = "https://gitlab.com"
token = "<token>"
shell = "sh" # use powershell or pwsh for Windows Images
# uncomment for Windows Images when the Runner manager is hosted on Linux
# environment = ["FF_USE_POWERSHELL_PATH_RESOLVER=1"]
executor = "docker-autoscaler"
# Docker Executor config
[runners.docker]
image = "busybox:latest"
# Autoscaler config
[runners.autoscaler]
plugin = "googlecloud" # for >= 16.11, ensure you run `gitlab-runner fleeting install` to automatically install the plugin
# for versions < 17.0, manually install the plugin and use:
# plugin = "fleeting-plugin-googlecompute"
capacity_per_instance = 1
max_use_count = 1
max_instances = 10
[runners.autoscaler.plugin_config] # plugin specific configuration (see plugin documentation)
name = "my-docker-instance-group" # Google Cloud Instance Group name
project = "my-gcp-project"
zone = "europe-west1"
credentials_file = "/home/user/.config/gcloud/application_default_credentials.json" # optional, default is '~/.config/gcloud/application_default_credentials.json'
[runners.autoscaler.connector_config]
username = "runner"
use_external_addr = true
[[runners.autoscaler.policy]]
idle_count = 5
idle_time = "20m0s"
Example: Azure scale set for 1 job per instance
Prerequisites:
- An Azure VM Image with Docker Engine installed.
- An Azure scale set where the autoscaling policy is set to
manual
. The runner handles the scaling.
This configuration supports:
- A capacity per instance of 1
- A use count of 1
- An idle scale of 5
- An idle time of 20 minutes
- A maximum instance count of 10
When the capacity and use count are both set to 1
, each job is given a secure ephemeral instance that cannot be
affected by other jobs. When the job completes, the instance it was executed on is immediately deleted.
When the idle scale is set to 5
, the runner keeps 5 instances available for future demand (because the capacity per instance is 1).
These instances stay for at least 20 minutes.
The runner concurrent
field is set to 10 (maximum number instances * capacity per instance).
concurrent = 10
[[runners]]
name = "docker autoscaler example"
url = "https://gitlab.com"
token = "<token>"
shell = "sh" # use powershell or pwsh for Windows AMIs
# uncomment for Windows AMIs when the Runner manager is hosted on Linux
# environment = ["FF_USE_POWERSHELL_PATH_RESOLVER=1"]
executor = "docker-autoscaler"
# Docker Executor config
[runners.docker]
image = "busybox:latest"
# Autoscaler config
[runners.autoscaler]
plugin = "azure" # for >= 16.11, ensure you run `gitlab-runner fleeting install` to automatically install the plugin
# for versions < 17.0, manually install the plugin and use:
# plugin = "fleeting-plugin-azure"
capacity_per_instance = 1
max_use_count = 1
max_instances = 10
[runners.autoscaler.plugin_config] # plugin specific configuration (see plugin documentation)
name = "my-docker-scale-set"
subscription_id = "9b3c4602-cde2-4089-bed8-889e5a3e7102"
resource_group_name = "my-resource-group"
[runners.autoscaler.connector_config]
username = "azureuser"
password = "my-scale-set-static-password"
use_static_credentials = true
timeout = "10m"
use_external_addr = true
[[runners.autoscaler.policy]]
idle_count = 5
idle_time = "20m0s"
Troubleshooting
ERROR: error during connect: ssh tunnel: EOF ()
When instances are removed by an external source (for example, an autoscaling group or automated script), jobs fail with the following error:
ERROR: Job failed (system failure): error during connect: Post "http://internal.tunnel.invalid/v1.43/containers/xyz/wait?condition=not-running": ssh tunnel: EOF ()
And the GitLab Runner logs show an instance unexpectedly removed
error
for the instance ID assigned to the job:
ERROR: instance unexpectedly removed instance=<instance_id> max-use-count=9999 runner=XYZ slots=map[] subsystem=taskscaler used=45
To resolve this error, check the events related to the instance
on your cloud provider platform. For example, on AWS, check the
CloudTrail event history for the event source ec2.amazonaws.com
.