---
title: "How to Build and Deploy Application on Kubernetes with CI/CD Pipeline Using Jenkins, Docker, Harbor Private Repository, and ArgoCD"
description: "meta description"
date: 2024-06-18T05:00:00Z
image: "/images/posts/01.jpg"
categories: ["Tech"]
authors: ["admin"]
tags: ["Astro", "ArgoCD"]
draft: false
---

CI/CD pipelines are necessary to effectively produce high-quality software in today’s software development environment. This article explains how to set up a continuous integration/delivery pipeline (CI/CD) using Jenkins, Docker images, the Harbour private repository, Git, and ArgoCD. This will generate images seamlessly, push them to the harbor, and then have them automatically deploy to the Kubernetes pods.

Getting Started
This is the general workflow

1. Docker File Creation: Intially, a Docker file needs to be created. In this file, a DevOps engineer specifies the environment and dependencies needed for the application.

2. Commit Code to the Repository: A repository, like Git, stores the source code and the Docker file. I’m going to store the repository on GitHub.

3. Jenkins Pulls the Code: We can launch the Jenkins job to pull the most recent code from the source code repository in order to begin the build process.

4. Building and Pushing the Docker Image: Jenkins uses the Docker file to build a Docker image. Jenkins pushes the completed image to the Harbour private repository. You can look at here to learn how to build the Harbour private repository.

5. Updating the Deployment Repository: Jenkins makes changes to the deployment file repository, which contains the Kubernetes deployment configurations needed for the application.

6. Syncing with ArgoCD: To ensure everything is current, ArgoCD, a Kubernetes continuous delivery tool, retrieves the most recent updates from the deployment source.

7. Deploying to Kubernetes: Lastly, ArgoCD ensures everything functions configured by syncing these modifications with the Kubernetes cluster and deploying the application into the designated pods.

The Workflow

CI/CD Pipeline Using GitHub, Jenkins, Harbor, Argo CD, and Kubernetes
Implementation
Tools needed
Kubernetes Cluster
Docker
Jenkins
Harbor
ArgoCD
GitHub
1. Create the Docker File
We will be using the DockerFile mentioned below


It is using the below index.html file.


You can find all the files in the GitHub repository below: https://github.com/tanmaybhandge/Harbor_CICD_Pipeline.git

2. Trigger Jenkins Jobs
We have two jobs configured on Jenkins.

The first job (Upsteam job) involves cloning a GitHub repository to obtain the latest source code. From this code, a Docker image will be created. Then it will build the image, logs into a Harbor private registry, pushes the image, and tags it with the build number of the upstream job.

After the image is successfully pushed, a downstream job will be start by the upstream job. The downstream job will receive the build number as a parameter, which will have the build number. Then downstream job will modify the image version same as build number and will push the changes on the Kubernetes deployment file.

What is the Upstram and Downstream job means ?

When you have one Jenkins job that starts another, the job that initiates the process is called the upstream job, while the job that gets started as a result is known as the downstream job. In the below example Build_Docker_Image_Push_Harbor is the upstream job and push_image_tag_git is the downstream job.

Job: Build_Docker_Image_Push_Harbor
Create the Pipeline job Build_Docker_Image_Push_Harborand paste the following script.

This Jenkins pipeline script automates the process of building a Docker image from a GitHub repository, pushing the image to a Harbor repository, and triggering another Jenkins job push_image_tag_git to modify the deployment file on GitHub and commit the changes.

