Deploying production-ready GitLab on Google Kubernetes Engine

This document describes how to deploy a scalable, reliable, and observable GitLab instance on Google Kubernetes Engine (GKE). GitLab is an open source application that helps its users plan, store, test, and deploy their source code. Its core functionality is that of a source code management platform, but it also includes features for project management, continuous integration, and continuous deployment.

In this tutorial, you deploy the following architecture. You use GKE for GitLab's application components and Google Cloud managed services where possible to decrease the operational burden of running GitLab. You use Helm as the mechanism to install and configure the GitLab application components in GKE.

Architecture that uses GKE for GitLab's application components and Google Cloud
managed services to decrease the operational burden of running GitLab

The following table maps the Google Cloud products used in this tutorial to their use case in GitLab.

Datastore Use case
Stackdriver Durable monitoring metric storage
Metric dashboarding
Alerting
System logs
Cloud Storage Backups
Large file storage
Build artifacts
Uploads
Cloud SQL for PostgreSQL Application metadata
User information
Cloud Memorystore for Redis Temporary data
Session data
Background job queues

This tutorial assumes an understanding of Cloud Identity and Access Management (IAM), Google Kubernetes Engine, and Cloud SQL.

If you are looking for a more automated approach to installation, use the GitLab on GKE Terraform module on GitHub.

Objectives

  • Create backing datastores to host GitLab data.
  • Install GitLab in a GKE cluster.
  • Connect to GitLab.

Costs

This tutorial uses the following billable components of Google Cloud Platform:

  • Compute Engine
  • Google Kubernetes Engine
  • Cloud Load Balancing
  • Cloud SQL
  • Cloud Memorystore
  • Container Registry
  • Cloud Storage
  • Stackdriver Monitoring

To generate a cost estimate based on your projected usage, use the pricing calculator. New GCP users might be eligible for a free trial.

Before you begin

  1. Sign in to your Google Account.

    If you don't already have one, sign up for a new account.

  2. Select or create a GCP project.

    Go to the project selector page

  3. Make sure that billing is enabled for your Google Cloud Platform project. Learn how to enable billing.

When you finish this tutorial, you can avoid continued billing by deleting the resources you created. For more information, see Cleaning up.

Creating prerequisite resources

Enable APIs

  1. Open Cloud Shell:

    Open Cloud Shell

  2. In Cloud Shell, enable the Google Kubernetes Engine, Service Networking, Resource Manager, and Redis APIs:

    gcloud services enable container.googleapis.com \
           servicenetworking.googleapis.com \
           cloudresourcemanager.googleapis.com \
           redis.googleapis.com
    

Configure Cloud IAM

  • Create an IAM service account for GitLab. Then add the storage.admin role to it so that it can access Cloud Storage.

    export PROJECT_ID=$(gcloud config get-value project)
    gcloud iam service-accounts create gitlab-gcs \
        --display-name "GitLab Cloud Storage"
    gcloud iam service-accounts keys create --iam-account \
        gitlab-gcs@${PROJECT_ID}.iam.gserviceaccount.com gcs-key.json
    gcloud projects add-iam-policy-binding --role roles/storage.admin ${PROJECT_ID} \
        --member=serviceAccount:gitlab-gcs@${PROJECT_ID}.iam.gserviceaccount.com
    

Create Cloud Storage buckets

  • Use the gsutil command-line tool to create the buckets used by GitLab:

    export PROJECT_ID=$(gcloud config get-value project)
    gsutil mb gs://${PROJECT_ID}-uploads
    gsutil mb gs://${PROJECT_ID}-artifacts
    gsutil mb gs://${PROJECT_ID}-lfs
    gsutil mb gs://${PROJECT_ID}-packages
    gsutil mb gs://${PROJECT_ID}-registry
    

Configure networking

  1. Create an external IP address that can be used to reach your GitLab instance:

    gcloud compute addresses create gitlab --region us-central1 \
        --description "Gitlab Ingress IP"
    
  2. Create a private IP address range that can be assigned to your Cloud SQL for PostgreSQL database instance so that it can't be reached from outside of your VPC network:

    export PROJECT_ID=$(gcloud config get-value project)
    gcloud compute addresses create gitlab-sql --global --prefix-length 20 \
        --description="Gitlab Cloud SQL range" --network=default
    gcloud beta services vpc-peerings connect \
        --service=servicenetworking.googleapis.com --ranges=gitlab-sql \
        --network=default --project ${PROJECT_ID}
    

