TIQETS.ENGINEERING
Gitlab CI Runners with Makisu
Speeding up CI/CD pipelines
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.
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.
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.