Deploying GitLab CE on Kubernetes: A Step-by-Step Guide

Deploying GitLab CE on Kubernetes: A Step-by-Step Guide

Deploying GitLab CE on Kubernetes can be achieved using both Helm charts and manual manifests. This guide will walk you through the process step-by-step, ensuring that you have a functioning GitLab CE instance. We will focus on creating a ConfigMap, setting up a Deployment, exposing it via a Service, and finally, binding a domain with an Ingress.

ConfigMap

First, you need to create a ConfigMap that will be used as the core GitLab file /etc/gitlab/gitlab.rb. I will disable many internal tools and modules to make the core GitLab UI function as a Git server.

Please note that, you will also require a persistent PostgreSQL database connection parameters.

apiVersion: v1
kind: ConfigMap
metadata:
  name: gitlab-config
data:
  EXTERNAL_URL: https://gitlab.example.com
  GITLAB_OMNIBUS_CONFIG: |
    # disable heavy features
    postgresql['enable'] = false
    registry['enable'] = false
    redis['enable'] = false
    nginx['enable'] = false
    logrotate['enable'] = false
    gitlab_kas['enable'] = false
    monitoring_role['enable'] = false
    prometheus['enable'] = false
    alertmanager['enable'] = false
    node_exporter['enable'] = false
    redis_exporter['enable'] = false
    postgres_exporter['enable'] = false
    gitlab_exporter['enable'] = false
    prometheus_monitoring['enable'] = false
    grafana['enable'] = false

    # web    
    gitlab_workhorse['listen_network'] = "tcp"
    gitlab_workhorse['listen_addr'] = "0.0.0.0:8181"

    # timezone
    gitlab_rails['time_zone'] = 'Asia/Dhaka'

    # database
    gitlab_rails['db_database'] = 'db_gitlab'
    gitlab_rails['db_username'] = 'user_gitlab'
    gitlab_rails['db_password'] = '0987abcd1234wxyz'
    gitlab_rails['db_host'] = '10.10.10.1'
    gitlab_rails['db_port'] = 5432

Deployment

Now we will create a deployment that will use the ConfigMap mentioned above. As you can see, I have added three extra volumes to persistently store the etc, log, and data directories. This is very important; otherwise, you will lose all your data every time you restart the pod. You are welcome to use any other volume type like hostPath, glusterfs, nfs, etc.

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: gitlab
  name: gitlab
spec:
  selector:
    matchLabels:
      app: gitlab
  template:
    metadata:
      labels:
        app: gitlab
    spec:
      containers:
      - envFrom:
        - configMapRef:
            name: gitlab-config
        image: gitlab/gitlab-ce
        name: app
        ports:
        - containerPort: 8181
          name: http
        volumeMounts:
        - mountPath: /etc/gitlab
          name: etc
        - mountPath: /var/opt/gitlab
          name: data
        - mountPath: /var/log/gitlab
          name: log
      volumes:
      - name: etc
        hostPath:
          path: /etc
      - name: data
        hostPath:
          path: /data
      - name: log
        hostPath:
          path: /var/log

Service

Once the pods are up and running, we need to expose the Deployment as a Service. You will notice that we have exposed port 8181 of the containers to forward web traffic to Gitlab workhorse.

apiVersion: v1
kind: Service
metadata:
  labels:
    app: gitlab
  name: gitlab
spec:
  ports:
    - name: http
      port: 8181
      targetPort: 8181
  selector:
    app: gitlab

Ingress

Finally, you need to bind a domain with the ingress.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: gitlab
spec:
  rules:
    - host: gitlab.example.com
      http:
        paths:
          - path: /
            backend:
              serviceName: gitlab
              servicePort: http
  tls:
    - hosts:
        - gitlab.example.com
      secretName: example-com-ssl