Prerequisites
- Kubernetes cluster
- Helm installed
- Docker installed
- Jenkins installed with necessary plugins (Helm, Kubernetes, Docker,
- Slack)
- DockerHub account
- Slack workspace and webhook URL
To deploy both Java and Python applications using Kubernetes and Helm with
Slack alerts, we can create a Jenkins pipeline that handles the following:
- Checkout the code for both applications.
- Build Docker images for both applications.
- Push the Docker images to a Docker registry.
- Deploy the applications to a Kubernetes cluster using Helm.
- Send Slack notifications for build and deployment status.
Firstly deployment of java application using helm:
Step 1: Setting Up the Spring Boot Application
- Create a simple Spring Boot application.
- Add a simple REST controller that returns a “Hello World!” message.
- Test the application locally to ensure it’s working.
mvn compile
mvn package
Step 2: Dockerizing the Spring Boot Application
- Create a Dockerfile for the Spring Boot application.
- Build the Docker image locally.
- Push the Docker image to DockerHub (or any container registry).
- Example Dockerfile
docker build -t testhello .
docker run -p 8040:8081 testhello
Step 3: Setting Up Kubernetes Cluster
- Set up a local Kubernetes cluster using Minikube or use a cloud
- provider (e.g., GKE, EKS, AKS).•
- Ensure kubectl is configured to interact with the cluster.
minikube start
minikube status
Step 4: Creating Helm Charts
- Introduction to Helm and its components (Chart.yaml, values.yaml,
templates, etc.). - Create a Helm chart for the Spring Boot application.
helm create myspringbootchart
- Define the deployment and service templates.
- Customize values.yaml for different environments (e.g.,
development, production).
Edit this part:
image:
repository: pramila188/testhello
tag: latest
pullPolicy: IfNotPresent
service:
type: NodePort
port: 8081
Example Helm chart structure:
my-springboot-chart/
├── Chart.yaml
├── values.yaml
└── templates/
├── deployment.yaml
├── service.yaml
eval $(minikube docker -env)
again run docker build and run command
Step 5: Deploying the Application Using Helm
- Package the Helm chart.
- Install the Helm chart on the Kubernetes cluster.
- Verify the deployment and ensure the application is running
helm install hellochart myspringbootchart
kubectl get pod
kubectl get svc
kubectl get deployment
..
minikube dashboard
minikube service hellochart myspringbootchart –url
Final output:
Same This type deploy python application on kubernetes cluster
This two applications maintain in two seperate git repo:
java application repo: Click here
python application repo: Click here
This 2 application deploy on kubernetes cluster using helm we can create Build
and Deploy Java and Python Applications file in application side is as
follows:
name: Build and Deploy Java and Python Applications
on:
push:
branches:
- main
jobs:
build_and_deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
- name: Log in to DockerHub
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build and push Java Docker image
run: |
docker build -t ${{ secrets.DOCKER_USERNAME }}/java-app:latest -f java-app/Dockerfile java-app
docker push ${{ secrets.DOCKER_USERNAME }}/java-app:latest
- name: Build and push Python Docker image
run: |
docker build -t ${{ secrets.DOCKER_USERNAME }}/python-app:latest -f python-app/Dockerfile python-app
docker push ${{ secrets.DOCKER_USERNAME }}/python-app:latest
- name: Install Helm
run: |
wget https://get.helm.sh/helm-v3.5.2-linux-amd64.tar.gz
tar -xvzf helm-v3.5.2-linux-amd64.tar.gz
sudo cp -f linux-amd64/helm /usr/bin
helm version
- name: Build and package Java Helm chart
run: |
cd java-app
yq e -i '.image.tag = "latest"' ./helmchart/values.yaml
helm template ./helmchart
helm lint ./helmchart
helm package ./helmchart --version "1.0.0"
- name: Build and package Python Helm chart
run: |
cd python-app
yq e -i '.image.tag = "latest"' ./helmchart/values.yaml
helm template ./helmchart
helm lint ./helmchart
helm package ./helmchart --version "1.0.0"
- name: Set up Kubernetes
uses: azure/setup-kubectl@v1
with:
version: 'v1.21.0'
azcliversion: 'latest'
- name: Deploy Java application to Kubernetes
run: |
helm upgrade --install java-app ./java-app/helmchart --namespace java --create-namespace
- name: Deploy Python application to Kubernetes
run: |
helm upgrade --install python-app ./python-app/helmchart --namespace python --create-namespace
Create new Repository shared_library
in shared-liberary create folder vars in vars create sharedPipeline.groovy
structure is as follows:
jenkins-shared-library
├── vars │
└── sharedPipeline.groovy
└── README.md
Now that we have a basic git checkout library ready lets add it to Jenkins
configurations.
Step 1: Go to Manage Jenkins –> Configure System
Step 2: Find the Global Pipeline Libraries section and add your repo
details and configurations as shown below.
In shared_library Repository sharedPipeline.groovy file is as follows:
def call() {
pipeline {
agent any
environment {
DOCKERHUB_CREDENTIALS = credentials('dockerhubpwd')
SLACK_CREDENTIALS = credentials('b3ee302b-e782-4d8e-ba83-7fa591d43205')
}
parameters {
string(name: 'JAVA_REPO', defaultValue: 'https://github.com/pramilasawant/testhello.git', description: 'Java Application Repository')
string(name: 'PYTHON_REPO', defaultValue: 'https://github.com/pramilasawant/phython-application.git', description: 'Python Application Repository')
string(name: 'DOCKERHUB_USERNAME', defaultValue: 'pramila188', description: 'DockerHub Username')
string(name: 'JAVA_IMAGE_NAME', defaultValue: 'testhello', description: 'Java Docker Image Name')
string(name: 'PYTHON_IMAGE_NAME', defaultValue: 'python-app', description: 'Python Docker Image Name')
string(name: 'JAVA_NAMESPACE', defaultValue: 'test', description: 'Kubernetes Namespace for Java Application')
string(name: 'PYTHON_NAMESPACE', defaultValue: 'python', description: 'Kubernetes Namespace for Python Application')
}
stages {
stage('Clone Repositories') {
parallel {
stage('Clone Java Repo') {
steps {
git url: params.JAVA_REPO, branch: 'main'
}
}
stage('Clone Python Repo') {
steps {
dir('python-app') {
git url: params.PYTHON_REPO, branch: 'main'
}
}
}
}
}
stage('Build and Push Docker Images') {
parallel {
stage('Build and Push Java Image') {
steps {
dir('testhello') {
sh 'mvn clean install'
script {
def image = docker.build("${params.DOCKERHUB_USERNAME}/${params.JAVA_IMAGE_NAME}:${currentBuild.number}")
docker.withRegistry('', 'dockerhubpwd') {
image.push()
}
}
}
}
}
stage('Build and Push Python Image') {
steps {
dir('python-app') {
script {
def image = docker.build("${params.DOCKERHUB_USERNAME}/${params.PYTHON_IMAGE_NAME}:${currentBuild.number}")
docker.withRegistry('', 'dockerhubpwd') {
image.push()
}
}
}
}
}
}
}
stage('Get Approval') {
steps {
script {
input message: 'Do you approve this deployment?', ok: 'Yes, deploy'
}
}
}
stage('Install yq') {
steps {
sh '''
wget https://github.com/mikefarah/yq/releases/download/v4.6.1/yq_linux_amd64 -O "${WORKSPACE}/yq"
chmod +x "${WORKSPACE}/yq"
export PATH="${WORKSPACE}:$PATH"
'''
}
}
stage('Build and Package Java Helm Chart') {
steps {
dir('testhello') {
sh '''
"${WORKSPACE}/yq" e -i '.image.tag = "latest"' ./myspringbootchart/values.yaml
helm template ./myspringbootchart
helm lint ./myspringbootchart
helm package ./myspringbootchart --version "1.0.0"
'''
}
}
}
stage('Build and Package Python Helm Chart') {
steps {
dir('python-app') {
sh '''
"${WORKSPACE}/yq" e -i '.image.tag = "latest"' ./my-python-app/values.yaml
helm template ./my-python-app
helm lint ./my-python-app
helm package ./my-python-app --version "1.0.0"
'''
}
}
}
stage('Deploy Java Application to Kubernetes') {
steps {
script {
kubernetesDeploy(
configs: 'Build and Deploy Java and Python Applications',
kubeconfigId: 'kubeconfig1pwd'
)
}
}
}
stage('Deploy Python Application to Kubernetes') {
steps {
script {
kubernetesDeploy(
configs: 'Build and Deploy Java and Python Applications',
kubeconfigId: 'kubeconfig1pwd'
)
}
}
}
}
post {
always {
script {
def slackBaseUrl = 'https://slack.com/api/'
def slackChannel = '#builds'
def slackColor = currentBuild.currentResult == 'SUCCESS' ? 'good' : 'danger'
def slackMessage = "Build ${currentBuild.fullDisplayName} finished with status: ${currentBuild.currentResult}"
echo "Sending Slack notification to ${slackChannel} with message: ${slackMessage}"
slackSend(
baseUrl: 'https://yourteam.slack.com/api/',
teamDomain: 'StarAppleInfotech',
channel: '#builds',
color: slackColor,
botUser: true,
tokenCredentialId: 'b3ee302b-e782-4d8e-ba83-7fa591d43205',
notifyCommitters: false,
message: "Build Final_project #${env.BUILD_NUMBER} finished with status: ${currentBuild.currentResult}"
)
}
}
}
}
}
In application side create a Jenkinsfile in java application testhello Jenkinsfile is
as follows:
@Library('shared_library') _
sharedPipeline()
Then, build the Final_project with helm
- Dependency Track – End To End CI/CD Pipeline - November 29, 2024
- Dependency-track Jenkins Integration - November 27, 2024
- Jenkins Setup for PyTest + Selenium Automation Testing - November 27, 2024