GitLab

From Leo's Notes
Last edited on 7 December 2022, at 17:22.


Installation

Docker based

Using docker-compose, we can quickly deploy GitLab with the following service definition. GitLab will be served on port 8888 with the registry served on port 5001. I then use Traefik (configured using container labels) to expose GitLab to the internet.

version: '3.3'

services:
  gitlab:
    image: gitlab/gitlab-ce:latest
    container_name: gitlab
    environment:
      GITLAB_OMNIBUS_CONFIG: |
        external_url 'https://git.steamr.com'
        nginx['listen_port'] = '8888'
        nginx['listen_https'] = false
        nginx['proxy_set_headers'] = { 'X-Forwarded-Proto' => 'https', 'X-Forwarded-Ssl' => 'on' }
        registry_external_url 'https://registry.steamr.com'
        registry['enable'] = true
        gitlab_rails['registry_enabled'] = true
        registry_nginx['listen_port'] = 5001
        registry_nginx['listen_https'] = false
        registry_nginx['proxy_set_headers'] = { 'X-Forwarded-Proto' => 'https', 'X-Forwarded-Ssl' => 'on' }
    volumes:
      - /volumes/gitlab/config:/etc/gitlab
      - /volumes/gitlab/logs:/var/log/gitlab
      - /volumes/gitlab/data:/var/opt/gitlab
    restart: always
    expose:
      - "8888"
      - "5001"

With Kubernetes

GitLab provides a set of helm charts which can be used to deploy GitLab. Configuration is done with the ConfigMaps.

# helm repo add gitlab https://charts.gitlab.io/
# helm install gitlab/gitlab --name=gitlab --namespace=default --set global.operator.enabled=true --set global.operator.bootstrap=true -f gitlab-config.yml  --debug
# kubectl get secret gitlab-gitlab-initial-root-password -ojsonpath='{.data.password}' | base64 --decode ; echo

The unicorn/workhorse pod used to drive the GitLab web application gets its configs from the gitlab-unicorn ConfigMap.

Upgrading

When upgrading, review the change logs to determine the appropriate upgrade path. The upgrade paths that you should take can be determined using this tool: https://gitlab-com.gitlab.io/support/toolbox/upgrade-path/

In general, your upgrade path needs to go through all the major revisions. For example, starting from 13.8.1 and upgrading to 14.3.0, you need to hop through to 13.8.Z, 13.9.Z, ... 13.12.Z, 14.0.Z, 14.1.Z, ..., 14.3.Z, where Z is the highest release number in that version. Use the upgrade path tool above to determine which versions are not required.

Upgrades should be scheduled periodically to avoid falling too far back as it may complicate the upgrade process and expose you to security vulnerabilities.

CI/CD Setup

GitLab has a built-in CI/CD pipeline feature that can automate certain tasks when code is committed into a repository. Some examples of CI/CD pipelines include compiling/building releases, running unit tests, or triggering certain web hooks when code is committed.

CI/CD pipelines can run in various ways. Most common is to use a Docker container to run CI/CD code in.

Docker based

I run the GitLab runner on a separate docker host from the GitLab instance. This is because GitLab runners will run with privileged mode and at worst pollutes the production docker environment with heaps of temporary build containers, and at worst can potentially interfere with the production GitLab environment.

Navigate to the settings page of a GitLab repository. Under CI/CD, go to 'Runners' and find the 'set up a specific runner manually' section. This section should contain the runner registration token.

To start the runner, I use the following docker command.

docker run --rm \
     -v /root/config:/etc/gitlab-runner \
     -v /var/run/docker.sock:/var/run/docker.sock \
     gitlab/gitlab-runner:latest \
     register -n --url https://git.steamr.com/ \
        --registration-token z276ujRTK69qD8xb-aNH \
        --executor docker \
        --docker-image "docker:stable"

Review the configuration that was generated and modify it as required. What I have is the following.

concurrent = 1
check_interval = 0

[session_server]
  session_timeout = 1800
  
[[runners]]
  name = "docker runner"
  url = "https://git.steamr.com/"
  token = "********"
  executor = "docker"
  [runners.docker]
    tls_cert_path = ""
    tls_verify = false
    image = "docker:stable"
    # alpine:latest"
    privileged = true
    disable_entrypoint_overwrite = false
    oom_kill_disable = false
    disable_cache = false
    volumes = ["/cache", "/var/run/docker.sock:/var/run/docker.sock"]
    shm_size = 0
  [runners.cache]
    [runners.cache.s3]
    [runners.cache.gcs]

