Gitlab CI/CD and Kubernetes

Nguyễn Đào Anh Khoa
4 min readDec 19, 2020

--

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:

Gitlab CI/CD pipeline

Pipelines for every merge requests:

Gitlab CI/CD pipeline

And the environments list:

Environment management

--

--

No responses yet