Create the PostgreSQL instance and database

  1. Create the Cloud SQL database that GitLab will use to store most of its metadata:

    gcloud beta sql instances create gitlab-db --network default \
        --database-version=POSTGRES_9_6 --cpu 4 --memory 15 --no-assign-ip \
        --storage-auto-increase --zone us-central1-a
    

    This command creates a privately accessible PostgreSQL database in the default network, with 4 CPU cores and 15 GB of RAM. The disk size of the database is set to increase automatically as needed.

  2. Create a database user and password for GitLab to authenticate to the database:

    export PASSWORD=$(openssl rand -base64 18)
    gcloud sql users create gitlab --instance gitlab-db --password ${PASSWORD}
    
  3. Create the database that GitLab will use in your PostgreSQL instance:

    gcloud sql databases create --instance gitlab-db gitlabhq_production
    

Create the Redis instance

  • Create the Redis instance. For more information on sizing the Redis instance, see the GitLab requirements documentation.

    gcloud redis instances create gitlab --size=2 --region=us-central1 \
        --zone=us-central1-a --tier standard
    

Create and configure the GKE cluster

  1. Create the GKE cluster that you will use to host the GitLab application's components. The Alias IP feature must be enabled in the cluster so that it can talk to the Redis instance.

    gcloud container clusters create gitlab --machine-type n1-standard-4 \
        --zone us-central1-a --enable-ip-alias
    
  2. Create a Storage Class so that GitLab can store its Git repositories on SSD Persistent Disks:

    cat > pd-ssd-storage.yaml <<EOF
    apiVersion: storage.k8s.io/v1
    kind: StorageClass
    metadata:
      name: pd-ssd
    provisioner: kubernetes.io/gce-pd
    parameters:
      type: pd-ssd
    EOF
    kubectl apply -f pd-ssd-storage.yaml
    
  3. Use kubectl to create a secret in your cluster that holds the PostgreSQL password:

    kubectl create secret generic gitlab-pg --from-literal=password=${PASSWORD}
    
  4. Create a secret to hold your Cloud Storage credentials:

    kubectl create secret generic google-application-credentials \
        --from-file=gcs-application-credentials-file=./gcs-key.json
    
  5. Create a secret to hold the additional parameters that Rails needs in order to configure the large file storage, artifacts, upload, and packages features:

    export PROJECT_ID=$(gcloud config get-value project)
    
    cat > rails.yaml <<EOF
    provider: Google
    google_project: ${PROJECT_ID}
    google_client_email: gitlab-gcs@${PROJECT_ID}.iam.gserviceaccount.com
    google_json_key_string: '$(cat gcs-key.json)'
    EOF
    kubectl create secret generic gitlab-rails-storage --from-file=connection=rails.yaml
    

Configuring and installing GitLab

In this section, you use Helm to deploy GitLab from the GitLab Chart repository. Helm is a package manager you can use to configure and deploy Kubernetes apps.

Install Helm

  1. Download and install the helm binary:

    wget https://storage.googleapis.com/kubernetes-helm/helm-v2.12.3-linux-amd64.tar.gz
    
  2. Unzip the file to your local system:

    tar zxfv helm-v2.12.3-linux-amd64.tar.gz
    cp linux-amd64/helm .
    
  3. Grant Tiller, the server side of Helm, the cluster-admin role in your cluster:

    kubectl create serviceaccount tiller --namespace kube-system
    kubectl create clusterrolebinding tiller-admin-binding \
        --clusterrole=cluster-admin --serviceaccount=kube-system:tiller
    
  4. Initialize Helm to install Tiller in your cluster:

    ./helm init --service-account=tiller
    ./helm update
    
  5. Ensure that Helm is properly installed by running the following command:

    ./helm version
    

    If Helm is correctly installed, v2.12.3 appears for both client and server:

    Client: &version.Version{SemVer:"v2.12.3", GitCommit:"eecf22f77df5f65c823aacd2dbd30ae6c65f186e", GitTreeState:"clean"}
    Server: &version.Version{SemVer:"v2.12.3", GitCommit:"eecf22f77df5f65c823aacd2dbd30ae6c65f186e", GitTreeState:"clean"}
    