To start the runner, use the following command

docker run -d --name gitlab-runner --restart always \
     -v /root/config:/etc/gitlab-runner \
     -v /var/run/docker.sock:/var/run/docker.sock \
     gitlab/gitlab-runner:latest

Kubernetes based

To install a GitLab runner with Helm, install the GitLab repo and then the helm chart. You might want to use an existing values.yaml file from https://gitlab.com/gitlab-org/charts/gitlab-runner/blob/master/values.yaml as a reference.

# helm repo add gitlab https://charts.gitlab.io
# helm install \
        --namespace gitlab \
        --name gitlab-runner \
        -f values.yaml \
        --set gitlabUrl=https://git.caas.ucalgary.ca,runnerRegistrationToken=xxxxxxxxxxx \
        gitlab/gitlab-runner

Troubleshooting

Failed to create listener - address family not supported

Runner container crashes with a fatal error message:

FATAL: Failed to create listener for metrics server  builds=0 error=listen tcp [::]:9252: socket: address family not supported by protocol

To fix, set in values.yaml:

envVars:
  - name: LISTEN_ADDRESS
    value: :9252

Docker-based CI/CD runner fails - docker no such host

My CI/CD pipeline fails with the following error:

ERROR: error during connect: Get http://docker:2375/v1.40/info: dial tcp: lookup docker on 10.1.2.200:53: no such host

This is caused because the runner is trying to reach the docker engine via the 'docker' DNS name rather than with the path based socket. To fix this, ensure that the docker runner has /var/run/docker.sock mounted as a volume and that the runner config has the following two lines:

privileged = true
volumes = ["/cache", "/var/run/docker.sock:/var/run/docker.sock"]

Remove/restart the runner and restart the pipeline.

Tasks

Registry Cleanup

The docker registry does not remove deleted images. Like a bad memory leak, the registry will grow as old images are still stored even when dereferenced and deleted.

Use the docker-distribution-pruner utility which can be obtained from their project CI / CD page:

On the GitLab instance, run the following:

## This will soft-delete the files to /var/opt/gitlab/gitlab-rails/shared/registry/docker-backup
# EXPERIMENTAL=true ./docker-distribution-pruner -config=/var/opt/gitlab/registry/config.yml -delete
INFO[0000] Walking REPOSITORIES...
INFO[0000] REPOSITORIES DIR: repositories
INFO[0000] Walking BLOBS...
...
INFO[0001] BLOBS INFO: Objects/Unused: 296 / 75 Data/Unused: 3.0 GB / 398 MB
WARN[0001] DELETEABLE INFO: 115 links, 75 blobs, 0 other, 398 MB

## Remove the files
# rm -rf /var/opt/gitlab/gitlab-rails/shared/registry/docker-backup

Backups

GitLab using the Helm Chart can be backed up by running backup-utility inside the GitLab runner container. Backups that are generated will be placed at /srv/gitlab/tmp/backup as defined by the backup.path parameter in /srv/gitlab/config/gitlab.yml.

Omnibus GitLab can be backed up by scheduling a task that runs /opt/gitlab/bin/gitlab-rake gitlab:backup:create. The destination is configured based on the gitlab_rails['backup_path'] value in /etc/gitlab/gitlab.rb. Specific components can be skipped by passing in the SKIP value. For example:

# /opt/gitlab/bin/gitlab-rake gitlab:backup:create SKIP=registry,pages,artifacts,builds  DIRECTORY=daily

See Also:

To restore, run gitlab-rake gitlab:backup:restore BACKUP=1571687885_2019_10_21_12.3.5-ee, to target a backup file in the backup directory named 1571687885_2019_10_21_12.3.5-ee_gitlab_backup.tar.

git@gitlab-task-runner-6c64cd44f8-wvjb4:/srv/gitlab/tmp/backups$ gitlab-rake gitlab:backup:restore BACKUP=1571687885_2019_10_21_12.3.5-ee
WARNING: This version of GitLab depends on gitlab-shell 10.0.0, but you're running Unknown. Please update gitlab-shell.
Unpacking backup ...