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.
The following table maps the Google Cloud products used in this tutorial to their use case in GitLab.
Datastore | Use case |
---|---|
Cloud Monitoring | 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 |
Memorystore for Redis | Temporary data Session data Background job queues |
This tutorial assumes an understanding of 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:
- Compute Engine
- Google Kubernetes Engine
- Cloud Load Balancing
- Cloud SQL
- Memorystore
- Container Registry
- Cloud Storage
- Cloud Monitoring
To generate a cost estimate based on your projected usage, use the pricing calculator. New Google Cloud users might be eligible for a free trial.
Before you begin
- Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
-
In the Google Cloud Console, on the project selector page, select or create a Google Cloud project.
-
Make sure that billing is enabled for your Cloud project. Learn how to confirm that billing is enabled for your project.
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
Open Cloud Shell:
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 \ sqladmin.googleapis.com
Configure 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}-gitlab-backups gsutil mb gs://${PROJECT_ID}-git-lfs gsutil mb gs://${PROJECT_ID}-gitlab-artifacts gsutil mb gs://${PROJECT_ID}-gitlab-uploads gsutil mb gs://${PROJECT_ID}-gitlab-packages gsutil mb gs://${PROJECT_ID}-gitlab-pseudo gsutil mb gs://${PROJECT_ID}-runner-cache gsutil mb gs://${PROJECT_ID}-registry
Configure networking
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"
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 services vpc-peerings connect \ --service=servicenetworking.googleapis.com --ranges=gitlab-sql \ --network=default --project ${PROJECT_ID}
Create the PostgreSQL instance and database
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_12 --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.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}
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
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
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
Use
kubectl
to create a secret in your cluster that holds the PostgreSQL password:kubectl create secret generic gitlab-pg --from-literal=password=${PASSWORD}
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
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
Create a secret to hold your GitLab registry parameters and Cloud Storage credentials:
cat > registry.gcs.yaml <<EOF gcs: bucket: ${PROJECT_ID}-gitlab-registry-storage keyfile: /etc/docker/registry/storage/gcs.json EOF kubectl create secret generic gitlab-registry-storage \ --from-file=storage=registry.gcs.yaml \ --from-file=gcs.json=gcs-key.json
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.
Verify Helm is installed
Verify that Helm is installed on Cloud Shell:
helm version
If Helm is correctly installed,
v3.2.1
or later appears:Client: version.BuildInfo{Version:"v3.2.1", GitCommit:"fe51cd1e31e6a202cba7dead9552a6d418ded79a", GitTreeState:"clean", GoVersion:"go1.13.10"}
If you don't see the a version number that's
v3.2.1
or later, follow the instructions in the Helm guide to install Helm.
Install the GitLab chart
The GitLab chart requires custom configuration so that it can leverage the external datastores that you previously provisioned.
Download the configuration file template:
wget https://raw.githubusercontent.com/terraform-google-modules/terraform-google-gke-gitlab/master/values.yaml.tpl
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 DOMAIN=${INGRESS_IP}.xip.io 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
Install the chart by using Helm:
helm repo add gitlab https://charts.gitlab.io/ helm install -f values.yaml gitlab gitlab/gitlab
Configure monitoring
You can monitor the GitLab installation by using the Prometheus integration. This integration deploys a Prometheus server to scrape metrics from GitLab. A sidecar container then sends metrics from Prometheus to Cloud Monitoring for longer term storage, dashboarding, and alerting.
Clone the Prometheus integration source code:
git clone https://github.com/stackdriver/stackdriver-prometheus-sidecar cd stackdriver-prometheus-sidecar/kube/full
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
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
Get the URL for your GitLab server:
export GITLAB_HOSTNAME=$(kubectl get ingresses.extensions gitlab-webservice-default \ -o jsonpath='{.spec.rules[0].host}') echo "Your GitLab URL is: https://${GITLAB_HOSTNAME}"
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.
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.
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.
Set up your first user account
When you are logged in, we recommend that you change the username and password of the root account.
In the top navigation bar, click the Admin Area button:
In the left navigation bar, click Users:.
Click the Edit button on the Administrator row to configure the account details:
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.
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 and adding additional layers of security such as mutual TLS database connections, visit the GitLab Chart documentation.
Cleaning up
- In the Cloud Console, go to the Manage resources page.
- In the project list, select the project that you want to delete, and then click Delete.
- In the dialog, type the project ID, and then click Shut down to delete the project.
What's next
- Try out other Google Cloud features for yourself. Have a look at our tutorials.