Building the Ultimate CI/CD Pipeline using Jenkins along with Maven, SonarQube, Nexus, and Docker And Deploying in Kubernetes using ArgoCd.

Introduction

Here in this Project, we will deploy the simple JAVA application on Kubernetes following the CI/CD practices. We will use Jenkins as our Continuous Integration tool and we use ArgoCd as a CD part and deploy our app in Kubernetes using it. We use tools like Maven for building the app, for UNIT and Integrated testing and then we will send the artifacts in Nexus, sonarqube for the static code analysis, use Docker to build the images and push them to the docker hub.

Objective

To Deploy the simple JAVA application on k8s using the CI/CD pipeline.

Continuous integration(CI)

The Steps followed in this part of the project are as follows:

AWS

We first Create two(2) AWS EC2 Instances ( t2.medium) where we will install all Jenkins and sonarQube in one EC2 instance whereas in another EC2 we will install Nexus in another.

Now after creating the AWS EC2 instance the next work is to connect this instance from our terminal through SSH.

ssh -i <path_to_private_key_file> @<public_dns_name_or_ip_address>

Installing Jenkins

Now we will install Java as a prerequisite for Installing Jenkins in 1st EC2 instances

sudo apt update

sudo apt install openjdk-11-jre

Check if Java is installed

java -version

Now we can install the Jenkins

curl -fsSL https://pkg.jenkins.io/debian/jenkins.io-2023.key | sudo tee \ /usr/share/keyrings/jenkins-keyring.asc > /dev/null

echo deb [signed-by=/usr/share/keyrings/jenkins-keyring.asc] \ https://pkg.jenkins.io/debian binary/ | sudo tee \ /etc/apt/sources.list.d/jenkins.list > /dev/null

sudo apt-get update

sudo apt-get install jenkins

Jenkins Is Installed in the EC2 instance.

Jenkins can be accessed in default port 8080. But for accessing Jenkins we first add the Inbound rule giving access to the port 8080.

We can check the Jenkins using this command in the terminal

ps -ef | grep jenkins

We create the pipeline project in Jenkins.

We provide the Jenkinsfile to the Jenkins through SCM i.e. Git Hub.

The Link to the source code is Here.

We use Maven for building the Java application and doing UNIT testing as well as Integrated Testing.

We use Sonarqube for the static code Analysis as well as Docker to build the images of the application and push them on the docker hub.

Setting Up SonarQube

We create the new user named sonarqube in our EC2 instances from the root user.

adduser sonarqube

Switching to the sonarqube user we can now install the sonarqube following the following steps:

wget https://binaries.sonarsource.com/Distribution/sonarqube/sonarqube-9.4.0.54424.zip

unzip *

chmod -R 755 /home/sonarqube/sonarqube-9.4.0.54424

chown -R sonarqube:sonarqube /home/sonarqube/sonarqube-9.4.0.54424 cd sonarqube-9.4.0.54424/bin/linux-x86-64/

./sonar.sh start

Now we can access the sonar Qube in port 9000.

Installing Docker

Now we install the docker in our root user following the command:

sudo apt update

sudo apt install docker.io

Grant Jenkins user and Ubuntu user permission to docker daemon.

sudo su -

usermod -aG docker jenkins

usermod -aG docker ubuntu

systemctl restart docker

We restart our Jenkins as Restarting Jenkins after downloading and installing plugins is necessary to ensure that the new plugins are fully loaded and integrated into the Jenkins environment.

Pipeline

The Jenkinsfile we provide to Jenkins is used for automating our tasks. The Maven used for build and test of our application looks out for pom.xml file for installing the required dependencies for building the app.

We configure the required credential of Sonarqube, Docker, and GitHub.

After configuring we again restarted the Jenkins server.

As per the Jenkinsfile ( mentioned above), docker is used as an agent to build the container required to run the steps.

Stage 1st

The first stage is for checking if Jenkins is able to clone the GitHub file or not.

Stage 2nd

In the second stage, we had done testing. Both the Unit testing and integrated testing. We perform these testing with the help of Maven.

