TIQETS.ENGINEERING

Gitlab CI Runners with Makisu

Speeding up CI/CD pipelines

Raditya Surya
Tiqets Engineering

--

What are Gitlab Runners?

Gitlab Runners are isolated virtual machines that run predefined steps through the GitLab CI API. Gitlab Runners run CI jobs and send the results back to Gitlab.

By using runners, we execute multiple jobs concurrently inside Docker containers. This brings us much faster pipelines compared to the single instances provided by Gitlab.

Makisu

Makisu is a fast and flexible Docker image build tool for unprivileged containerized environments, such as Kubernetes. Among others, it brings a distributed layer cache.

Makisu

Install the Makisu binary

go get github.com/uber/makisu/bin/makisu

Build your Docker images

To build your Docker images using Makisu, run the following:

makisu build -t <docker tag> --dest <tar location> <docker context>

CI Runners + Makisu

With Gitlab CI Runners, we can spin up new EC2 nodes to run our pipeline jobs within our Kubernetes cluster. There, we use Makisu to build the Docker images.

Example of Gitlab CI Runner

Install Gitlab Runner Chart

We install the runner with helm. You can find the configuration in the documentation here.

To install the helm chart, run this command:

# For Helm 2 
helm install - namespace <NAMESPACE> - name gitlab-runner -f <CONFIG_VALUES_FILE> gitlab/gitlab-runner
# For Helm 3
helm install - namespace <NAMESPACE> gitlab-runner -f <CONFIG_VALUES_FILE> gitlab/gitlab-runner

.gitlab-ci.yml

To use the Makisu image, set up a base job in your .gitlab-ci.yml file, like this:

.makisu-builder:
image:
name: gcr.io/uber-container-tools/makisu-alpine:v0.1.14
entrypoint: [""]
variables:
REGISTRY_CONFIG: /registry-config.yaml
SSL_CERT_DIR: "/makisu-internal/certs/"
CURL_CA_BUNDLE: "/makisu-internal/certs/cacerts.pem"
script:
- |
/makisu-internal/makisu \
--log-level=debug \
--log-fmt=console \
build \
--replica=$DOCKER_REGISTRY/$DOCKER_IMAGE_NAME:$CI_COMMIT_REF_SLUG \
--push=$DOCKER_REGISTRY \
--modifyfs \
-t=$DOCKER_REGISTRY:$DOCKER_TAG \
--registry-config=$REGISTRY_CONFIG \
-f=$DOCKERFILE \
--build-arg=DOCKER_TAG=$DOCKER_TAG \
--commit=implicit \
--storage=/makisu-storage \
$CONTEXT

This setup will spawn a runner with a Makisu container running inside your Kubernetes cluster. By default, the runner will check out your repository and use it as the context.

Then extend .makisu-builder and set up a job to build your images:

build_base_image:
stage: build
extends:
- .makisu-builder
variables:
CONTEXT: "$CI_PROJECT_DIR/Dockerfiles/base"
DOCKER_IMAGE_NAME: <your docker image>

Speed up build with cache

Makisu support a distributed caching system which will help us reduce our build time. By default, Makisu will store the Docker layer cache locally and Docker registry if you push the images to the registry, and it will use a separate key-value store to map lines of a Dockerfile to names of the layers.

Redis can be set up as a distributed cache key-value store. You can install Redis on your Kubernetes cluster and connect it to your GitLab runner.

$ helm repo add bitnami https://charts.bitnami.com/bitnami
$ helm install redis-makisu-cache bitnami/redis # Helm 3
$ helm install --name redis-makisu-cache bitnami/redis # Helm 2

To connect Makisu with Redis, edit your .gitlab-ci.yml and add this line to your base job Makisu flags:

--redis-cache-addr=redis-makisu-cache:6379

The cache has a 14 day TTL by default. You can read more about the cache settings here.

Conclusions

By using this setup, we doubled the speed of CI/CD pipeline build times (Master, feature, and production branches).

Author

Raditya Surya is an Infrastructure Engineer at Tiqets, and also tries to catch up with the latest technology available.

--

--