UNC Campus Git: Gitlab Runner in Openshift Platform

Summary

This article describes how to install and configure Gitlab Runner in OpenShift Platform.

Body

This article describes how to install and configure Gitlab Runner in OpenShift Platform.

 

 

In This Article: 

This process to install and configure Gitlab Runner in OpenShift Platform involves the following steps, which must be performed in order. Use the links below to jump to a specific step.

 

Instructions

 

Step 1: Get access to OpenShift Cloudapps Platform

 

Step 2: Create service account, roles, and role-bindings

oc login -u <onyen> https://api.cloudapps.unc.edu:6443

oc project <gitlab-runner-project-name>

oc create serviceaccount <gitlab-runner-sa> -n <gitlab-runner-project-name>

vi gitlab-runner-rbac.yml  # Use the below yaml with updated names and namespace

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: gitlab-runner-role
  namespace:  <gitlab-runner-project-name>
rules:
- apiGroups: [""]
  resources: ["pods", "pods/exec", "pods/log", "pods/attach", "secrets", "events"]
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
- apiGroups: [""]
  resources: ["configmaps"]
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: gitlab-runner-binding
  namespace:  <gitlab-runner-project-name>
subjects:
- kind: ServiceAccount
  name: gitlab-runner-sa
  namespace: <gitlab-runner-project-name>
roleRef:
  kind: Role
  name: gitlab-runner-role
  apiGroup: rbac.authorization.k8s.io

oc apply -f gitlab-runner-rbac.yml

 

Step 3: Create ImageStream

To download the Docker Image in Openshift, create an ImageStream. For the list of available version tags, see GitLab Runner tags. You don't need a BuildConfig for this. You can directly create an ImageStream that imports the image from Docker Hub.

 

Using the command line (oc)

oc import-image gitlab-runner-docker:latest --from=docker.io/gitlab/gitlab-runner:bleeding--confirm -n <gitlab-runner-project-name>

 

Using a YAML definition (imagestream-import.yaml)

Either update in UI(Administrator>Builds>Imagestream>Create ImageStream)

OR

oc apply -f imagestream-import.yaml

apiVersion: image.openshift.io/v1
kind: ImageStream
metadata:
  name: gitlab-runner-docker-hub
  namespace: <gitlab-runner-project-name>
spec:
  tags:
    - name: latest
      from:
        kind: DockerImage
        name: 'docker.io/gitlab/gitlab-runner:bleeding'
      importPolicy:
        scheduled: true
      referencePolicy:
        type: Local

 

Step 4: Get the runner and token info

Get your token info from GitLab

  • Go to your GitLab instance at https://sc.unc.edu
  • Navigate to SettingsCI/CDRunners
  • Find or create a runner and copy the token

 

Step 5: Create ConfigMap

The Advanced Configuration stores the config.toml configuration file for registering runner.

In your OpenShift project:

  • Go to WorkloadsConfigMaps
  • Create ConfigMap
  • Replace the token line with: token = "your-actual-token-here" (sample config.toml below)
  • Click Save

 

Sample config.toml

concurrent = 4
check_interval = 0
log_level = "info"
listen_address = ":9252"  # Optional: for metrics
[session_server]
   session_timeout = 1800
[[runners]]
  name = "ocp-test-runner"  # Use the runner name created in Gitlab
  url = "https://sc.unc.edu" 
  token = "<redacted>"  # Use the token generated in Gitlab
  executor = "kubernetes"
  request_concurrency = 4
  environment = ["FF_USE_ADAPTIVE_REQUEST_CONCURRENCY=true"]  # Auto-adjust concurrency
  [runners.kubernetes]
        namespace = "<openshift_name_space>"
        image = "docker.io/gitlab/gitlab-runner-helper:x86_64-bleeding"
        # CORRECTED helper image tag (no extra hyphen)
        helper_image = "gitlab/gitlab-runner-helper:x86_64-bleeding"
        service_account = <gitlab-runner-sa>
        privileged = false
        pull_policy = "if-not-present"
           [runners.kubernetes.volumes]
             [[runners.kubernetes.volumes.empty_dir]]
               name = "runner-home"
               mount_path = "/home/gitlab-runner"
               medium = "Memory"
            # THIS FIXES THE GIT PERMISSION ISSUE
             [[runners.kubernetes.env]]
               name = "HOME"
               value = "/tmp"
             # Also set a writable GIT_CONFIG path
             [[runners.kubernetes.env]]
               name = "GIT_CONFIG"
               value = "/tmp/.gitconfig"
              # Method 1: Using env_variables (preferred)
             [[runners.kubernetes.env_variables]]
               name = "HOME"
               value = "/tmp"
             [[runners.kubernetes.env_variables]]
               name = "GIT_CONFIG"
               value = "/tmp/.gitconfig"

 

