Jenkins (CICD) - On-Premises
Clone the Jenkins Helm chart to your GitHub repository
git clone https://github.com/jenkinsci/helm-charts
Modify values.yaml
to set account information
## Sections to modify
-- Update login information
admin:
username: "WHAT YOU WANT" # Set admin username
password: "WHAT YOU WANT" # Set admin password
...
-- Update the following section to enable login
# Jenkins Config as Code Security Realm-section
securityRealm: |-
local:
allowsSignup: false # Disable user signup
enableCaptcha: false # Disable captcha
users:
- id: "WHAT YOU WANT" # Set admin user ID
password: "WHAT YOU WANT" # Set admin user password
ArgoCD - Connect to your Git repository to configure Jenkins CD
Creating a Jenkins Item
Create a new item
- Select
Pipeline
Configure GitHub project
Check
GitHub project
Enter the repository URL
Set build trigger
- Check
GitHub hook trigger for GITScm polling
Define the pipeline
Choose either
Pipeline script
orPipeline script from SCM
Creating the Jenkins Pipeline (CI/CD)Jenkins Pipeline Configuration
pipeline { agent { kubernetes { label 'jenkins-agent' yaml """ apiVersion: v1 kind: Pod spec: containers: - name: jnlp image: jenkins/inbound-agent:latest args: ['\$(JENKINS_SECRET)', '\$(JENKINS_NAME)'] - name: docker image: docker:20.10 command: - cat tty: true volumeMounts: - name: docker-socket mountPath: /var/run/docker.sock - name: kubectl image: lachlanevenson/k8s-kubectl:latest command: - cat tty: true volumeMounts: - name: kube-config mountPath: /home/jenkins/.kube volumes: - name: docker-socket hostPath: path: /var/run/docker.sock type: Socket - name: kube-config configMap: name: kube-config """ } } environment { GIT_CREDENTIALS_ID = 'YOUR GIT TOKEN CREDENTAIL ID IN JENKINS' // GitHub credentials token DOCKER_HUB_REPO = 'YOUR REPOSITORY' // Docker Hub repository SLACK_CHANNEL = 'YOUR SLACK CHANNEL' // Slack notification channel SLACK_CREDENTIAL_ID = 'YOUR SLACK TOKEN CREDENTAIL ID IN JENKINS' // Slack credentials token KUBECONFIG_PATH = '/home/jenkins/.kube/kubeconfig' // Kubernetes config path } stages { stage('Clone Repository') { steps { container('jnlp') { git credentialsId: env.GIT_CREDENTIALS_ID, branch: 'main', url: 'https://github.com/hee-bin/frontend-cicd-test.git' // Clone Git repository } } } stage('Build Docker Image') { steps { container('docker') { script { def customImage = docker.build("${DOCKER_HUB_REPO}:${env.BUILD_ID}") // Build Docker image } } } } stage('Test Docker Image') { steps { script { def dockerImageTag = "${DOCKER_HUB_REPO}:${env.BUILD_ID}" sh "docker run --rm -d --name test_container ${dockerImageTag} npm run dev" // Run Docker container sh "docker exec test_container echo 'I am running'" // Check container status sh "docker stop test_container" // Stop container } } } stage('Push Docker Image') { steps { container('docker') { script { withCredentials([usernamePassword(credentialsId: 'dockerHub-token', usernameVariable: 'DOCKERHUB_USER', passwordVariable: 'DOCKERHUB_PASS')]) { sh "echo ${DOCKERHUB_PASS} | docker login -u ${DOCKERHUB_USER} --password-stdin" // Docker Hub login sh "docker tag ${DOCKER_HUB_REPO}:${env.BUILD_ID} ${DOCKER_HUB_REPO}:${env.BUILD_ID}" // Tag Docker image sh "docker push ${DOCKER_HUB_REPO}:${env.BUILD_ID}" // Push Docker image sh "docker tag ${DOCKER_HUB_REPO}:${env.BUILD_ID} ${DOCKER_HUB_REPO}:latest" sh "docker push ${DOCKER_HUB_REPO}:latest" } } } } } stage('Deploy to Kubernetes') { steps { container('kubectl') { script { withEnv(["KUBECONFIG=${env.KUBECONFIG_PATH}"]) { def deploymentExists = sh(script: 'kubectl get deployment frontend', returnStatus: true) == 0 // Check if deployment exists if (deploymentExists) { sh "kubectl set image deployment/frontend frontend=${DOCKER_HUB_REPO}:${env.BUILD_ID} --record" // Update existing deployment } else { sh 'kubectl apply -f test.yml' // Apply new deployment } } } } } } } post { always { script { slackSend(channel: env.SLACK_CHANNEL, message: "Build ${currentBuild.fullDisplayName} finished with status: ${currentBuild.currentResult}") // Send Slack notification } } success { script { slackSend(channel: env.SLACK_CHANNEL, message: "Build ${currentBuild.fullDisplayName} succeeded") // Send success notification } } failure { script { slackSend(channel: env.SLACK_CHANNEL, message: "Build ${currentBuild.fullDisplayName} failed") // Send failure notification } } } }
Kubeconfig File:
Contains information for accessing and interacting with Kubernetes cluster.
Includes:
Cluster Information: Kubernetes API server address.
User Information: Authentication details (certificates, tokens).
Context Information: Links users to clusters, facilitates easy switching.
Role of KUBECONFIG_PATH:
Cluster Authentication:
Provides access details to Kubernetes cluster.
Ensures authenticated interaction for
kubectl
commands.Command Execution:
Used by
kubectl
to interact with the cluster.Necessary for checking deployments, applying new ones, etc.
Example Usage:
Jenkins Pipeline:
pipeline { // Jenkins agent and other settings... environment { GIT_CREDENTIALS_ID = 'YOUR GIT TOKEN CREDENTIAL ID IN JENKINS' DOCKER_HUB_REPO = 'YOUR REPOSITORY' SLACK_CHANNEL = 'YOUR SLACK CHANNEL' SLACK_CREDENTIAL_ID = 'YOUR SLACK TOKEN CREDENTIAL ID IN JENKINS' KUBECONFIG_PATH = '/home/jenkins/.kube/kubeconfig' // Kubernetes config path } stages { // Other stages... stage('Deploy to Kubernetes') { steps { container('kubectl') { script { withEnv(["KUBECONFIG=${env.KUBECONFIG_PATH}"]) { // Check if Kubernetes deployment exists def deploymentExists = sh(script: 'kubectl get deployment frontend', returnStatus: true) == 0 if (deploymentExists) { // Update existing deployment sh "kubectl set image deployment/frontend frontend=${DOCKER_HUB_REPO}:${env.BUILD_ID} --record" } else { // Apply new deployment sh 'kubectl apply -f test.yml' } } } } } } } // Post actions... }
Key Takeaways:
KUBECONFIG_PATH:
Specifies the path to the Kubeconfig file.
Essential for secure communication and deployment tasks in Kubernetes cluster.
Setting Up Jenkins Credentials
environment {
GIT_CREDENTIALS_ID = 'YOUR GIT TOKEN CREDENTAIL ID IN JENKINS' // GitHub credentials token
DOCKER_HUB_REPO = 'YOUR REPOSITORY' // Docker Hub repository
SLACK_CHANNEL = 'YOUR SLACK CHANNEL' // Slack notification channel
SLACK_CREDENTIAL_ID = 'YOUR SLACK TOKEN CREDENTAIL ID IN JENKINS' // Slack credentials token
KUBECONFIG_PATH = '/home/jenkins/.kube/kubeconfig' // Kubernetes config path
}
Git Credentials: Token for GitHub or GitLab
Docker Hub Credentials: Token for Docker Hub or GCR
Slack Token: Generated upon installing Jenkins CI in Slack
Integrating Jenkins with GitHub Webhook
Jenkins Configuration
Create Item
Select
GitHub project
Enter the repository URL
Check
Build Triggers
forGitHub hook trigger for GITScm polling
GitHub Configuration
Set Up Webhook
Navigate to
repository > settings > webhooks
Set the Payload URL to
http://<jenkins-server-url>/github-webhook
0/github-webhook !!!!!
USE IP instead of DOMAIN
Integrating Jenkins with Slack
Slack Configuration
Install Jenkins CI App in Slack
Create and Configure Notification Channel
Generate Slack Token
Jenkins Configuration
Install Slack Notification Plugin
- Manage Jenkins > Manage Plugins > Available > Slack Notification Plugin
Store Credentials
- Store the generated Slack token as a credential in Jenkins
Configure Slack Notifier in Jenkins
Manage Jenkins > Configure System > Slack Notifier
Set Workspace and Credential
Pipeline Configuration
For Freestyle projects, configure Slack notification in the Post-build Actions section
For Pipeline projects, define Slack notification in the Jenkinsfile
This guide explains how to set up Jenkins using Helm, integrate it with GitHub and Slack for a complete CI/CD pipeline, and automate build, test, and deployment processes using a Jenkins pipeline script.