Connecting GitLab to Kubernetes

Brian Michalski
4 min readNov 22, 2018

--

GitLab has this cool looking “Add Kubernetes Cluster” button which let’s you connect a project to Kubernetes and automate the DevOps workflow. I’m honestly not entirely sure what it does, but the button looks cool and I’ve been wanting to click it for a few months now.

By default, GitLab connects to Google Cloud Platform and can setup GKE automatically, but there is also an option to connect it to an existing cluster. GKE doesn’t really have a free tier, so I went the homemade route and worked through the steps to connect GitLab to a Kubernetes cluster running on some spare Raspberry Pi’s I had laying around.

This post assumes you have a pretty vanilla Kubernetes cluster and that you have virtually no clue what you’re doing (like me). To setup my cluster, I followed this tutorial, but there are plenty of others like it. To integrate it with Gitlab we need to 1) Enable the API for remote access 2) Create a system account, and 3) Set it up in the Gitlab UI.

Enabling API Access

The Kubernetes API is only available over HTTPS (by default?) and uses a bunch of self-signed certificates in the process. Those self-signed certificates reference the hostname of the Master Node — which in my case has an address like 192.168.1.2. If you try and connect to that Master Node using an address other than 192.168.1.2, like an external IP address or public DNS name, the TLS check will fail because the certificate doesn’t include that name. GitLab will need to connect using an external IP or public DNS name, so we need to update the certificates for the API server to keep the TLS gods happy.

To fix this, we can use the kubeadm command to re-run the certs phase of the setup shown below which will recreate certificates with additional hostnames. Plug your external IP instead of 73.112.123.115 and/or hostname instead of kubernetes.yoursite.com[ref]. You probably need to sudo to run most or all of these commands.

rm /etc/kubernetes/pki/apiserver.*kubeadm alpha phase certs all --apiserver-advertise-address=0.0.0.0 --apiserver-cert-extra-sans=73.112.123.115,kubernetes.yoursite.comdocker rm -f `docker ps -q -f 'name=k8s_kube-apiserver*'`systemctl restart kubelet

On your firewall / router, forward port 6443 to the internal IP of the Kubernetes master node. Boom, the internet can talk to your API server.

Adding a Service Account

Instead of giving GitLab your default login information I created a new Service Account and granted it cluster-admin privileges to set everything up. To create a new Service Account called “gitlab” use:

kubectl create serviceaccount gitlab

And assign it the cluster-admin role using:

kubectl create clusterrolebinding gitlab-cluster-admin --clusterrole=cluster-admin --serviceaccount=default:gitlab

In this case, gitlab-cluster-admin refers to the name of this service account↔role mapping and our service account was created in the default namespace

Filling out the Gitlab UI

The Gitlab UI asks for a bunch of information but has pretty limited documentation about what the right values are suppose to look like.

Kubernetes cluster name: Any name you want to reference this cluster.

API URL: https://73.112.123.115:6443, substitute in your external IP address or public DNS name for the cluster.

CA Certificate: This value should be the same for all users accessing your cluster but you can use a command to fish it out for the specific Service Account we’ll be using.

  1. Use kubectl get secrets to list all of the secrets available, there should be one for the gitlab user we created earlier, like gitlab-token-r56q4.
  2. Use kubectl get secret gitlab-token-r56q4 -o jsonpath=”{[‘data’][‘ca\.crt’]}” | base64 -d to extract the value of the certificate and base64 decode it. Replace gitlab-token-r56q4 with the name of the secret from step #1. This should look like an SSL certificate in PEM format (if that does anything for you).

Token: Usekubectl get secret gitlab2-token-r56q4 -o jsonpath=”{[‘data’][‘token’]}” | base64 -d again replacing gitlab-token-r56q4 with the name of your secret.

Project namespace (optional, unique): Leave blank. gitlab will auto generate this.

RBAC-enabled cluster: Check the box. I don’t know what RBAC is, but it seems to be setup by default(?) on most clusters.

The final form should look something like this —

Click “Add Kubernetes cluster” and enjoy your setup!

If for some reason that didn’t work] I found it useful to try to cURL at your API server from another external machine using a command like:

curl --cacert <file containing CA Certificate> -H "Authorization: Bearer eyJhb...<token value here>" https://73.112.123.115:6443/api/v1/namespaces/default/pods

You should see a JSON structure describing your pods (if any). The errors from cURL are pretty useful to debug and seem to provide a bit more detail than the Gitlab UI currently does.

Happy clustering!

July 2020 Update: Check out this post for some tips how to get started using your Gitlab managed cluster.

--

--

Brian Michalski

Engineer @ Google working on Maps + Cloud (@GMapsPlatform). Open Source [Digital Signage, Vehicle Tracking] Developer.