Step 6: Create deployment 

Your deployment will need writable home directory, so add volumes and add ConfigMap so the gitlab-runner will register. That should get the pod up and running. deployment.yml should look something like this:

kind: Deployment
apiVersion: apps/v1
metadata:
  name: gitlab-runner-docker-hub
  namespace: <openshiftnamespace>
spec:
  replicas: 1
  selector:
    matchLabels:
      app: gitlab-runner-docker-hub
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: gitlab-runner-docker-hub
    spec:
      restartPolicy: Always
      serviceAccountName: <gitlab-runner-sa>
      schedulerName: default-scheduler
      terminationGracePeriodSeconds: 30
      securityContext: {}
      containers:
        - resources:
            limits:
              cpu: 200m
              memory: 256Mi
            requests:
              cpu: 100m
              memory: 128Mi
          terminationMessagePath: /dev/termination-log
          name: container
          command:
            - /bin/sh
          env:
            - name: CI_SERVER_URL
              value: 'https://sc.unc.edu'
            - name: CI_SERVER_TOKEN
              valueFrom:
                secretKeyRef:
                  name: pc-docker-test-runner-secret
                  key: CI_SERVER_TOKEN
            - name: HOME
              value: /tmp/runner-home
          securityContext:
            capabilities:
              drop:
                - ALL
            allowPrivilegeEscalation: false
          imagePullPolicy: IfNotPresent
          volumeMounts:
            - name: runner-home
              mountPath: /tmp/runner-home
            - name: config
              mountPath: /tmp/runner-home/.gitlab-runner
          terminationMessagePolicy: File
          image: 'image-registry.openshift-image-registry.svc:5000/<namespace>/gitlab-runner-docker-hub@sha256:c4209fddcacdd77d8d228aea57f91486d059f6952befaf266e30d22a487407e5'
          args:
            - '-c'
            - |
              echo "Using config from ConfigMap at /tmp/runner-home/.gitlab-runner/config.toml"
              echo "Starting runner..."
              exec gitlab-runner run --user=gitlab-runner --working-directory=/tmp/runner-home
      serviceAccount: pc-gitlab-runner-sa
      volumes:
        - name: runner-home
          emptyDir: {}
        - name: config
          configMap:
            name: pc-test-gitlab-runner-config #configmap name
            defaultMode: 420
      dnsPolicy: ClusterFirst
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 25%
      maxSurge: 25%
  revisionHistoryLimit: 10
  progressDeadlineSeconds: 600

Restart the deployment

  • Go to WorkloadsDeployments
  • Click gitlab-runner-docker-hub
  • Click ActionsRestart Rollout

 

Verify the logs for the running pods

 

OR via CLI

oc logs -f deployment/gitlab-runner-docker-hub -n <projectname>

At this point, the status of the runner in Gitlab UI should be online

 

Step 7: Create pipeline

Create .gitlab-ci.yml file in your Gitlab project’s repository and can be updated by going to Build > PipelineEditor.

Here is an working example of CI file

variables:
  HOME: "/tmp"
  
before_script:
- echo "===== PREPARING ENVIRONMENT ====="
- echo "===== INSTALLING GIT ====="
- git version
- echo "===== CONFIGURING GIT ====="
- git config --global --add safe.directory "$CI_PROJECT_DIR"
- git config --global user.email "runner@example.com"
- git config --global user.name "GitLab Runner"
- echo "===== DEBUG INFO ====="
- whoami
- id
- pwd
- ls -la
- echo "HOME=$HOME"
- echo "CI_PROJECT_DIR=$CI_PROJECT_DIR"
- echo "===== READY ====="
test-job:
  script:
  - echo "Running test job..."
  - echo "System info:- $(uname -a)"
  - echo "Current directory:- $(pwd)"
  - echo "Git status:"
  - git status
  - echo "Creating a test file"
  - echo "Test content $(date)" > test-file.txt
  - echo "Adding file to git"
  - git add test-file.txt
  - echo "Committing file"
  - git commit -m "Add test file from CI job [skip ci]"
  - echo "Git log:"
  - git log --oneline -1
  - echo "All tests passed successfully!"
  
after_script:
  - echo "Job completed with exit code:- $?"

 

Step 8: Run pipeline

  • Trigger the pipeline or run it manually or rerun existing job.
  • You can view the status of the pipeline from Build > Jobs

  • Click on the job to see the pipeline output
Running with gitlab-runner 18.10.0~pre.781.gae674a65 (ae674a65)
  on ocp-test-runner QtDNHcjuV, system ID: r_xxxxxx