Stage 3rd

In The Third stage, we use Maven to build our app and get the jar/war file which we send the jar file to Nexus.

Stage 4th

In The Fourth stage sonarqube is used for the static code Analysis and Jenkins sends the response back to the sonarqube server.

When the Static Code Analysis passed we can look into our SonarQube server for the analysis of our Code.

Stage 5th

For stage 5th we need to first download Nexus in our other EC2 instances.

We download the Nexus in our EC2 instances using the following command.

Before starting, we will need to update our system packages to the latest version. We can update them using the following command:

apt-get update -y

Once Our server is updated, We can proceed to the next step.

Nexus is based on Java so we will need to install Java version 8 on our system.

apt-get install openjdk-8-jdk -y

Before starting, we will need to create a separate user to run Nexus. We can create it by running the following command:

useradd -M -d /opt/nexus -s /bin/bash -r nexus

Next, allows Nexus users to run all users with sudo without any password. You can do it by running the following command:

echo "nexus ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/nexus

Next, create a directory for Nexus and download the latest version of Nexus with the following command:

mkdir /opt/nexus wget https://sonatype-download.global.ssl.fastly.net/repository/downloads-prod-group/3/nexus-3.29.2-02-unix.tar.gz

Once the download is completed, extract the downloaded file to the /opt/nexus directory by running the following command:

tar xzf nexus-3.29.2-02-unix.tar.gz -C /opt/nexus --strip-components=1

Next, set proper ownership to the nexus directory by running the following command:

chown -R nexus:nexus /opt/nexus

Next, edit the nexus.vmoptions configuration file and define max memory size:

nano /opt/nexus/bin/nexus.vmoptions

Set Java max memory size and replaced "../sonatype-work" with "./sonatype-work":

save and close the file then edit the nexus.rc file and define the run as user:

nano /opt/nexus/bin/nexus.rc

Uncomment and change the following line with Nexus user:

run_as_user="nexus"

Save and close the file then start the Nexxus service with the following command:

sudo -u nexus /opt/nexus/bin/nexus start

By following these command steps we will install the Nexus Successfully in the EC2 instance.

We will create a new repository named demoapp-release in the Nexus Server creating a custom repository as maven ( hosted ).

We will install the Nexus plugin in Jenkins and configure it . And we build our pipeline in which this stage is to push our artifacts to the Nexus server.

We can get our release as well as a snapshot in the Nexus server. At first, we tested the hard-coded release and send it to the Nexus server.

We then automate our release version by writing some functions:

def readPomVersion = readMavenPom file: 'pom.xml'

We again send our artifacts to the Nexus server but this time we use the function to add our release.

Our next steps will be to build the docker image and push it to the docker hub.

Stage 6th

In this stage, we will build the multi-stage Docker images and push it to the Docker hub. We create 2 images one with the block number tag and one with the latest tag.

We then can check the docker hub for the image.

In This way, we automate the building, testing, and building of the images, and push them to the docker hub with the help of Jenkins.

Continuous Deployment(CD)

As the next part, we should implement the CD part where we use ArgoCd to deploy our app images in Kubernetes.

We can use our local terminal and with the help of Minikube, we can achieve the required process.

kubectl create namespace argocd 
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml

We follow the command to install ArgoCd.

We can list out the services using the command:

kubectl get svc -n argocd

We edit the argocd-server type as Nodeport from ClusterIP

Minikube provides us with a special command which it will generate the URL using which we can access in our browser.

minikube service argocd-server is the name of the svc.

It will provide us with the URL through which we can access the ArgoCd.

The username is admin and the password is stored in the secret.

After logging in to ArgoCD We create the new app and enter the required field as necessary. And it will take the deployment file and deploy the images in Kubernetes.

We can also use argocd using the CLI command also.

In This way, we deploy our App in Kubernetes following the CI/CD practices.

Conclusion

In conclusion, implementing a CI/CD pipeline using SonarQube, Maven, Nexus, and Docker helps us to achieve reliable software development. Jenkins is used to implement the CI part and Argocd is used for the CD part.