Learn End to End Solution Of Jenkins, Helm and Kubenetes in Local Environment

Deploy Jenkins in Docker for Desktop

1. Make sure Docker for desktop is installed and running. 
2. Write the Dockerfile for Jenkins As follows: 
FROM jenkins/jenkins:2.277.4-lts-jdk11
USER root
RUN apt-get update && apt-get install -y apt-transport-https \
ca-certificates curl gnupg2 \
RUN curl -fsSL https://download.docker.com/linux/debian/gpg | apt-key add -
RUN apt-key fingerprint 0EBFCD88
RUN add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/debian \
$(lsb_release -cs) stable"
RUN apt-get update && apt-get install -y docker-ce-cli
RUN curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
RUN install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl
RUN curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3
RUN chmod 700 get_helm.sh
RUN ./get_helm.sh
RUN mkdir /root/.kube
COPY ./config /root/.kube/
RUN jenkins-plugin-cli --plugins "blueocean:1.24.6 docker-workflow:1.26"

And docker-compose.yml as, 
version: "2"
# image: jenkinsci/blueocean
build: .
user: root
- "8080:8080"
- "8443:8443"
- "50000:50000"
- ./jenkins_data:/var/jenkins_home
##### Mac OS X and Linux ONLY #####
- /var/run/docker.sock:/var/run/docker.sock

3. Also copy or create a config file as per your ~/.kube/config in the same folder of Dockerfile. We will copy this in the container. This will help Jenkins instance to realize and connect to Docker for Desktop Kubernetes. So, file content will look like, 
apiVersion: v1
- cluster:
    certificate-authority-data: ...
    server: https://kubernetes.docker.internal:6443
  name: docker-desktop
- context:
    cluster: docker-desktop
    user: docker-desktop
  name: docker-desktop
current-context: docker-desktop
kind: Config
preferences: {}
- name: docker-desktop
    client-certificate-data: ...
    client-key-data: ...

4. In the folder of Dockerfile and docker-compose, run the command: docker-compose up. The jenkins should run at localhost:8080. Create a Admin user and password that you will use later to deploy the app.
It is important to note that, in the Jenkins I want bith kubectl and helm be available. That is why the dockerfile has helm installation and kubectl binary download command which is important because that is how Jenkins will realize helm command when it will spin up. You can read more detail about the dockerfile and compose file about Jenkins here:
install helm: https://helm.sh/docs/intro/install/
install kubectl: https://kubernetes.io/docs/tasks/tools/install-kubectl-linux/

App that I want to deploy in Jenkins

1. This is a simple Node.js App that I would like to deploy in Kubernetes. The code is here:
2. Clone the code and push to your own repo(or fork it)
3. Create a Pipeline Project in Jenkins. In the pipeline section in definition filed select 'Pipeline Script from SCM'. In the SCM field select GIT. In the repository URL, put your git url. In my case it is the URL mentioned above. Keep the Master branch selected. 
4. For Jenkins to understand Docker command you need to install a plugin. Or you can customize dockerfile of Jenkins to put docker installation command. For simplicity I just install, 'kubernetes Plugin'. You can find detail about the Plugin here:

Deploy Application with helm

1. Run helm create command from your code folder. It will create basic helm config to deploy an application Kubernetes. Change the repository to your dockerhub image repository, tag to latest, service type to LoadBalancer, service port to 3000 in values.yaml. And also in your template/deployment.yaml change the containerPort to 3000 as our node application listens port 3000. If you clone my repo these are already there. 
2. To deploy an application using helm you need to run command line, helm upgrade --install Release_name folder-location-where-your-hel-files-arelocated
You can read more on helm official document. But if you don't want to overwhelmed for this for the sake of this practice tutorial just follow this 
3. Create Jenkins Secret with kind username and password with your docker credentials and use the autogenerated ID in the value of registryCredential as shown in environment section of pipeline in Jenkinsfile. This is to push the image to your docker hub after Jenkins build it.
4. For your reference the Jenkinsfile to deploy the application should be,
pipeline {
environment {
registry = "knsakib/simple-node-local-jenkins-kube"
registryCredential = '4ac13e38-8252-49a6-92f1-e2bcd019ade0'
dockerImage = ''
CI = 'true'
agent any
stages {
stage('Building our image') {
steps {
script {
dockerImage = docker.build registry
stage('Push image') {
steps {
script {
docker.withRegistry( '', registryCredential ) {
stage('Deployment') {
steps {
script {
sh """
helm upgrade --install local-kube helm-local-jenkins-kube
// sh """
// kubectl create secret docker-registry IMG_PULL_SECRET \
// --docker-server=https://registry.hub.docker.com --docker-username=${docker-user} \
// --docker-password=${docker-pass} --docker-email=${docker-email}>
// """
// sh """
// helm upgrade --install local-kube \
// --set imagePullSecrets=${IMG_PULL_SECRET} \
// --set image.repository=knsakib/simple-node-local-jenkins-kube helm-local-jenkins-kube
// """
sh "sleep 5"

To know more about how the Jenkinsfile has been written to deploy an app using helm visit these links: https://dzone.com/articles/building-docker-images-to-docker-hub-using-jenkins https://dzone.com/articles/easily-automate-your-cicd-pipeline-with-jenkins-he https://github.com/eldada/jenkins-pipeline-kubernetes/blob/master/Jenkinsfile

4. If needs to use private docker hub, create another set of secrets in Jenkins(text type secrets). For example, I created 3 secrets, docker-user, docker-pass, docker-email. And then create a kubernetes secrets IMG_PULL_SECRET out of those 3 Jenkins secrets. Then use those secrets in the helm command or as suggested here use as helm value in values.yaml (imagePullSecerts in values.yaml). I am exactly sure how I would inject those values in values.yaml. So, I prefer command line argument to push the secrets in the environment. So, basicallt you need to uncomment from line 31 to 41 and comment line 30.   
5. Click the 'Build Now' button in Jenkins to build and deploy docker for desktop kubernetes. Visit http://localhost:3000. You will see your application running. 

Miscellaneous doc to learn the Difference between nodeport, LB and ingress(just wanted to include in this post😃): https://medium.com/google-cloud/kubernetes-nodeport-vs-loadbalancer-vs-ingress-when-should-i-use-what-922f010849e0

Post a Comment