Install the GitLab chart

The GitLab chart requires custom configuration so that it can leverage the external datastores that you previously provisioned.

  1. Download the configuration file template:

    wget https://raw.githubusercontent.com/terraform-google-modules/terraform-google-gke-gitlab/master/values.yaml.tpl
    
  2. Create the configuration file:

    export PROJECT_ID=$(gcloud config get-value project)
    export INGRESS_IP=$(gcloud compute addresses describe gitlab \
        --region us-central1 --format 'value(address)')
    export DB_PRIVATE_IP=$(gcloud sql instances describe gitlab-db \
        --format 'value(ipAddresses[0].ipAddress)')
    export REDIS_PRIVATE_IP=$(gcloud redis instances describe gitlab \
        --region=us-central1  --format 'value(host)')
    export CERT_MANAGER_EMAIL=$(gcloud config get-value account)
    
    cat values.yaml.tpl | envsubst > values.yaml
    
  3. Install the chart by using Helm:

    ./helm repo add gitlab https://charts.gitlab.io/
    ./helm install -f values.yaml --version 1.7.1 -n gitlab gitlab/gitlab
    

Configure monitoring

You can monitor the GitLab installation by using the Stackdriver Prometheus integration. This integration deploys a Prometheus server to scrape metrics from GitLab. A sidecar container then sends metrics from Prometheus to Stackdriver for longer term storage, dashboarding, and alerting.

  1. Clone the Prometheus integration source code:

    git clone https://github.com/stackdriver/stackdriver-prometheus-sidecar
    cd stackdriver-prometheus-sidecar/kube/full
    
  2. Configure the installation by setting the following environment variables:

    export KUBE_NAMESPACE=default
    export KUBE_CLUSTER=gitlab
    export GCP_REGION=us-central1
    export GCP_PROJECT=$(gcloud config get-value project)
    export SIDECAR_IMAGE_TAG=release-0.4.2
    
  3. Install the Prometheus integration:

    ./deploy.sh
    

    Your metrics from GitLab will now be added automatically to Monitoring.

Using GitLab

Now that GitLab is up and running, connect to it and set up the initial user password.

Initial login

  1. Get the URL for your GitLab server:

    export GITLAB_HOSTNAME=$(kubectl get ingresses.extensions gitlab-unicorn \
        -o jsonpath='{.spec.rules[0].host}')
    echo "Your GitLab URL is: https://${GITLAB_HOSTNAME}"
    
  2. Get the initial root account password:

    kubectl get secret gitlab-gitlab-initial-root-password \
        -o go-template='{{.data.password}}' | base64 -d && echo
    

    The 64-character string printed to the console is the password. Store it for later.

  3. Ensure that all pods have reached the healthy state:

    kubectl get pods
    

    It can take 3–5 minutes for all pods to reach the intended state.

  4. Visit the GitLab URL in your browser from step 1 and log in as the root user with the password from step 2. The following screenshot shows the login page.

    GitLab login page

Set up your first user account

When you are logged in, we recommend that you change the username and password of the root account.

  1. In the top navigation bar, click the Admin Area button:

    GitLab Admin Area

  2. In the left navigation bar, click Users:.

    Left navigation bar of GitLab

  3. Click the Edit button on the Administrator row to configure the account details:

    Edit button on Administrator row

  4. In the form that is presented, change the Name, Username, Email, and Password fields, and then click the Save changes button at the bottom.

    You are signed out.

  5. Log in with your new username and password.

You are now ready to use GitLab. Visit the GitLab documentation to learn more about how to interact with it. For more information on customizing your installation, visit the GitLab Chart documentation.

Cleaning up

  1. In the GCP Console, go to the Manage resources page.

    Go to the Manage resources page

  2. In the project list, select the project you want to delete and click Delete .
  3. In the dialog, type the project ID, and then click Shut down to delete the project.

What's next

  • Try out other Google Cloud Platform features for yourself. Have a look at our tutorials.
Was this page helpful? Let us know how we did:

Send feedback about...