Introduction

Deploying a Gitlab runner using kubernetes is a great option to overcome the limitations of other gitlab runner executor such as docker and docker machine.

Running Gitlab Runner container pod in gitlab namespace

Copy the deployment definition in file named gitlab-runner-deploy.yaml file. Replace the environment variable name CI_SERVER_URL, REGISTRATION_TOKEN. The key value in registration-token is an base64 value of the runner registration token.

apiVersion: v1
kind: Namespace
metadata:
  name: gitlab
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: gitlab-runner
  namespace: gitlab
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: gitlab-runner
  namespace: gitlab
spec:
  replicas: 1
  selector:
    matchLabels:
      app: gitlab-runner
  template:
    metadata:
      labels:
        app: gitlab-runner
    spec:
      serviceAccountName: gitlab-runner
      containers:
        - name: gitlab-runner
          image: gitlab/gitlab-runner:latest
          imagePullPolicy: IfNotPresent
          env:
            - name: CI_SERVER_URL
              value: "https://git.writeonce.de"
            - name: REGISTRATION_TOKEN
              valueFrom:
                secretKeyRef:
                  name: gitlab-runner-secret
                  key: registration-token
          volumeMounts:
            - name: config
              mountPath: /etc/gitlab-runner
      volumes:
        - name: config
          configMap:
            name: gitlab-runner-config
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: gitlab-runner-config
  namespace: gitlab
data:
  config.toml: |
    [[runners]]
      name = "Kubernetes Runner"
      url = "https://git.writeonce.de"
      token = ""
      executor = "kubernetes"
      [runners.kubernetes]
        image = "alpine:latest"
        namespace = "gitlab"
        privileged = true
        cpu_request = "100m"
        memory_request = "128Mi"
        cpu_limit = "1"
        memory_limit = "2Gi"
        poll_timeout = 180

        [[runners.kubernetes.volumes.host_path]]
          name = "docker-socket"
          mount_path = "/var/run/docker.sock"
          host_path = "/var/run/docker.sock"
          mount_type = "hostPath"
---
apiVersion: v1
kind: Secret
metadata:
  name: gitlab-runner-secret
  namespace: gitlab
type: Opaque
data:
  registration-token:

Execute below command to create the gitlab runner container pod.

kubectl apply -f gitlab-runner-deploy.yaml

Authorization

Executing the pipeline now would fail, as the pod would require permissions to create the pipeline container within the gitlab name space. The gitlab document provides the role based authorization definition.

kubectl auth can-i create pods --as=system:serviceaccount:gitlab:gitlab-runner -n gitlab
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: gitlab-runner-secrets-manager
  namespace: gitlab
rules:
- apiGroups: [""]
  resources: ["events"]
  verbs:
  - "list"
  - "watch"
- apiGroups: [""]
  resources: ["namespaces"]
  verbs:
  - "create"
  - "delete"
- apiGroups: [""]
  resources: ["pods"]
  verbs:
  - "create"
  - "delete"
  - "get"
  - "list"
  - "watch"
- apiGroups: [""]
  resources: ["pods/attach"]
  verbs:
  - "create"
  - "delete"
  - "get"
  - "patch"
- apiGroups: [""]
  resources: ["pods/exec"]
  verbs:
  - "create"
  - "delete"
  - "get"
  - "patch"
- apiGroups: [""]
  resources: ["pods/log"]
  verbs:
  - "get"
  - "list"
- apiGroups: [""]
  resources: ["secrets"]
  verbs:
  - "create"
  - "delete"
  - "get"
  - "update"
- apiGroups: [""]
  resources: ["serviceaccounts"]
  verbs:
  - "get"
- apiGroups: [""]
  resources: ["services"]
  verbs:
  - "create"
  - "get"
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: gitlab-runner-secrets-manager
  namespace: gitlab
subjects:
  - kind: ServiceAccount
    name: gitlab-runner
    namespace: gitlab
roleRef:
  kind: Role
  name: gitlab-runner-secrets-manager
  apiGroup: rbac.authorization.k8s.io

References