Deploying a YouTube Clone App with DevSecOps & DevOps tools such as Jenkins using Shared Library, Docker, and Kubernetes requires a step-by-step guide
Table of contents
- Verify the Trivy version on Jenkins machine
- Configure Splunk
- Restart Splunk and Jenkins services to make it effective.
- On the Jenkins Server, we will create a simple hello pipeline to check if the logs are visible in Splunk.
- Integrate Slack for Notifications
- Install Plugins like JDK, Sonarqube Scanner, NodeJs
- Configure Java and Nodejs in Global Tool Configuration
- Configure Sonar Server in Manage Jenkins
- Add New stages to the pipeline
- Install OWASP Dependency Check Plugins
- Docker Image Build and Push
- Should have an rapidapiaccount.
- Run the Docker container
- Kubernetes Setup
- On Jenkins Server
- Install Helm & Monitoring K8S using Prometheus and Grafana
- Create Kubernetes Cluster Monitoring Dashboard.
- Create a POD Monitoring Dashboard
- Kubernetes Deployment
This blog will help you create a secure DevSecOps pipeline for your project. Using tools like Kubernetes, Docker, SonarQube, Trivy, OWASP Dependency Check, Prometheus, Grafana, Jenkins (with a shared library), Splunk, Rapid API, and Slack notifications, we make it easy to create and manage your environment.
Environment Setup:
Step 1: Launch an Ubuntu instance for
Jenkins( will install Trivy, Docker and SonarQube)
Splunk
K8S-Master
K8S-Worker
I am using Terraform to create a infrastrucutre. I have prepared the Terraform code.
clone the Terraform git repo in your system.
Do the
ls
in a terminal, go toTerraform_code
Folder, and initiate the following Terraform commands to run the infrastructure.
$ cd Terraform_Code
$ ls -l
total 20
drwxr-xr-x 1 bsingh 1049089 0 Jul 28 12:45 Code_IAC_Jenkins_Trivy_Docker/
drwxr-xr-x 1 bsingh 1049089 0 Jul 28 12:47 Code_IAC_Splunk/
-rw-r--r-- 1 bsingh 1049089 632 Jul 28 12:46 main.tf
Now, we have to run the following command
$ Terraform init
$ Terraform fmt # for formatting
$ Terraform validate # for validate the codes
$ Terraform plan # for plan the Terraform
$ Terraform apply # to Apply the terraform code.
Note: Once you apply the Terraform code, please wait 5 minutes for both instances to be ready and then configure them as described below. Now, we will configure Jenkins.
- To unlock the setup password
sudo cat /var/lib/jenkins/secrets/initialAdminPassword
Dashboard for Jenkins
Now, we will try to access the SonarQube as it is accessible via
9000
, Make sure add 9000 ports in the security group.
<ec2-public-ip:9000>
Dashboard of SonarQube
Verify the Trivy version on Jenkins machine
$ trivy --version
Version: 0.53.0
Configure Splunk
Do the following in a terminal: go to the Terraform_Code folder and run these Terraform commands to set up the infrastructure.
$ cd Terraform_Code
$ ls -l
total 20
drwxr-xr-x 1 bsingh 1049089 0 Jul 28 12:45 Code_IAC_Jenkins_Trivy_Docker/
drwxr-xr-x 1 bsingh 1049089 0 Jul 28 12:47 Code_IAC_Splunk/
-rw-r--r-- 1 bsingh 1049089 632 Jul 28 12:46 main.tf
Now, run the following commands:
$ terraform init
$ terraform fmt # for formatting
$ terraform validate # to validate the code
$ terraform plan # to plan the Terraform
$ terraform apply # to apply the Terraform code
Note: Once you apply the Terraform code, please wait 5 minutes for both instances to be ready, then configure them as described below. Now, we will configure Jenkins.
To unlock the setup password:
sudo cat /var/lib/jenkins/secrets/initialAdminPassword
Dashboard for Jenkins
Now, we will try to access SonarQube, which is available on port 9000. Make sure to add port 9000 to the security group.
<ec2-public-ip:9000>
Dashboard of SonarQube
Verify the Trivy version on the Jenkins machine:
$ trivy --version
Version: 0.53.0
Configure Splunk
Verify the public IP address of Splunk and open it in a browser.
<splunk-public-ip:8000>
Log in with the username and password you created when setting up Splunk.
Dashboard for Splunk
Install the Splunk app for Jenkins; ensure you have Splunk web portal login credentials, or create them first if you don't.
In Splunk Dashboard > Click on Apps > Find more apps
-
Search for Jenkins in the search bar. When you see the Splunk app for Jenkins, click on Install.
-
Click on
go home
-
- On the Splunk homepage, you will see that Jenkins has been added.
In the Splunk web interface, go to Settings > Data Inputs.
Click on HTTP Event Collector and Click on Global Settings
Set All tokens to enabled > Uncheck SSL enable > Use 8088 port and click on save
Now click on New token
-
Provide a Name and click on the next > Review > Click Submit
Click Start searching> Now let’s copy our token again> In the Splunk web interface, go to Settings > Data Inputs> Click on the HTTP event collector >Now copy your token and keep it safe.
Add Splunk Plugin in Jenkins
Go to Jenkins dashboard > Click on Manage Jenkins > Plugins > Available plugins > Search for Splunk and install it.
Now, Click on Manage Jenkins
System > Go to Splunk > Check to enable > HTTP input host as SPLUNK PUBLIC IP > HTTP token that you generated in Splunk> Jenkins IP and apply.
Don't forget to tick on Enable checkbox.
If the connection fails, follow the steps below on the Splunk EC2 machine.
ubuntu@ip-172-31-23-110:~$ sudo ufw allow 8088 Rules updated Rules updated (v6) ubuntu@ip-172-31-23-110:~$ sudo ufw status Status: inactive ubuntu@ip-172-31-23-110:~$ sudo ufw allow openSSH Rules updated Rules updated (v6) ubuntu@ip-172-31-23-110:~$ sudo ufw allow 8000 Rules updated Rules updated (v6) ubuntu@ip-172-31-23-110:~$ sudo ufw status Status: inactive ubuntu@ip-172-31-23-110:~$ sudo ufw enable Command may disrupt existing ssh connections. Proceed with operation (y|n)? y Firewall is active and enabled on system startup ubuntu@ip-172-31-23-110:~$
Check Network Connectivity from Jenkins to Splunk
ping 52.204.146.179
telnet 52.204.146.179 8088
Restart Splunk and Jenkins services to make it effective.
Procedure to restart Jenkins
Jenkins Public IP Address:8080/restart
Procedure to restart Splunk
Click on Settings > Server controls > Restart splunk.
On the Jenkins Server, we will create a simple hello pipeline to check if the logs are visible in Splunk.
Now go to Splunk, click on the Jenkins app, and you will see some data from Jenkins.
We can see the logs in Splunk. 😃
If you want to see the more details logs then switch it to admin
and you will see below
Integrate Slack for Notifications
If you don't have a Slack account, create one first. If you already have an account, log in. Slack login
Create a Slack account and create a channel Named "Jenkins_Notification"
Install the Jenkins CI app on Slack
Go to Slack and click on your name > Select Settings and Administration > Click on Manage apps
-
search here "
Jenkins CI
" > Click onAdd to Slack
-
Select the change name "Jenkins" and click on
add Jenkins CI integration
You will be sent to this page
Install Slack Notification Plugin in Jenkins
Go to Jenkins Dashboard > Click on manage Jenkins > Plugins > Available plugins "Search for Slack Notification and install"
Now, we will be configure the credential
Click on Manage Jenkins –> Credentials > Global > Select kind as Secret Text > At Secret Section Provide Your Slack integration token credential ID> Id and description are optional and create
in Slack Step 3 it is mention the token.
Click on Manage Jenkins > System > Go to the end of the page > Workspace > team subdomain > Credential –> Select your Credential for Slack > Default channel –> Provide your Channel name > Test connection > Click on Apply and save
You will get a notification as below on Slack app.
Add this to the pipeline
def COLOR_MAP = [ 'FAILURE' : 'danger', 'SUCCESS' : 'good' ] post { always { echo 'Slack Notifications' slackSend ( channel: '#jenkins', #change your channel name color: COLOR_MAP[currentBuild.currentResult], message: "*${currentBuild.currentResult}:* Job ${env.JOB_NAME} \n build ${env.BUILD_NUMBER} \n More info at: ${env.BUILD_URL}" ) } }
If you don't know how to do Integrating Slack with Jenkins
Sample pipeline with post action.
```bash def COLOR_MAP = [ 'FAILURE' : 'danger', 'SUCCESS' : 'good' ]
pipeline { agent any
stages { stage('Hello') { steps { echo 'Hello World' } } }
post { always { echo 'Slack Notifications' slackSend ( channel: '#jenkins', color: COLOR_MAP[currentBuild.currentResult], message: "${currentBuild.currentResult}: Job ${env.JOB_NAME} \n build ${env.BUILD_NUMBER} \n More info at: ${env.BUILD_URL}" ) } } }
You will get Slack Notification
* ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722485569206/0771003c-2c2f-407a-9762-4395b3f693ff.png align="center")
* Splunk Notification
* ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722485580921/fda146b8-8250-4d91-b385-b6b8fb4684bd.png align="center")
### Start Jenkins Shared library Job : [Ref link](https://www.jenkins.io/doc/book/pipeline/shared-libraries/)
Go to Jenkins dashboard and click on New Item. Provide a name for the Job & click on Pipeline and click on OK.
2.b: Create a `Jenkins shared library1` in GitHub Create a new repository in GitHub named `Jenkins_shared_library1`
* ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722485636264/30c09949-d384-4735-b6ca-b218f3928316.png align="center")
* Connect to your VS Code , Create a directory named `Jenkins_shared_library1`, Create a Vars directory inside it
![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722485649885/c718914b-37eb-43c0-ba9a-506d8d7dd68d.png align="center")
Open Terminal Run the below commands to push to GitHub
* ```sh
echo "Welcome to my Jenkins_shared_library" >> README.md
git init
git add README.md
git commit -m "first commit"
git branch -M main
git push -u origin main
- Create
cleanWorkspace.groovy
file and add the below code
//cleanWorkspace.groovy //cleans workspace
def call() {
cleanWs()
}
Create
checkoutGit.groovy
file and add the code below.Note: we will be using this
Youtube-clone-app
repo.
def call(String gitUrl, String gitBranch) {
checkout([
$class: 'GitSCM',
branches: [[name: gitBranch]],
userRemoteConfigs: [[url: gitUrl]]
])
}
Now push them to GitHub using the below commands from vs code
git add .
git commit -m "message"
git push origin main
- Add Jenkins shared library to Jenkins system Go to Jenkins Dashboard > Click on Manage Jenkins > system > Search for
Global Trusted Pipeline Libraries
and click on Add
Now Provide a name that we have to call in our pipeline
-
Click apply and save
Now, go to the your pipeline
- Run Pipeline Go to Jenkins Dashboard again & select the job and add the below pipeline
@Library('Jenkins_shared_library') _ //name used in jenkins system for library
def COLOR_MAP = [
'FAILURE' : 'danger',
'SUCCESS' : 'good'
]
pipeline{
agent any
parameters {
choice(name: 'action', choices: 'create\ndelete', description: 'Select create or destroy.')
}
stages{
stage('clean workspace'){
steps{
cleanWorkspace()
}
}
stage('checkout from Git'){
steps{
checkoutGit('https://github.com/mrbalraj007/Youtube-clone-app.git', 'main')
}
}
}
post {
always {
echo 'Slack Notifications'
slackSend (
channel: '#jenkins', //change your channel name
color: COLOR_MAP[currentBuild.currentResult],
message: "*${currentBuild.currentResult}:* Job ${env.JOB_NAME} \n build ${env.BUILD_NUMBER} \n More info at: ${env.BUILD_URL}"
)
}
}
}
Build with parameters and build
here is the Stage view.
-
Install Plugins like JDK, Sonarqube Scanner, NodeJs
Install Plugin
Go to Manage Jenkins →Plugins → Available Plugins →
Install below plugins
I→ Eclipse Temurin Installer (Install without restart)
II → SonarQube Scanner (Install without restart)
III → NodeJs Plugin (Install Without restart)
Configure Java and Nodejs in Global Tool Configuration
Goto Manage Jenkins → Tools → Install JDK(17) and NodeJs(16)→ Click on Apply and Save
-
Need to use the latest version of NodeJS
-
Configure Sonar Server in Manage Jenkins
Grab the Public IP Address of your EC2 Instance. SonarQube works on Port 9000, so use :9000. Go to your SonarQube Server. Click on Administration → Security → Users → Click on Tokens and Update Token → Give it a name → and click on Generate Token.
-
click on update Token
-
Create a token with a name and generate and notedown somewhere.
-
Goto Jenkins Dashboard → Manage Jenkins → Credentials → Add Secret Text.
Now, go to Dashboard → Manage Jenkins → System and Add like the below image.
-
Click on Apply and Save.
The Configure System option is used in Jenkins to configure different servers. Global Tool Configuration is used to configure different tools that we install using plugins. We will install a Sonar scanner in the tools.
-
In the Sonarqube Dashboard add a quality gate also Administration–> Configuration–>Webhooks > Click on Create
-
Add details
#in url section of quality gate <http://jenkins-public-ip:8080>/sonarqube-webhook/
Add New stages to the pipeline
Go to vs code and create a file
sonarqubeAnalysis.groovy
& add the below code and push to Jenkins shared library GitHub Repo.def call() { withSonarQubeEnv('sonar-server') { sh ''' $SCANNER_HOME/bin/sonar-scanner -Dsonar.projectName=Youtube -Dsonar.projectKey=Youtube ''' } }
Create another file for qualityGate.groovy
def call(credentialsId) { waitForQualityGate abortPipeline: false, credentialsId: credentialsId }
Create another file for npmInstall.groovy
def call() { sh 'npm install' }
Push them to the GitHub Jenkins shared library
git add . git commit -m "message" git push origin main
Add these stages to the pipeline now
//under parameters tools{ jdk 'jdk17' nodejs 'node16' } environment { SCANNER_HOME=tool 'sonar-scanner' } // add in stages stage('sonarqube Analysis'){ when { expression { params.action == 'create'}} steps{ sonarqubeAnalysis() } } stage('sonarqube QualitGate'){ when { expression { params.action == 'create'}} steps{ script{ def credentialsId = 'Sonar-token' qualityGate(credentialsId) } } } stage('Npm'){ when { expression { params.action == 'create'}} steps{ npmInstall() } }
Pipeline should be looks like
@Library('Jenkins_shared_library') _ def COLOR_MAP = [ 'FAILURE' : 'danger', 'SUCCESS' : 'good' ] pipeline{ agent any tools{ jdk 'jdk17' nodejs 'node16' } environment { SCANNER_HOME=tool 'sonar-scanner' } parameters { choice(name: 'action', choices: 'create\ndelete', description: 'Select create or destroy.') } stages{ stage('clean workspace'){ steps{ cleanWorkspace() } } stage('checkout from Git'){ steps{ checkoutGit('https://github.com/mrbalraj007/Youtube-clone-app.git', 'main') } } stage('sonarqube Analysis'){ when { expression { params.action == 'create'}} steps{ sonarqubeAnalysis() } } stage('sonarqube QualitGate'){ when { expression { params.action == 'create'}} steps{ script{ def credentialsId = 'Sonar-token' qualityGate(credentialsId) } } } stage('Npm'){ when { expression { params.action == 'create'}} steps{ npmInstall() } } } post { always { echo 'Slack Notifications' slackSend ( channel: '#jenkins', color: COLOR_MAP[currentBuild.currentResult], message: "*${currentBuild.currentResult}:* Job ${env.JOB_NAME} \n build ${env.BUILD_NUMBER} \n More info at: ${env.BUILD_URL}" ) } } }
Now, time to Build it again and see the Stage View.
-
To see the report, you can go to the Sonarqube Server and navigate to Projects.
You can see the report has been generated, and the status shows as passed. You can see that 549 lines were scanned. For a detailed report, you can go to issues.
-
Slack Notification
-
Install OWASP Dependency Check Plugins
GotoDashboard → Manage Jenkins → Plugins → OWASP Dependency-Check. Click on it and install it without restart.
-
First, we configured the Plugin and next, we had to configure the Tool Goto Dashboard → Manage Jenkins → Tools
-
Click on Apply and Save here.
Create a file for trivyFs.groovy
def call() { sh 'trivy fs . > trivyfs.txt' }
Push to GitHub
git add . git commit -m "message" git push origin main
Add the below stages to the Jenkins pipeline
stage('Trivy file scan'){ when { expression { params.action == 'create'}} steps{ trivyFs() } } stage('OWASP FS SCAN') { when { expression { params.action == 'create'}} steps { dependencyCheck additionalArguments: '--scan ./ --disableYarnAudit --disableNodeAudit', odcInstallation: 'DP-Check' dependencyCheckPublisher pattern: '**/dependency-check-report.xml' } }
Note: The stage with the Dependency Check steps cannot be directly used inside a shared library. The main reason is that pipelines loaded from shared libraries have more restrictive script security by default, so the dependencyCheck and dependencyCheckPublisher steps would fail with rejected signature errors.
-
You will see that in status, a graph will also be generated and Vulnerabilities.
-
Docker Image Build and Push
We need to install the Docker tool in our system, Goto Dashboard → Manage Plugins → Available plugins → Search for Docker and install these plugins
Docker Docker Commons Docker Pipeline Docker API docker-build-step
and click on install without restart
Add DockerHub Username and Password under Global Credentials
-
Now, goto Dashboard → Manage Jenkins → Tools
-
Should have an rapidapiaccount.
"Once you have an account, your name will automatically appear in Rapid API."
-
In the search bar, type "YouTube" and choose "YouTube v3."
-
Copy API and use it in the groovy file
docker build –build-arg REACT_APP_RAPID_API_KEY= -t ${imageName} .
Create a shared library file for dockerBuild.groovy
def call(String dockerHubUsername, String imageName) { // Build the Docker image sh "docker build --build-arg REACT_APP_RAPID_API_KEY=f0ead79813mshb0aa -t ${imageName} ." // Tag the Docker image sh "docker tag ${imageName} ${dockerHubUsername}/${imageName}:latest" // Push the Docker image withDockerRegistry([url: 'https://index.docker.io/v1/', credentialsId: 'docker']) { sh "docker push ${dockerHubUsername}/${imageName}:latest" } }
Create another file for trivyImage.groovy
def call() { sh 'trivy image sevenajay/youtube:latest > trivyimage.txt' }
Push the above files to the GitHub shared library.
Add this stage to your pipeline with parameters
#add inside parameter string(name: 'DOCKER_HUB_USERNAME', defaultValue: 'balrajsi', description: 'Docker Hub Username') string(name: 'IMAGE_NAME', defaultValue: 'youtube', description: 'Docker Image Name') #stage stage('Docker Build'){ when { expression { params.action == 'create'}} steps{ script{ def dockerHubUsername = params.DOCKER_HUB_USERNAME def imageName = params.IMAGE_NAME dockerBuild(dockerHubUsername, imageName) } } } stage('Trivy iamge'){ when { expression { params.action == 'create'}} steps{ trivyImage() } }
Run the Docker container
Create a new file runContainer.groovy
def call(){ sh "docker run -d --name youtube1 -p 3000:3000 balrajsi/youtube:latest" }
Create Another file to remove container removeContainer.groovy
def call(){ sh 'docker stop youtube1' sh 'docker rm youtube1' }
Push them to the Shared library GitHub repo
git add . git commit -m "message" git push origin main
Add the below stages to the Pipeline
stage('Run container'){ when { expression { params.action == 'create'}} steps{ runContainer() } } stage('Remove container'){ when { expression { params.action == 'delete'}} steps{ removeContainer() } }
here is the updated pipeline so far
@Library('Jenkins_shared_library') _ def COLOR_MAP = [ 'FAILURE' : 'danger', 'SUCCESS' : 'good' ] pipeline{ agent any tools{ jdk 'jdk17' nodejs 'node16' } environment { SCANNER_HOME=tool 'sonar-scanner' } parameters { choice(name: 'action', choices: 'create\ndelete', description: 'Select create or destroy.') string(name: 'DOCKER_HUB_USERNAME', defaultValue: 'balrajsi', description: 'Docker Hub Username') string(name: 'IMAGE_NAME', defaultValue: 'youtube', description: 'Docker Image Name') } stages{ stage('clean workspace'){ steps{ cleanWorkspace() } } stage('checkout from Git'){ steps{ checkoutGit('https://github.com/mrbalraj007/Youtube-clone-app.git', 'main') } } stage('sonarqube Analysis'){ when { expression { params.action == 'create'}} steps{ sonarqubeAnalysis() } } stage('sonarqube QualitGate'){ when { expression { params.action == 'create'}} steps{ script{ def credentialsId = 'Sonar-token' qualityGate(credentialsId) } } } stage('Npm'){ when { expression { params.action == 'create'}} steps{ npmInstall() } } stage('Trivy file scan'){ when { expression { params.action == 'create'}} steps{ trivyFs() } } stage('OWASP FS SCAN') { when { expression { params.action == 'create'}} steps { dependencyCheck additionalArguments: '--scan ./ --disableYarnAudit --disableNodeAudit', odcInstallation: 'DP-Check' dependencyCheckPublisher pattern: '**/dependency-check-report.xml' } } stage('Docker Build'){ when { expression { params.action == 'create'}} steps{ script{ def dockerHubUsername = params.DOCKER_HUB_USERNAME def imageName = params.IMAGE_NAME dockerBuild(dockerHubUsername, imageName) } } } stage('Trivy iamge'){ when { expression { params.action == 'create'}} steps{ trivyImage() } } stage('Run container'){ when { expression { params.action == 'create'}} steps{ runContainer() } } stage('Remove container'){ when { expression { params.action == 'delete'}} steps{ removeContainer() } } } post { always { echo 'Slack Notifications' slackSend ( channel: '#jenkins', color: COLOR_MAP[currentBuild.currentResult], message: "*${currentBuild.currentResult}:* Job ${env.JOB_NAME} \n build ${env.BUILD_NUMBER} \n More info at: ${env.BUILD_URL}" ) } } }
Build with parameters ‘create’
-
I can see the image pushed to my Docker Hub account.
It will start the container public-ip-jenkins:3000
-
Build with parameters ‘delete’ It will stop and remove the Container
Delete view:
-
Kubernetes Setup
Will create two Ubuntu
t2.large
instances, one for the k8s master and the other for the worker.Install Kubectl on the Jenkins machine as well.
Kubectl is to be installed on Jenkins
Connect to your Jenkins machine, and create a shell script file install.sh
sudo apt-get update -y # Install AWS CLI sudo apt-get install -y awscli, curl # Install kubectl curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl kubectl version --client
K8S Master-Worker setup
Will set the host name
# Master Node sudo hostnamectl set-hostname K8s-Master # Worker Node sudo hostnamectl set-hostname K8s-Worker
Will install the package on both Master & Node
sudo apt-get update sudo apt-get install -y docker.io sudo usermod –aG docker Ubuntu newgrp docker sudo chmod 777 /var/run/docker.sock sudo apt-get update # apt-transport-https may be a dummy package; if so, you can skip that package sudo apt-get install -y apt-transport-https ca-certificates curl gpg curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.29/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.29/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list sudo apt-get update sudo apt-get install -y kubelet kubeadm kubectl sudo apt-mark hold kubelet kubeadm kubectl sudo snap install kube-apiserver
Note- if ask for password then presh enter and move on.
Now, we will run the following code on
Master node only
sudo kubeadm init --pod-network-cidr=10.244.0.0/16 # in case your in root exit from it and run below commands mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
On Worker Node-:
sudo kubeadm join : --token --discovery-token-ca-cert-hash --v=5
sudo kubeadm join 172.31.20.226:6443 --token 035jqv.haoqokd3166ocy8f --discovery-token-ca-cert-hash sha256:938fa33276feb05b57db6231f546cea2a4a2b49b7574618737e02982cb7ceb7e --v=5
From the K8S-master download the config file which is under path
/home/ubuntu/.kube
copy it and save it in documents or another folder, save it as secret-file.txt
If you are using Moboxterm then you can follow as below.
On Jenkins Server
Install Kubernetes Plugin,
Kubernetes Credentials Kubernetes Kubernetes Client API Kubernetes CLI
go to Manage Jenkins -> Manage Credentials -> Click on Jenkins Global -> Add Credentials
-
Install Helm & Monitoring K8S using Prometheus and Grafana
On Kubernetes Master install the helm
curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 chmod 700 get_helm.sh ./get_helm.sh
See the Helm version
helm version --client
We need to add the Helm Stable Charts for your local client. Execute the below command:
helm repo add stable https://charts.helm.sh/stable
Add Prometheus Helm repo
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
Create Prometheus namespace
kubectl create namespace prometheus
Install kube-Prometheus-stack Below is the command to install kube-prometheus-stack. The helm repo kube-stack-Prometheus (formerly Prometheus-operator) comes with a Grafana deployment embedded.
Let’s check if the Prometheus and Grafana pods are running or not
kubectl get pods -n prometheus
Now See the services
kubectl get svc -n prometheus
This confirms that Prometheus and grafana have been installed successfully using Helm.
To make Prometheus and grafana available outside the cluster, use LoadBalancer or NodePort instead of ClusterIP.
Edit Prometheus Service
kubectl edit svc stable-kube-prometheus-sta-prometheus -n prometheus
Edit Grafana Service
kubectl edit svc stable-grafana -n prometheus
Verify if the service is changed to LoadBalancer and also get the Load BalancerPorts.
kubectl get svc -n prometheus
Access Grafana UI in the browser
Get the external IP from the above screenshot and put it in the browser k8s-master-public-ip:external-ip
Login to Grafana
UserName: admin Password: prom-operator
- Create a Dashboard in Grafana
In Grafana, we can create various kinds of dashboards as per our needs.
How to Create Kubernetes Monitoring Dashboard? For creating a dashboard to monitor the cluster: Click the ‘+’ button on the left panel and select ‘Import’. Enter the 15661
dashboard id under Grafana.com
Dashboard. Click ‘Load’.
-
Select ‘Prometheus’ as the endpoint under the Prometheus data sources drop-down. Click ‘Import’.
This will show the monitoring dashboard for all cluster nodes
Create Kubernetes Cluster Monitoring Dashboard.
For creating a dashboard to monitor the cluster:
Click the ‘+’ button on the left panel and select ‘Import’.
Enter 3119 dashboard ID under Grafana.com Dashboard.
Click ‘Load’.
Select ‘Prometheus’ as the endpoint under the Prometheus data sources drop-down.
Click ‘Import’.
This will show the monitoring dashboard for all cluster nodes
-
Create a POD Monitoring Dashboard
For creating a dashboard to monitor the cluster:
Click the ‘+’ button on the left panel and select ‘Import’.
Enter 6417 dashboard ID under Grafana.com Dashboard.
Click ‘Load’.
Select ‘Prometheus’ as the endpoint under the Prometheus data sources drop-down.
Click ‘Import’.
Kubernetes Deployment
Let’s Create a Shared Jenkins library file for K8s deploy and delete
Name
kubeDeploy.groovy
def call() { withKubeConfig(caCertificate: '', clusterName: '', contextName: '', credentialsId: 'k8s', namespace: '', restrictKubeConfigAccess: false, serverUrl: '') { sh "kubectl apply -f deployment.yml" } }
To delete deployment
Name
kubeDelete.groovy
def call() { withKubeConfig(caCertificate: '', clusterName: '', contextName: '', credentialsId: 'k8s', namespace: '', restrictKubeConfigAccess: false, serverUrl: '') { sh "kubectl delete -f deployment.yml" } }
Let’s push them to GitHub
git add . git commit -m "message" git push origin main
The final stage of the Pipeline
stage('Kube deploy'){ when { expression { params.action == 'create'}} steps{ kubeDeploy() } } stage('kube deleter'){ when { expression { params.action == 'delete'}} steps{ kubeDelete() } }
Overall pipeline state
@Library('Jenkins_shared_library') _ def COLOR_MAP = [ 'FAILURE' : 'danger', 'SUCCESS' : 'good' ] pipeline{ agent any tools{ jdk 'jdk17' nodejs 'node16' } environment { SCANNER_HOME=tool 'sonar-scanner' } parameters { choice(name: 'action', choices: 'create\ndelete', description: 'Select create or destroy.') string(name: 'DOCKER_HUB_USERNAME', defaultValue: 'balrajsi', description: 'Docker Hub Username') string(name: 'IMAGE_NAME', defaultValue: 'youtube', description: 'Docker Image Name') } stages{ stage('clean workspace'){ steps{ cleanWorkspace() } } stage('checkout from Git'){ steps{ checkoutGit('https://github.com/mrbalraj007/Youtube-clone-app.git', 'main') } } stage('sonarqube Analysis'){ when { expression { params.action == 'create'}} steps{ sonarqubeAnalysis() } } stage('sonarqube QualitGate'){ when { expression { params.action == 'create'}} steps{ script{ def credentialsId = 'Sonar-token' qualityGate(credentialsId) } } } stage('Npm'){ when { expression { params.action == 'create'}} steps{ npmInstall() } } stage('Trivy file scan'){ when { expression { params.action == 'create'}} steps{ trivyFs() } } stage('OWASP FS SCAN') { when { expression { params.action == 'create'}} steps { dependencyCheck additionalArguments: '--scan ./ --disableYarnAudit --disableNodeAudit', odcInstallation: 'DP-Check' dependencyCheckPublisher pattern: '**/dependency-check-report.xml' } } stage('Docker Build'){ when { expression { params.action == 'create'}} steps{ script{ def dockerHubUsername = params.DOCKER_HUB_USERNAME def imageName = params.IMAGE_NAME dockerBuild(dockerHubUsername, imageName) } } } stage('Trivy iamge'){ when { expression { params.action == 'create'}} steps{ trivyImage() } } stage('Run container'){ when { expression { params.action == 'create'}} steps{ runContainer() } } stage('Remove container'){ when { expression { params.action == 'delete'}} steps{ removeContainer() } } stage('Kube deploy'){ when { expression { params.action == 'create'}} steps{ kubeDeploy() } } stage('kube deleter'){ when { expression { params.action == 'delete'}} steps{ kubeDelete() } } } post { always { echo 'Slack Notifications' slackSend ( channel: '#jenkins', color: COLOR_MAP[currentBuild.currentResult], message: "*${currentBuild.currentResult}:* Job ${env.JOB_NAME} \n build ${env.BUILD_NUMBER} \n More info at: ${env.BUILD_URL}" ) } } }
It will apply the deployment
Stage view
-
kubectl get all (or) kubectl get svc
Will verify if the YouTube app is accessible from Kubernetes.
<kubernetes-worker-ip:svc port>
Delete view:
-
ResourIt will apply the deployment. ### Stage View To verify if the YouTube app is accessible from Kubernetes, use: ```sh kubectl get all
or
kubectl get svc
Access the app at:
<kubernetes-worker-ip:svc port>
Delete View
Resources used in AWS