#
GitLab in Kubernetes
Difficulty: Hard / Advanced
#
Introduction
In this article, I will describe all the steps required to setup GitLab CI/CD in Kubernetes using Kustomize.
We will go through how to run GitLab on Kubernetes when you already have related resources Postgres
, Redis
, MinIO
, TLS Certificates
, etc...already available in your setup.
This is a very common scenario in companies and also for self-hosting that you are already using these services in your environment and prefer to use the same for gitlab.
The all in one production installation may be easily performed with Helm. You can refer to the official documentation from GitLab if that is your requirement.
#
Requirements
You will need the following in order to run GitLab.
- Database: Postgres
- Cache: Redis
- Storage: MinIO is used as object storage for the container registry, GitLab backups, the Terraform storage backend, GitLab artifacts and more
- Ingress Controller: Nginx ingress
- Persistent Volume: Gitaly will store repository data data on disk. Your Kubernetes cluster must have a way of provisioning storage. You can install the local path provisioner in your cluster for dynamically provisioning volumes.
#
Necessary Repositories
You can swap MinIO with any other object storage i.e S3 by changing the connection info secret.
#
Lets Get Started!
When installing GitLab with Helm it generates the ConfigMaps after rendering the templates with parameters. We can manually change these values in ConfigMaps but its a hassle and not convenient. To make this process easy we will use a tool called subvars which will let us render these values from the command line. Install it by following the instructions on the GitHub page, we will use it later.
Download the release with manifests from GitHub. Alternatively you can clone the repo. If you are cloning the repo remove the
.git
folder afterwards as it creates issues some times when rendering multiple version of the same file withsubvars
.export RELEASE_VER=1.0 wget -q https://github.com/kha7iq/gitlab-k8s/archive/refs/tags/v${RELEASE_VER}.tar.gz tar -xf v${RELEASE_VER}.tar.gz cd gitlab-k8s-${RELEASE_VER}
Next set the URL for our GitLab instance in our Kustomization file. This is located within the
ingress-nginx
folder. You will find two blocks, one forweb-ui
and the second for theregistry
along with atls-secret-name
for HTTPS.patch: |- - op: replace path: /spec/rules/0/host value: your-gitlab-url.example.com - op: replace path: /spec/tls/0/hosts/0 value: your-gitlab-url.example.com - op: replace path: /spec/tls/0/secretName value: example-com-wildcard-secret
Next create
minio-conn-secret
containing the configuration for MinIO. It will be used for all of the enabled S3 buckets except for the GitLab backup, we will create that separately. Create a Kubernetes secret to store this information. The following is an exampleminio.configcat << EOF > minio.config provider: AWS region: us-east-1 aws_access_key_id: 4wsd6c468c0974006d aws_secret_access_key: 5d5e6c468c0974006cdb41bc4ac2ba0d aws_signature_version: 4 host: minio.example.com endpoint: "https://minio.example.com" path_style: true EOF
kubectl create secret generic minio-conn-secret \ --from-file=connection=minio.config --dry-run=client -o yaml >minio-connection-secret.yml
Now create a secret with the MinIO configuration which will be used for the GitLab backup storage. Replace the MinIO endpoint, bucket name, access key & secret key.
cat << EOF > storage.config [default] access_key = be59435b326e8b0eaa secret_key = 6e0a10bd2253910e1657a21fd1690088 bucket_location = us-east-1 host_base = https://minio.example.com host_bucket = https://minio.example.com/gitlab-backups use_https = True default_mime_type = binary/octet-stream enable_multipart = True multipart_max_chunks = 10000 multipart_chunk_size_mb = 128 recursive = True recv_chunk = 65536 send_chunk = 65536 server_side_encryption = False signature_v2 = True socket_timeout = 300 use_mime_magic = False verbosity = WARNING website_endpoint = https://minio.example.com EOF
kubectl create secret generic storage-config --from-file=config=storage.config \ --dry-run=client -o yaml > secrets/storage-config.yml
All other secrets can be used as is from the repository or you can change all of them. You may read more about this here
One of the most important secrets is the
gitlab-rails-secret
secret. In case of a disaster where you have to restore GitLab from a backup you must apply the same secret to your cluster as these keys will be used to decrypt the database from backup. Make sure you keep this consistent after first install and do not change it.It's alot of work to change database details and other parameters one by one in ConfigMaps. I have implemented some templating for this which can provide all the values of environment variables and render the manifests with
subvars
. It will output these to a destination folder and replace all the parameters defined as Go templates. The values should be self explanatory, for example, theGITLAB_GITALY_STORAGE_SIZE
variable is used to specify how much storage is needed for Gitaly andGITLAB_STORAGE_CLASS
is the name of storage class in your Kubernetes cluster. The following command is an example of how to use this:GITLAB_URL=gitlab.example.com \ GITLAB_REGISTRY_URL=registry.example.com \ GITLAB_PAGES_URL=pages.example.com \ GITLAB_POSTGRES_HOST=192.168.1.90 \ GITLAB_POSTGRES_PORT=5432 \ GITLAB_POSTGRES_USER=gitlab \ GITLAB_POSTGRES_DB_NAME=gitlabhq_production \ GITLAB_REDIS_HOST=192.168.1.91:6379 \ GITLAB_GITALY_STORAGE_SIZE=15Gi \ GITLAB_STORAGE_CLASS=local-path \ subvars dir --input gitlab-k8s-1.0 --out dirName
Change into
dirName/gitlab-k8s-1.0
so you may review things to confirm everything is in order before applying the changes to the cluster.The final step is to create the namespace
gitlab
and build with Kustomize orkubectl
. I prefer Kustomize but you can also usekubectl
with-k
flag.Create the Namespacekubectl create namespace gitlab
Apply the Final Manifestkustomize build gitlab-k8s-1.0/ | kubectl apply -f - # or following if you have already changed into directory kustomize build . | kubectl apply -f - # With kubectl kubectl apply -k gitlab-k8s-1.0/ # or following if you have already changed into directory kubectl apply -k .
Head over to the endpoint you have configured for your GitLab instance,
https://gitlab.example.com
for example, and login.
#
Notes
- Default passwords
GitLab 'root' user password configured as secretPostgres password configured as secretLAwGTzCebner4Kvd23UMGEOFoGAgEHYDszrsSPfAp6lCW15S4fbvrVrubWsua9PI
ZDVhZDgxNWY2NmMzODAwMTliYjdkYjQxNWEwY2UwZGMK