pipeline {
    agent any

    stages {
        stage('Build') {
            steps {
                // Get some code from a GitHub repository
                git branch: 'main', url: 'https://github.com/tanmaybhandge/Harbor_CICD_Pipeline.git'
                sh 'docker build -t library/harbor_cicd_v2 .'

            }

        }
        stage('Push to Harbor') {
            environment {
                DOCKER_CREDENTIALS = credentials('Harbor')
            }
            steps {
                script {
                    // Login to Harbor using credentials
                    sh "docker login -u ${DOCKER_CREDENTIALS_USR} -p ${DOCKER_CREDENTIALS_PSW} 10.1.1.1"

                    // Tag the image
                    sh 'docker tag library/harbor_cicd_v2 10.1.1.1/library/harbor_cicd:v${BUILD_NUMBER}'
                    
                    // Push the image to Harbor
                    sh 'docker push 10.1.1.1/library/harbor_cicd:v${BUILD_NUMBER}'
                }
            }
        }
        stage('Trigger GitHub Push') {
            steps {
                build job: 'push_image_tag_git', wait: true, parameters: [string(name: 'Build_Number_Image', value: "${BUILD_NUMBER}")]
            }
        }

    }
}
There is no checkbox selected on the job Build_Docker_Image_Push_Harbor you just need to paste the above script into the Pipeline script.


Pipeline script
Stages
Here is the explanation of each stage

Build

Git Checkout: Clones the repository from the specified URL and checks out the ‘main’ branch.
Docker Build: Builds a Docker image from the Dockerfile in the repository, tagging it as library/harbor_cicd_v2.
Push to Harbor

Environment Variables: Fetches Docker credentials stored in Jenkins using the ID ‘Harbor’. I have already created the Harbor credentials in Jenkins (default credentials of Harbor: Username admin, Password Harbor12345)
Docker Login: Logs into the Harbor registry using the retrieved credentials.
Docker Tag: Tags the built Docker image with a new tag that includes the Jenkins build number. We will use the build number as the tag of the current pipeline.
Docker Push: Pushes the tagged Docker image to the specified Harbor repository.
Trigger GitHub Push

Trigger Another Job: Initiates the push_image_tag_git job.
Pass Parameters: Sends the current build number to the triggered job.
Job: Push_Image_Tag_Git
This job will modify the Kubernetes deployment YAML file hosted on GitHub to include the new image tag pushed by the upstream job. To achieve this, you’ll need the following:

Parameterized Trigger Plugin
GitHub Plugin
GitHub credentials with push access permission
Here is the configuration of the job

Create the Freestryle Project with the name push_image_tag_git

A. Ensure the option This project is parameterisedis selected, and then proceed to configure the string parameter accordingly.


B. In the Source Code Managmentsection, select Git, paste the repository URL, and choose the appropriate credentials which has the permission/access to your GitHub. For the Branches to Build section, specify your branch. I’m using the default main branch.


C. Add Execute Shell on the Build Steps and paste the following.


Build Steps
sed -i "s#image: 10.1.1.1/library/harbor_cicd:v.*#image: 10.1.1.1/library/harbor_cicd:v${Build_Number_Image}#" Deployment/deployment.yaml
cat Deployment/deployment.yaml
git config --global user.email "tanmay8928@gmail.com"
git config --global user.name "Tanmay"
git add .
git commit -m "Deployment file modified by Jenkins job with the image Harbor image 10.1.1.1/library/harbor_cicd:v${Build_Number_Image}"
This script locates the image tag in the Deployment.yaml file, replaces it with the specified version from the Jenkins build (${Build_Number_Image}), configures the email and name for Git commits, adds all modified files to the Git staging area, and commits the changes with a descriptive message.

D. In the Post-Build Actionssection, select ‘Push Only If Build Succeeds’ Then, specify the branch name and the target remote name under the ‘Branches’ field. I am specifying branch name asmain and the target remote name asorigin


3. Trigger the Build Docker job.
Manually trigger the Build_Docker_Image_Push_Harbor it will perform the below actions and it will trigger the Push_image_Tag_Git job. Both of the jobs will perform the below

Build_Docker_Image_Push_Harbor

Build Stage: Clones a GitHub repository and builds a Docker image.
Push to Harbor Stage: Logs into a Harbor registry, tags the image with the build number, and pushes it.
Trigger GitHub Push Stage: Triggers downstream job Push_image_Tag_Gitand passes the build number as a parameter.
Push_image_Tag_Git

Execute Shell: It will locate the image tag in the Deployment.yaml file, replace it with the specified version from the previous Jenkins build, configures the email and name for Git commits, adds all modified files to the Git staging area, and commits the changes with a descriptive message.