Runners and executors

GitLab CI/CD · Expert · 14 min

Self-managed runners control cost, hardware, network access and security for every job you run.

GitLab Runner is a Go binary that polls GitLab for jobs and runs them with an executor:

  • docker: each job in a fresh container from the job's image; the default choice.
  • kubernetes: each job as a pod in a cluster; scales with the cluster.
  • shell: directly on the host; simple but jobs share the machine and its state.
  • docker-autoscaler and instance: create cloud VMs on demand through fleeting plugins; the successor to the deprecated docker+machine autoscaling.

You create a runner in the UI (project, group or instance level), which gives an authentication token starting with glrt-, then run gitlab-runner register with it on the host. The runner's settings live in config.toml: concurrent caps jobs across the whole process, and each [[runners]] section has its executor settings, such as the default image, privileged mode and volumes.

Jobs are routed with tags: a runner configured with tags gpu and linux only takes jobs whose tags: are a subset of its tags. Runners can also be set to run untagged jobs or only protected branches. A protected runner is the right place for deploy jobs with production access.

Security: privileged = true (needed for Docker-in-Docker) gives jobs root-equivalent access to the host. Isolate such runners and never share them with untrusted projects.

Example

# Register a runner using the glrt- token from the UI
gitlab-runner register --non-interactive \
  --url https://gitlab.example.com \
  --token "$RUNNER_TOKEN" \
  --executor docker --docker-image alpine:3.22

# /etc/gitlab-runner/config.toml (excerpt)
# concurrent = 8                 # max parallel jobs for this process
# [[runners]]
#   name = "docker-gpu"
#   executor = "docker"
#   [runners.docker]
#     image = "alpine:3.22"
#     privileged = false

# .gitlab-ci.yml side: route a job by tags
#   train:
#     tags: [gpu, linux]
gitlab-runner verify && gitlab-runner list

Remember

  • The runner polls GitLab; executors decide how jobs are isolated
  • Tags route jobs; concurrent caps parallel jobs
  • Privileged runners are root-equivalent; keep them isolated and protected

Watch out for

  • Using the shell executor for untrusted code; jobs share the host and its leftovers.

Check yourself

  1. A job has tags: [gpu]. Which runner can take it?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: docs.gitlab.com/runner/executors/