GitLab and IBM Cloud Private
A major part of Application Modernization (AppMod) is to modernize the build and deployment process for existing applications to prepare for the Cloud. Many organizations already embrace CI/CD for their new application development, however the older Java applications are often left behind with a manual build process and their source code stored on developers file systems in Eclipse workspaces. In order to quickly show the benefits that storing source code in Git and automating build and deployment using Maven and Jenkins can bring I’ve taken to installing the GitLab Helm Chart in IBM Cloud Private to provide Source Control for the applications that I am modernizing. Of course, if an organization already has GitHub Enterprise or some other source control system then I am happy to use their existing framework, but in many circumstances getting access and new repositories created can be time consuming and it is then that I choose to standup my own, private SCM to demonstrate the AppMod benefits.
I faced some challenges working out how to connect to GitLab running in ICP using SSH (because GitLab wants to use port 22 which is often taken by the Linux host) and HTTPS (as in a private network the certificates are self-signed).
Let’s start by Installing GitLab. We’ll need some storage.
If you don’t have a dynamic provisioner for your Kubernetes Persistent Volumes, create the following Persistent Volumes on your NFS server:
- Name: gitlab; Size: 50GB; Access Mode: RWO
- Name: gitlab-minio; Size: 10GB; Access Mode: RWO
- Name: gitlab-postgresql; Size: 8GB; Access Mode: RWO
- Name: gitlab-redis; Size: 5GB; Access Mode: RWO
Here is a sample yaml file that will create the Persistent Volumes on an NFS server.
apiVersion: v1
kind: PersistentVolume
metadata:
name: gitlab
spec:
capacity:
storage: 50Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Recycle
nfs:
path: /storage/gitlab
server: 9.37.138.12
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: gitlab-minio
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Recycle
nfs:
path: /storage/gitlab-minio
server: 9.37.138.12
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: gitlab-postgresql
spec:
capacity:
storage: 8Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Recycle
nfs:
path: /storage/gitlab-postgresql
server: 9.37.138.12
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: gitlab-redis
spec:
capacity:
storage: 5Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Recycle
nfs:
path: /storage/gitlab-redis
server: 9.37.138.12
Now we are ready to use Helm to install the GitLab Chart.
Add the public GitLab chart repo to your helm repositories using the commands below.
helm repo add gitlab https://charts.gitlab.io
helm repo update
GitLab provides a set of command line parameters that can be used to configure the helm chart during installation.
The command below installs GitLab for using in an IBM Cloud Private environment:
- the global.ingress.enabled=true and nginx-ingress.enabled=false parameters tell GitLab that we will be using the Kubernetes Ingress provided by IBM Cloud Private
- parameters global.hosts.https=true, certmanager.install=false and global.ingress.configureCertmanager=false configure GitLab with self-signed SSL certificates which is often required in Private Cloud environments as CA certificates are hard to get for non-public URLs.
- parameters global.hosts.externalIP and global.hosts.domain sets the domain that will be used for the ingress URLs to an IP address (which is also often required in a Private Cloud environments where the IBM Cloud Private proxies haven’t been configured with a DNS name.
- the global.shell.port parameter is used to set GitLab to use port 2222 for SSH instead of the default port 22
- the certmanager.install=false and gitlab-runner.install=false turn off components that don’t run well in a Private Cloud.
helm upgrade --install gitlab gitlab/gitlab --tls \
--set global.edition=ee \
--set global.ingress.enabled=true \
--set nginx-ingress.enabled=false \
--set certmanager.install=false \
--set global.ingress.configureCertmanager=false \
--set gitlab-runner.install=false \
--set global.hosts.https=true \
--set global.hosts.externalIP=9.37.138.12 \
--set global.hosts.domain=9.37.138.12.nip.io \
--set global.ingress.class= \
--set global.shell.port=2222 \
--set prometheus.install=false \
--set gitlab.sidekiq.minReplicas=1 \
--set gitlab.sidekiq.maxReplicas=1 \
--set registry.minReplicas=1 \
--set registry.maxReplicas=1 \
--set gitlab.unicorn.minReplicas=1 \
--set gitlab.unicorn.maxReplicas=1 \
--set gitlab.gitlab-shell.minReplicas=1 \
--set gitlab.gitlab-shell.maxReplicas=1
Once GitLab is installed and all of the pods have started correctly, it is necessary to update the IBM Cloud Private Ingress Controller to use port 2222 for SSH traffic and to direct that traffic to the gitlab-shell service on port 22. The command below shows that the service is listening on port 22.
kubectl get services | grep gitlab-shellgitlab-gitlab-shell ClusterIP 10.0.0.33 <none> 22/TCP 59m
GitLab has created tcp-config-services ConfigMap to help with this task named gitlab-nginx-ingress-tcp. The command below describes the ConfigMap. Note that the Data in the configmap states the port to listen on and where to send the data.
kubectl describe configmap gitlab-nginx-ingress-tcpName: gitlab-nginx-ingress-tcp
Namespace: default
Labels: app=gitlab-shell
chart=gitlab-shell-1.7.0
heritage=Tiller
release=gitlab
Annotations: <none>
Data
====
2222:
----
default/gitlab-gitlab-shell:22
Events: <none>
This ConfigMap must be added to the IBM Cloud Private Ingress DaemonSet as a tcp-services-configmap argument.
1. Use kubectl to edit the definition of the nginx-ingress-controller
deamonset
kubectl edit daemonset nginx-ingress-controller -n kube-system
2. In the spec.container.args
section add a new line with the value —-tcp-services-configmap=default/gitlab-nginx-ingress-tcp
as shown below
spec:
containers:
- args:
- /nginx-ingress-controller
- -- default-backend-service=$(POD_NAMESPACE)/default-backend
- -- configmap=$(POD_NAMESPACE)/nginx-ingress-controller
- --tcp-services-configmap=default/gitlab-nginx-ingress-tcp
- --annotations-prefix=ingress.kubernetes.io
- --enable-dynamic-configuration=true
- --enable-ssl-passthrough=true
- --publish-status-address=9.37.138.12
3. Scroll down to the spec.container.ports
section and add a new containerPort
for port 2222
as shown below:
ports:
- containerPort: 80
hostPort: 80
name: http
protocol: TCP
- containerPort: 443
hostPort: 443
name: https
protocol: TCP
- containerPort: 2222
hostPort: 2222
name: ssh
protocol: TCP
4. Save your changes to the definition of the nginx-ingress-controller
deamonset and wait for the pods to restart.
Next we will create a new GitLab User and our first GitLab Project.
1. Open GitLab in a browser using the Ingress URL (https://gitlab.9.37.138.12.nip.io
in my case)
2. Register for a new account. In this example I will be using the user liberty
.
3. Click the Create a project button and create a project. In this example I will be using a project called test
Now that we have a user and a project, we can configure GitLab for SSH. In order to do that you must upload a public key.
1. In GitLab, click on your user icon in the top right corner and select Settings
2. Select SSH Keys from the menu on the left side.
3. If you don’t have an SSH key-pair, there is a link provided to help you create one. If you do have a key-pair, copy the contents of your public key in to the box provided and click Add Key
4. You can now optionally test that SSH is configured correctly for GitLab. From the machine where your private key is installed enter the following command (change the URL as necessary):
ssh -Tv -p 2222 git@gitlab.9.37.138.12.nip.io
You should receive a prompt to enter the passphrase for your private key after debug statements that verify the public key exchange completed correctly:
debug1: Offering public key: /Users/dmulley@us.ibm.com/.ssh/id_rsa RSA SHA256:ydUoID/S/fw7wz1FNUH5vDl3aUhy2xayg5rIcvOi8bQ
debug1: Server accepts key: /Users/dmulley@us.ibm.com/.ssh/id_rsa RSA SHA256:ydUoID/S/fw7wz1FNUH5vDl3aUhy2xayg5rIcvOi8bQ
Enter passphrase for key ‘/Users/dmulley@us.ibm.com/.ssh/id_rsa’:
You will then see a message that authentication succeeded and the command will exit with a welcome message and status 0
debug1: Authentication succeeded (publickey).
Authenticated to gitlab.9.37.138.12.nip.io ([9.37.138.12]:2222).
…
Welcome to GitLab, @liberty!
debug1: channel 0: free: client-session, nchannels 1
Transferred: sent 3488, received 3296 bytes, in 0.4 seconds
Bytes per second: sent 8916.8, received 8426.0
debug1: Exit status 0
SSH is now configured.
For reference, I’ve included some tips on using SSH on port 2222 with command line Git here.
Assuming you are running the git command line on the machine that your private-key is installed then no additional configuration is required. Git requires a specific URL format when using SSH on a port other than 22. In the case of the example project used in this document the URL is ssh://git@gitlab.9.37.138.12.nip.io:2222/liberty/test.git
For Git the command line configuration to add the repo as a remote origin would be:
git remote add origin ssh://git@gitlab.9.37.138.12.nip.io:2222/liberty/test.git
To clone the repo at a Git command line the command would be:
git clone ssh://git@gitlab.9.37.138.12.nip.io:2222/liberty/test.git
Now let’s cover how to connect Jenkins to your new Gitlab project.
Jenkins requires that you upload your SSH private-key in order to make SSH connections to Gitlab. In this example a new Jenkins job will be created and connected to the test
Gitlab project.
1. In Jenkins, click New Item and create a new Multibranch Pipeline named test-gitlab
and click `OK`
2. In the Branch Sources section, click Add Source → Git
3. On the Credentials line, click Add and select Jenkins
4. On the Add Credentials page, select SSH Username with private key
from the Kind drop-down. Enter liberty
as the Username (to match the Gitlab user), click the Enter directly option on the Private Key line and paste your private-key (including the BEGIN RSA PRIVATE KEY and END RSA PRIVATE KEY lines). Enter your passphrase in the Passphrase box and click Add
5. When you are returned to the `Branch Sources` section, enter ssh://git@gitlab.9.37.138.12.nip.io:2222/liberty/test.git
as the Project Repository and ensure that the Credentials box shows the newly created liberty
credential. Click OK
6. Jenkins should then trigger a scan of the Gitlab repository to look for Jenkinsfiles. Given the repository is empty, it won’t find any, however, this is a test of connectivity to the repo that would fail if SSH was incorrectly configured. The screenshot below shows the connection being made using GIT_SSH and no errors being returned.
For illustration, I’ve included a screenshot of a failure below:
Conclusion
You’ve now installed GitLab in to ICP, updated the ICP Ingress Controller to route SSH traffic on port 2222 to the Gitlab shell service and tested SSH from command line Git and Jenkins. You are ready to starting putting source code in to GitLab and modernizing the build process for your applications.