Gitlab CI/CD and Kubernetes
Prerequisite
This isn’t a Kubernetes or DevOps introduction, so it’s required to have the following prerequisites:
- Basic knowledge of Docker and container
- Basic knowledge of Kubernetes
- Bash scripting
- Familiar with YAML syntax
Disclaimer
The code used in this article is for demonstration only, to provide you an abstract view of the Gitlab - Kubernetes CI/CD pipeline. I recommend that you go through the Gitlab CI/CD documentation after reading this article, and make sure you understand all the concepts there before applying this to your project.
CI/CD
The term CI/CD is used for a long time in software development. It generally stands for Continuous Integration (CI) and Continuous Delivery (CD). CI/CD bridges the gap between development team and operation team, helps the application deployment more rapidly and reliable. Nowadays, with the widespread of agile and microservices, CI/CD becomes inevitable in software development.
In this article, I’ll show you how to set up a CI/CD pipeline to test, build, deploy a Rails application using Gitlab CI/CD and Kubernetes. However, you can apply the same technique to other kinds of applications and frameworks as well.
Gitlab CI/CD
GitLab CI/CD is a tool built into GitLab. It provides an awesome set of features to build a complete CI/CD pipeline even with a community edition - at least in our use case.
The Gitlab CI/CD pipeline is split into 2 parts: Gitlab and Gitlab runner.
- Gitlab creates jobs on Git/Gitlab operations such as git push, branch creation, tag creation, MR creation, …
- Gitlab runner automatically picks jobs from Gitlab and executes them.
In this article, I use Gitlab v13.5.4-ce and Gitlab runner 13.4.1 with Kubernetes executor. For more information about Gitlab runner and Kubernetes executor, please refer to the official documentation.
Setup Gitlab and Kubernetes cluster
Prepare a Kubernetes cluster.
I use an EKS cluster, but you can use other Kubernetes services of your choice.
Create namespace and a service account with an appropriate role:
kubectl apply -f k8s/gitlab-cd-role.yaml -n app-prodkubectl create sa gitlab-cd -n app-userkubectl create rolebinding gitlab-cd-role-binding —-role=gitlab-cd ---serviceaccount=app-user:gitlab-cd -n app-prod
An then get the secret and cluster CA using:
SECRET_NAME=$(kubectl get sa gitlab-cd -o jsonpath={.secrets[0].name} -n app-user)kubectl get secret $SECRET_NAME -o jsonpath={.data.token} -n app-user | base64 -dkubectl get secret $SECRET_NAME -o "jsonpath={.data['ca\.crt']}" -n app-user | base64 -d
Set Gitlab CI/CD variables:
Follow: https://docs.gitlab.com/ee/ci/variables/README.html#create-a-custom-variable-in-the-ui
Below is the list of variables that I used:
Project folder structure
The project folder should look like this:
.├───k8s
│ ├───production
│ ├───├───deployment.yaml
│ ├───├───ingress.yaml
│ ├───├───migration-job.yaml
│ ├───├───service.yaml
│ ├───staging
├───├───├───...├───rails
│ ├───app
│ ├───Gemfile
│ ├───...├───Dockerfile
├───.gitlab-ci.yml
├───.gitlab-ci-test.yml
├───.gitlab-ci-build.yml
├───.gitlab-ci-staging.yml
├───.gitlab-ci-production.yml
Gitlab CI/CD pipeline
GitLab CI/CD is configured by a file called .gitlab-ci.yml
placed at the repository’s root.
This file creates a pipeline, which consists of many stages such as test, build, staging … Each stage is defined under a child yml file. Each stage has one or many jobs. Each job is defined under a YAML block.
First, test the application using the ci job. This will create a pod inside the Gitlab runner cluster. Pull the project source code and run the scripts described under the script block.
Then build a base image using rebuild_base_image job. The project’s CI/CD variables can be defined in CI/CD variables setting. Here I use 2 project’s CI/CD variables which are ECR_URL and ECR_REPO.
And finally, deploy the application to either review/staging/production environment.
Result:
Depends on the configuration in your .gitlab-ci.yml file, you should get the pipelines that look like this:
Pipelines for every merge requests:
And the environments list: