GitLab Advanced CI/CD - Hands-On Lab: GitLab Runners Deep Dive
Runner scalers rely on a consistent runner image to be able to spin up runner machines on demand. The first step to creating this image is understanding how the underlying runner functions. In this lab, you will learn how to create a Docker based runner. This runner will be able to serve as a basis for a Docker autoscaler.
Estimate time to complete: 15 minutes
Task A. Create a new project
To start, let’s create a new project in the lab environment:
-
Select Create a project.
-
Select Create blank project.
-
For the project name, type CICD Runner.
-
Leave all other options as default and select Create project.
Task B. Adding the runner to the project
-
Navigate to your project.
-
In the left sidebar, select Settings > CI/CD.
-
Select Expand next to Runners.
-
Select New project runner.
-
Select Run untagged jobs, leave all other settings as default, and select Create runner.
-
Ensure that Linux is selected as your operating system.
-
In the section titled Step 1, review the command, which will look something like this:
gitlab-runner register --url https://ilt.gitlabtraining.cloud --token glrt-RrzYz4Kok-1X63pSqVJf
-
Take note of the value following
--token
. You will need this token later for the registration of your runner.
Task B. Deploying a runner
We will manage the association of the runner and deployment of runner configuration through GitLab. This strategy allows you to have source control on your runner configuration, which is ideal for tracking changes.
Let’s take a look at how this is structured:
-
Navigate to your project repository.
-
Select + > New file.
-
In the filename, type
.gitlab-ci.yml
. -
Add the deploy stage to the
.gitlab-ci.yml
file:stages: - deploy
-
Our first task is to setup our job to install the required dependencies for an SSH connection. Copy and paste the code below.
deploy config: stage: deploy image: ubuntu:latest before_script: - 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client git -y )' - eval $(ssh-agent -s) - chmod 400 "$SSH_PRIVATE_KEY" - ssh-add "$SSH_PRIVATE_KEY" - mkdir -p ~/.ssh - chmod 700 ~/.ssh - ssh-keyscan -t rsa,ed25519 $ip >> ~/.ssh/known_hosts
This job starts by installing and starting an ssh agent on the runner. When you redeemed your invitation code, an instance was created for you to deploy to and the SSH private key is stored in a variable named
SSH_PRIVATE_KEY
. This key is added to the SSH agent to use for connections. -
As a script for the job, we are going to SSH into our server and register the gitlab runner on it. Make sure to replace
your-token-here
with your runner registration token.script: - ssh root@$ip 'gitlab-runner unregister --all-runners' - ssh root@$ip 'gitlab-runner register --non-interactive --url https://ilt.gitlabtraining.cloud --executor "docker" --docker-image alpine:latest --token your-token-here'
The first command we run will unregister any current runners on your remote server. This prevents duplicate registrations of runners.
The
–non-interactive
flag prevents the runner from prompting us for inputs during the installation process. Rather than entering a prompt, we provide the arguments for URL, executor, docker image, and token through command line arguments.In this configuration, the executor is set to docker. For the
docker-image
, you are setting the default Docker image to use for your pipelines. You can use any Docker image you like, for this example, we will usealpine:latest
as the default image. -
Select Commit changes.
-
Select Build > Pipelines.
-
Select your most recent pipeline.
-
Verify that the pipeline completes successfully.
To verify that the runner is registered:
-
In the left sidebar, select Settings > CI/CD.
-
Select Expand next to Runners. You should see a green circle next to your runner.
Task C. View your runner configuration
When this runner is created, it will have a config.toml
file that defines the configuration of the runner. Let’s start by viewing our current runner configuration.
-
At the end of your
deploy config
job script, add the following command:- ssh root@$ip 'cat /etc/gitlab-runner/config.toml'
-
Commit this change and navigate to the pipeline created from the change.
-
View the
deploy config
job output. -
You will see an output from the
cat
command similar to below:concurrent = 1 check_interval = 0 shutdown_timeout = 0 [session_server] session_timeout = 1800 [[runners]] name = "runner-test" url = "https://ilt.gitlabtraining.cloud" id = 1852 token = "your-token-here" token_obtained_at = 2024-07-08T12:59:30Z token_expires_at = 0001-01-01T00:00:00Z executor = "docker" [runners.custom_build_dir] [runners.cache] MaxUploadedArchiveSize = 0 [runners.cache.s3] [runners.cache.gcs] [runners.cache.azure] [runners.docker] tls_verify = false image = "alpine:latest" privileged = false disable_entrypoint_overwrite = false oom_kill_disable = false disable_cache = false volumes = ["/cache"] shm_size = 0 network_mtu = 0
Task D. Editing your runner configuration
For our configuration, we want to be able to run our job with Docker in Docker. To do this, we need to change two default configurations:
privileged = true
volumes = ["/certs/client", "/cache"]
To make these changes, we will push a config.toml
file to the runner.
-
Navigate to your project repository.
-
Select + > New file
-
In the filename, type
config.toml
. -
Copy the
config.toml
from your job output into the toml file you created in your repository.Your
config.toml
will look something like this (theyour-token
value will be your runner token instead):concurrent = 1 check_interval = 0 connection_max_age = "15m0s" shutdown_timeout = 0 [session_server] session_timeout = 1800 [[runners]] name = "docker-runner" url = "https://gitlab.com" id = 40174213 token = "your-token" token_obtained_at = 2024-07-24T12:10:22Z token_expires_at = 0001-01-01T00:00:00Z executor = "docker" [runners.custom_build_dir] [runners.cache] MaxUploadedArchiveSize = 0 [runners.cache.s3] [runners.cache.gcs] [runners.cache.azure] [runners.docker] tls_verify = false image = "alpine:latest" privileged = false disable_entrypoint_overwrite = false oom_kill_disable = false disable_cache = false volumes = ["/cache"] shm_size = 0 network_mtu = 0
-
Before saving your
config.toml
file, update the following fields in yourconfig.toml
:privileged = true volumes = ["/certs/client", "/cache"]
-
Commit your
config.toml
file. -
Select your
.gitlab-ci.yml
file. -
Select Edit > Edit in pipeline editor.
-
After the
gitlab-runner register
command, add the following into the script:- scp config.toml root@$ip:/etc/gitlab-runner/config.toml - ssh root@$ip 'gitlab-runner restart'
-
After doing this, you will have the following
.gitlab-ci.yml
file:stages: - deploy deploy config: stage: deploy image: ubuntu:latest before_script: - 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client git -y )' - eval $(ssh-agent -s) - chmod 400 "$SSH_PRIVATE_KEY" - ssh-add "$SSH_PRIVATE_KEY" - mkdir -p ~/.ssh - chmod 700 ~/.ssh - ssh-keyscan -t rsa,ed25519 $ip >> ~/.ssh/known_hosts script: - ssh root@$ip 'gitlab-runner unregister --all-runners' - ssh root@$ip 'gitlab-runner register --non-interactive --url https://ilt.gitlabtraining.cloud --executor "docker" --docker-image alpine:latest --token glrt-71BkHhUV__N_4DDN-Xxz' - scp config.toml root@$ip:/etc/gitlab-runner/config.toml - ssh root@$ip 'gitlab-runner restart' - ssh root@$ip 'cat /etc/gitlab-runner/config.toml'
-
Select Commit changes.
This script copies your configuration to the runner machine. When the runner is registered, the new configuration is applied!
Task E. Testing the Runner
To test the runner, let’s create a basic Docker in Docker configuration to use for a project.
-
Navigate to your
Runners
project. -
Start by disabling instance level runners to ensure the jobs run on your project runner. To do this, navigate to Settings > CI/CD.
-
Select Expand next to the Runners option.
-
Toggle Enable instance runners for this project off.
-
Navigate back to your code repository.
-
Select + > New file.
-
For the filename, type
Dockerfile
. Add the following content:FROM node:latest WORKDIR /app CMD ["npm", "start"]
-
Select Commit changes.
-
Select your
.gitlab-ci.yml
file. -
Select Edit > Edit in pipeline editor.
-
Delete all of your existing jobs and stages, leaving you with an empty file.
-
Add a build stage:
stages: - build
-
Add the following build job:
build image: stage: build image: docker:27 services: - docker:27-dind variables: IMAGE: $CI_REGISTRY_IMAGE/$CI_COMMIT_REF_SLUG:$CI_COMMIT_SHA script: - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY - docker build -t $IMAGE . - docker push $IMAGE
-
Select Commit changes.
When your pipeline runs, you should see your job succeed using your new Docker runner!
Task F. Disabling the runner
For future labs, it is best to use the instance runners to ensure consistency in your results. To allow for this, disable your custom runner using the following steps:
-
Navigate to your project.
-
Select Settings > CI/CD.
-
Select Expand beside the Runners section.
-
Toggle Enable instance runners for this project to on.
-
Pause your assigned project runner by selecting the pause button.
Lab Guide Complete
You have completed this lab exercise. You can view the other lab guides for this course.
Suggestions?
If you wish to make a change to the Hands-On Guide for GitLab CI/CD, please submit your changes via Merge Request.
6f6d0996
)