Preparing the "kubernetes" executor 00:00
Using default image
Using Kubernetes namespace: <openshit-namespace>
Using Kubernetes executor with image docker.io/gitlab/gitlab-runner-helper:x86_64-bleeding ...
Using attach strategy to execute scripts...
Using effective pull policy of [IfNotPresent] for container build
Using effective pull policy of [IfNotPresent] for container helper
Using effective pull policy of [IfNotPresent] for container init-permissions
Preparing environment 00:14
Using FF_USE_POD_ACTIVE_DEADLINE_SECONDS, the Pod activeDeadlineSeconds will be set to the job timeout: 1h0m0s...
Waiting for pod <namespace>/runner-qtdnhcjuv-project-5051-concurrent-0-ur08v3s9 to be running, status is Pending
Running on runner-qtdnhcjuv-project-5051-concurrent-0-ur08v3s9 via gitlab-runner-docker-hub-7f7d5d4f78-zgsbc...
Getting source from Git repository 00:01
Gitaly correlation ID: 01KKX5V5HMW266V2P3BT5S45T4
Fetching changes with git depth set to 20...
Initialized empty Git repository in /builds/<namespace>/ocp-testapp/.git/
Created fresh repository.
Checking out f57fb498 as detached HEAD (ref is main)...
Skipping Git submodules setup
Executing "step_script" stage of the job script 00:01
$ echo "===== PREPARING ENVIRONMENT ====="
===== PREPARING ENVIRONMENT =====
$ echo "===== INSTALLING GIT ====="
===== INSTALLING GIT =====
$ git version
git version 2.47.3
$ echo "===== CONFIGURING GIT ====="
===== CONFIGURING GIT =====
$ git config --global --add safe.directory "$CI_PROJECT_DIR"
$ git config --global user.email "runner@example.com"
$ git config --global user.name "GitLab Runner"
$ echo "===== DEBUG INFO ====="
===== DEBUG INFO =====
$ whoami
1014910000
$ id
uid=1014910000(1014910000) gid=0(root) groups=0(root),1014910000
$ pwd
/builds/<namespace>ocp-testapp
$ ls -la
total 16
drwxrwsrwx 3 1014910000 1014910000   74 Mar 17 05:56 .
drwxrwsrwx 4 1014910000 1014910000   48 Mar 17 05:56 ..
drwxrwsrwx 6 1014910000 1014910000  113 Mar 17 05:56 .git
-rw-rw-rw- 1 1014910000 1014910000 2329 Mar 17 05:56 .gitlab-ci.yml
-rw-rw-rw- 1 1014910000 1014910000 6175 Mar 17 05:56 README.md
-rw-rw-rw- 1 1014910000 1014910000  137 Mar 17 05:56 index.php
$ echo "HOME=$HOME"
HOME=/tmp
$ echo "CI_PROJECT_DIR=$CI_PROJECT_DIR"
CI_PROJECT_DIR=/builds/<namespace>/ocp-testapp
$ echo "===== READY ====="
===== READY =====
$ echo "Running test job..."
Running test job...
$ echo "System info:- $(uname -a)"
System info:- Linux runner-qtdnhcjuv-project-5051-concurrent-0-ur08v3s9 5.14.0-427.109.1.el9_4.x86_64 #1 SMP PREEMPT_DYNAMIC Wed Jan 28 17:07:26 EST 2026 x86_64 GNU/Linux
$ echo "Current directory:- $(pwd)"
Current directory:- /builds/<namespace>/ocp-testapp
$ echo "Git status:"
Git status:
$ git status
HEAD detached at f57fb49
nothing to commit, working tree clean
$ echo "Creating a test file"
Creating a test file
$ echo "Test content $(date)" > test-file.txt
$ echo "Adding file to git"
Adding file to git
$ git add test-file.txt
$ echo "Committing file"
Committing file
$ git commit -m "Add test file from CI job [skip ci]"
[detached HEAD d535b50] Add test file from CI job [skip ci]
 1 file changed, 1 insertion(+)
 create mode 100644 test-file.txt
$ echo "Git log:"
Git log:
$ git log --oneline -1
d535b50 Add test file from CI job [skip ci]
$ echo "All tests passed successfully!"
All tests passed successfully!
Running after_script 00:01
Running after script...
$ echo "Job completed with exit code:- $?"
Job completed with exit code:- 0
Cleaning up project directory and file based variables 00:00
Job succeeded

 


 

Details

Details

Article ID: 530
Created
Wed 4/1/26 2:53 PM
Modified
Wed 4/15/26 3:58 PM
Article Agent
The TDX agent acting as the primary point of contact for the article and is responsible for ensuring the content's accuracy on behalf of the group.