GitLab CI/CD pipeline project
In the initial phase of the project, three EC2 instances have been provisioned with the following configurations: instance type t2.medium, 4 GiB of memory, and 2 vCPUs. The instances created are:
Master-K8: Acts as the master node for the Kubernetes cluster.
Slave-K8: Functions as the slave node in the Kubernetes cluster.
SonarQube: Hosts the SonarQube server for continuous inspection of code quality.
EC2 Instance Setup for Master and Worker Nodes:
Always run this command first on your virtual machine.
Sudo apt update
#!/bin/bash
# Update the package index
sudo apt-get update
# Install Docker
sudo apt-get install -y docker.io
# Adjust permissions for Docker
sudo chmod 666 /var/run/docker.sock
# Install required packages for Kubernetes
sudo apt-get install -y apt-transport-https ca-certificates curl gpg
# Create the directory for the Kubernetes keyring
sudo mkdir -p -m 755 /etc/apt/keyrings
# Add the Kubernetes apt repository GPG key
sudo curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.30/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
# Add the Kubernetes apt repository
echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.30/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list
# Update the package index again to include the Kubernetes repository
sudo apt-get update
# Install specific versions of Kubernetes components
sudo apt-get install -y kubelet=1.30.0-1.1 kubeadm=1.30.0-1.1 kubectl=1.30.0-1.1
# Prevent Kubernetes components from being updated automatically
sudo apt-mark hold kubelet kubeadm kubectl
Make a script of the above commands and then make it executable(Master & workernode)
vi 1.sh
sudo chmod +x 1.sh
./1.sh
Kubernetes Master Node only:
This command initialize the Kubernetes master node.
sudo kubeadm init --pod-network-cidr=10.244.0.0/16
Joining Worker Node(s)
Once you receive the output of sudo kubeadm init --pod-network-cidr=10.244.0.0/16
on the master node, copy the kubeadm join
command and run it on each worker node.
eg; kubeadm join 172.31.35.0:6443 --token x4c4jj.335cm3o787lgn1fo \
--discovery-token-ca-cert-hash sha256:79f7c7f3b19fa6aa827c692c46eacb815db68b77
b2bb56404d6efabc1ea4482b
Now apply these following commands:
# Create the .kube directory in the user's home directory
mkdir -p $HOME/.kube
# Copy the Kubernetes admin configuration file to the .kube directory
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
# Change ownership of the Kubernetes admin configuration file
sudo chown $(id -u):$(id -g) $HOME/.kube/config
Network plugin command & Ingress controller:
kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v0.49.0/deploy/static/provider/baremetal/deploy.yaml
Now Configure SonarQube:
Always run this command first on your virtual machine.
# Update package index
sudo apt-get update
# Install Docker
sudo apt install docker.io -y
# Adjust permissions for Docker socket
sudo chmod 666 /var/run/docker.sock
# Run SonarQube container
docker run -d --name sonar -p 9000:9000 sonarqube:lts-community
login in SonarQube and the default username & password is admin. then later you setup new password.
Second Phase of the Project:
Create an account on GitLab. then imported project (source code ) from Github. Runner is a agent used to run CI/CD jobs defined in GitLab CI/CD pipelines. It is responsible for executing the scripts specified in .gitlab-ci.yml
files. For setting up a GitLab Runner on an EC2 instance by launching a new EC2 instance type t2.large
, 8 GiB memory, and 2 vCPUs.
Install GitLab Runner:
GitLab — settings — ci/cd — Project runner — Tags(self-hosted) — register runner.
Runner tools to install: java17, Maven, Docker, Trivy
sudo apt install openjdk-17-jre-headless -y
sudo apt install maven -y
sudo apt install docker.io -y
sudo chmod 666 /var/run/docker.sock
Install trivy:
sudo apt-get install wget apt-transport-https gnupg lsb-release
wget -qO — https://aquasecurity.github.io/trivy-repo/deb/public.key | sudo apt-key add -
echo deb https://aquasecurity.github.io/trivy-repo/deb $(lsb_release -sc) main | sudo tee -a /etc/apt/sources.list.d/trivy.list
sudo apt-get update
sudo apt-get install trivy
SonarQube Server page— create configuration name, URL, personal access token(go to GitLab-setting-Access Token). Set up your project Key and generate project token on SonarQube.Configure variables on GitLab — Setting — CI/CD — Variables (SONAR_TOKEN, SONAR_HOST_URL).
we need to add other variables for building(DOCKER_PASSWORD,DOCKER_USERNAME) and deploying (KUBECONFIG_CONTENT, KUBECONFIG_PATH)
— — — — GitLab boardgame pipeline — — — — — — -
stages:
— prepare
— compile_test
— security
— build
— docker_build_push
— deploy
prepare-tool:
stage: prepare
script:
— mvn — version
— java — version
tags:
— self-hosted
compile:
stage: compile_test
script:
— mvn compile
tags:
— self-hosted
test:
stage: compile_test
script:
— mvn test
tags:
— self-hosted
trivy_fs_scan:
stage: security
script:
— trivy fs — format table -o trivy-fs-report.html .
tags:
— self-hosted
sonarqube-check:
stage: security
image: adijaiswal/sonar-maven:latest
variables:
SONAR_USER_HOME: “${CI_PROJECT_DIR}/.sonar”
GIT_DEPTH: “0”
cache:
key: ${CI_JOB_NAME}
paths:
— .sonar/cache
script:
— sonar-scanner
-Dsonar.projectKey=batch-4840424_game_AZBIztabnxHIeySEwl_E
-Dsonar.java.binaries=.
allow_failure: true
only:
— main
build_application:
stage: build
script:
— mvn package
tags:
— self-hosted
build_docker_image:
stage: docker_build_push
script:
— docker login -u $DOCKER_USERNAME -p $DOCKER_PASSWORD
— mvn package
— docker build -t adijaiswal/bgame:latest .
tags:
— self-hosted
push_docker_image:
stage: docker_build_push
script:
— docker login -u $DOCKER_USERNAME -p $DOCKER_PASSWORD
— docker push adijaiswal/bgame:latest
tags:
— self-hosted
k8s-deploy:
stage: deploy
image: lachlanevenson/k8s-kubectl:1.18.0
variables:
KUBECONFIG_PATH: /home/ubuntu/config
before_script:
— mkdir -p $(dirname “$KUBECONFIG_PATH”)
— echo “$KUBECONFIG_CONTENT” | base64 -d > “$KUBECONFIG_PATH”
— export KUBECONFIG=”$KUBECONFIG_PATH”
script:
— kubectl apply -f deployment-service.yaml
only:
— main
tags:
— self-hosted
The CI/CD pipeline for the project is structured into several stages, ensuring a robust and secure deployment process. The stages include: prepare, compile_test, security, build, docker_build_push, and deploy.
In the prepare stage, the necessary tools and their versions are checked. The compile_test stage compiles the code and runs tests using Maven. The security stage includes two critical checks: a file system scan with Trivy for vulnerabilities and a SonarQube analysis for code quality, using a custom Sonar-Maven Docker image. The build stage packages the application with Maven.
Next, the docker_build_push stage involves building and pushing the Docker image. The Docker image is built and tagged, then pushed to Docker Hub. Finally, the deploy stage uses a Kubernetes deployment where the Kubernetes configuration file is applied to the cluster using kubectl. This stage includes setting up the KUBECONFIG file for secure access to the Kubernetes cluster.
Each stage is tagged with self-hosted to specify the runner type, ensuring the tasks run on a self-hosted GitLab Runner. This comprehensive pipeline ensures that the code is compiled, tested, scanned for vulnerabilities, packaged, containerized, and deployed efficiently and securely.
I trust that this GitLab CI/CD project has offered you a thorough and detailed understanding of the continuous integration and continuous deployment processes
Subscribe to my newsletter
Read articles from Shazia Massey directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by