Daniel's Blog

Configuring gitlab runner for kubernetes

Gitlab runner is a program that polls the gitlab servers for any pipeline jobs that need to be run. Then it runs those jobs in another container.

When the runner is polling you only see the runner pod

 $ kubectl get pods
NAME                                          READY   STATUS    RESTARTS   AGE
gitlab-runner-gitlab-runner-65b48d8f7-628q8   1/1     Running   1          3m49s

But when a job has been picked up, the runner job pod appears

$ kubectl get pods
NAME                                                 READY   STATUS    RESTARTS   AGE
gitlab-runner-gitlab-runner-65b48d8f7-628q8          1/1     Running   1          5m16s
runner-wm4edtf9-project-11427687-concurrent-089lwn   3/3     Running   0          69s

Looking at the runner pod there are three containers:

build, run, and service

$ kubectl get pod runner-wm4edtf9-project-11427687-concurrent-089lwn -o jsonpath='{range .spec.containers[*]}{.name}{"\n"}{end}'
build 
helper 
svc-0

Looking at the resources they are asking for they have limits and requests:

$ kubectl get pod runner-wm4edtf9-project-11427687-concurrent-089lwn -o jsonpath='{range .spec.containers[*]}{.resources}{"\n"}{end}'
{"limits":{"cpu":"1250m","memory":"750Mi"},"requests":{"cpu":"1","memory":"500Mi"}}
{"limits":{"cpu":"500m","memory":"500Mi"},"requests":{"cpu":"250m","memory":"250Mi"}}
{"limits":{"cpu":"1250m","memory":"750Mi"},"requests":{"cpu":"1","memory":"500Mi"}}

How was this added?

This information is stored in the config map's config.toml entry:

$ kubectl describe cm gitlab-runner-gitlab-runner

Name:         gitlab-runner-gitlab-runner
Namespace:    gitlab-apps
Labels:       app=gitlab-runner-gitlab-runner
              app.kubernetes.io/managed-by=Helm
              chart=gitlab-runner-0.29.0
              heritage=Helm
              release=gitlab-runner
Annotations:  meta.helm.sh/release-name: gitlab-runner
              meta.helm.sh/release-namespace: gitlab-apps

Data
====
...
config.template.toml:
----
[[runners]]
  limit = 3

  [runners.kubernetes]
    image = "ubuntu:16.04"
    memory_request = "500Mi"
    memory_limit = "750Mi"
    cpu_request = "1000m"
    cpu_limit = "1250m"
    helper_cpu_request = "250m"
    helper_cpu_limit = "500m"
    helper_memory_request = "250Mi"
    helper_memory_limit = "500Mi"
    service_cpu_request = "1000m"
    service_cpu_limit = "1250m"
    service_memory_request = "500Mi"
    service_memory_limit = "750Mi"
...

When editing the data it looks like this:

 16   config.template.toml: |
 17     [[runners]]
 18       limit = 3
 19 
 20       [runners.kubernetes]
 21         image = "ubuntu:16.04"
 22         memory_request = "500Mi"
 23         memory_limit = "750Mi"
 24         cpu_request = "1000m"
 25         cpu_limit = "1250m"
 26         helper_cpu_request = "250m"
 27         helper_cpu_limit = "500m"
 28         helper_memory_request = "250Mi"
 29         helper_memory_limit = "500Mi"
 30         service_cpu_request = "1000m"
 31         service_cpu_limit = "1250m"
 32         service_memory_request = "500Mi"
 33         service_memory_limit = "750Mi"

Notice the pipe | symbol?

That is Yaml's Literal Style

It is necessary to add the multiline configuration to the yaml. Also, notice the quotes around most everything? Those are necessary for it to be parsed correctly.

After doing this, your gitlab containers will have limits to ensure they don't take over the cluster. Another good idea is to create a node pool for them, but that can seem overkill since they aren't used often and you don't want a node pool to be sitting there costing money while it isn't being used.