Problem
Gitlab has by far established itself as the de-facto standard if you want to privately, in your own cloud/cluster, host a code repo and have the nice interface and other trimmings typically provided by a Github. However, unlike other services out there, there’s very few super clear and simple instructions out there for quickly plopping it into your kubernetes cluster. Especially if you don’t use helm. Also, what is up with that pesky omnibus configuration and why is it every time you search for how to quickly configure a standard vanilla kubernetes pod the search results introduces so much complexity! Well here is the quick ended to end solution!
Assumptions
- You’re running a services echo system in Kubernetes cluster
- You have external access to all services routed through an ingress controller
- You want Gitlabto live as another service alongside your other applications and services and accessible through some domain name / path via ingress
Solution
First let’s set up the basic deployment. Since we will use our ingress configuration to secure all external traffic into the kubernetes cluster with SSL (TLS/HTTPS), let’s keep the deployment for Gitlab simple.
Now, Gitlab utilizes both postgres database and redis so we have to have pods for those created for Gitlab.
Lets spool up a deployment for postgres with the following YAML. Note in this example I do not use a secret for the db password for brevity. Its super simple, follow this guide to make it more secure.
Let’s name the file gitlab-postgres.yaml
kind: Service apiVersion: v1 metadata: name: gitlab-db spec: selector: pod: gitlab-db ports: - protocol: TCP port: 5432 targetPort: 5432 --- kind: PersistentVolumeClaim apiVersion: v1 metadata: name: gitlab-db-pvc spec: accessModes: - ReadWriteOnce resources: requests: storage: 10Gi --- apiVersion: apps/v1 kind: Deployment metadata: name: gitlab-db spec: replicas: 1 selector: matchLabels: pod: gitlab-db template: metadata: labels: pod: gitlab-db spec: containers: - name: gitlab-db image: postgres:alpine imagePullPolicy: IfNotPresent env: - name: POSTGRES_USER value: gitlab - name: POSTGRES_DB value: gitlabhq_production - name: POSTGRES_PASSWORD value: gitlab ports: - containerPort: 5432 volumeMounts: - name: gitlab-db-volume mountPath: /var/lib/postgresql/data subPath: gitlab volumes: - name: gitlab-db-volume persistentVolumeClaim: claimName: gitlab-db-pvc
Ok, now lets spool up a redis pod with the following YAML
Lets name this file gitlab-redis.yaml
apiVersion: v1 kind: Service metadata: name: gitlab-memcache spec: selector: pod: gitlab-memcache ports: - protocol: TCP port: 6379 targetPort: 6379 --- apiVersion: apps/v1 kind: Deployment metadata: name: gitlab-memcache spec: replicas: 1 selector: matchLabels: pod: gitlab-memcache template: metadata: labels: pod: gitlab-memcache spec: containers: - name: gitlab-redis-master image: redis imagePullPolicy: IfNotPresent resources: limits: cpu: "0.2" ports: - containerPort: 6379
Don’t be confused by my usage of memcache as a naming convention in this YAML, it’s just a personal preference as it is more descriptive of the pod’s purpose. Postgres is a database and Redis is a memcache :-P. If it bugs you feel free to replace memcache with redis in this example.
OK, now that we’ve got our postgres db and redis up. Lets create and deploy our Gitlab pod!
Let’s create gitlab-pod.yaml
--- apiVersion: v1 kind: Service metadata: name: gitlab spec: selector: pod: gitlab ports: - protocol: TCP port: 80 targetPort: 80 --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: gitlab-pvc labels: pod: gitlab spec: accessModes: - ReadWriteOnce resources: requests: storage: 10Gi --- apiVersion: apps/v1 kind: Deployment metadata: name: gitlab spec: replicas: 1 selector: matchLabels: pod: gitlab template: metadata: labels: pod: gitlab spec: containers: - name: gitlab image: gitlab/gitlab-ce imagePullPolicy: IfNotPresent env: - name: GITLAB_OMNIBUS_CONFIG value: | postgresql['enable'] = false prometheus['monitor_kubernetes'] = false gitlab_rails['db_username'] = "gitlab" gitlab_rails['db_password'] = "gitlab" gitlab_rails['db_host'] = "gitlab-db" gitlab_rails['db_port'] = "5432" gitlab_rails['db_database'] = "gitlabhq_production" gitlab_rails['db_adapter'] = 'postgresql' gitlab_rails['db_encoding'] = 'utf8' redis['enable'] = false gitlab_rails['redis_host'] = 'gitlab-memcache' gitlab_rails['redis_port'] = '6379' gitlab_rails['gitlab_shell_ssh_port'] = 22 external_url 'http://gitlab.example.com' ports: - containerPort: 80 volumeMounts: - name: gitlab mountPath: /var/opt/gitlab subPath: gitlab_data - name: gitlab mountPath: /etc/gitlab subPath: gitlab_configuration volumes: - name: gitlab persistentVolumeClaim: claimName: gitlab-pvc
The key part of this configuration is the omnibus section that tells Gitlab where our database and redis is. Do note that for this deployment you need to have prometheus['monitor_kubernetes'] = false
configured or things break.
Now lets apply these manifests.
kubectl apply -f gitlab-postgres.yaml kubectl apply -f gitlab-redis.yaml kubectl apply -f gitlab-pod.yaml
Note: Gitlab takes a while to launch so you might want to use kubectl logs -l pod=gitlab -- follow
to watch it come up.
Win
Simply create your password for the root account and you’re good to go!! (note: the name of the account you create as password is ‘root’, you can subsequently create your main user with the permissions you’d like).
Leave a Reply
Your email is safe with us.