Deployment on Kubernetes through Jenkins Dynamic Cluster

Deployment on Kubernetes through Jenkins Dynamic Cluster

Jenkins Job Cluster

For managing and running jobs in Jenkins, in real world instead of a Standalone Master we use Cluster of Nodes including Master and Slave nodes and since this cluster is meant for building jobs, hence it is called Jenkins Job Cluster. The reasons why we need a Jenkins Cluster are ---

  • It increases resources and we can run more jobs in parallel
  • Job can be run in a distributed architecture i.e., running a job is not constrained in the master node OS or environment and since different jobs demand their own environment for running we can distribute jobs in different slaves with those particular environment.
  • Master load decreases and hence after an upgrade or crash Jenkins can be load faster.
No alt text provided for this image

Slave Provisioning 

Jenkins slave nodes can be provisioned in two ways ---

  • Static Provision – In this method slave nodes are provisioned before hand even if master does not need them at that point of time.
  • Dynamic Provision – In this method slave nodes are provisioned on-demand i.e., whenever we require that particular environment we launch the slave node, run job on top of it, after job run terminate the slave. It saves a lot of resources.

In this task we will deploy our website on top of kubernetes through Dynamic Jenkins Cluster.

Task Overview :

Create A dynamic Jenkins cluster and perform task-3 using the dynamic Jenkins cluster. Steps to proceed as:

  1. Create container image that’s has Linux and other basic configuration required to run Slave for Jenkins. ( example here we require kubectl to be configured )
  2. When we launch the job it should automatically starts job on slave based on the label provided for dynamic approach.
  3. Create a job chain of job1 & job2 using build pipeline plugin in Jenkins 
  4. Job1 : Pull the Github repo automatically when some developers push repo to Github and perform the following operations as:
  • Create the new image dynamically for the application and copy the application code into that corresponding docker image
  • Push that image to the docker hub (Public repository) ( Github code contain the application code and Dockerfile to create a new image )

5. Job2 ( Should be run on the dynamic slave of Jenkins configured with Kubernetes kubectl command): Launch the application on the top of Kubernetes cluster performing following operations:

  • If launching first time then create a deployment of the pod using the image created in the previous job. Else if deployment already exists then do rollout of the existing pod making zero downtime for the user.
  • If Application created first time, then Expose the application. Else don’t expose it.

Task Description :

Setup :

No alt text provided for this image

Cluster Configuration :

I will be using the above setup for launching a dynamic Slave Node having kubectl configured in it for Jenkins. For this ---

  1. On Docker Host System we have to enable TCP support to the Docker Server program as it is not enabled by default
No alt text provided for this image

then we have to run a couple of commands to reload internal Dtabase and restart service

# systemctl daemon-reload
# systemctl restart docker

2. Now on the Jenkins server only docker client program should be installed

# systemctl stop docker

and to update the Docker Host information

# export DOCKER_HOST=<ip of docker host system:4243>

3. The Dockerfile for the image from which we will launch the slave having kubectl

FROM centos:latest


RUN yum install sudo -y
RUN yum update -qy
RUN yum install git -y
# Installing SSH Server
RUN yum install openssh-server -y
RUN mkdir -p /var/run/sshd
# Installing JDK
RUN yum install java-11-openjdk-devel  -y


#Creating jenkins user
RUN useradd jenkins
RUN echo "jenkins:jenkins" | chpasswd
RUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g'  -i  /etc/pam.d/sshd
RUN mkdir /home/jenkins/.m2
RUN echo "jenkins ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/jenkins
RUN chmod 0440 /etc/sudoers.d/jenkins
RUN ssh-keygen -A
ENV NOTVISIBLE "in users profile"
RUN echo "export VISIBLE=now" >> /etc/profile
RUN rm /run/nologin
RUN chown -R jenkins:jenkins /home/jenkins/.m2


# kubectl setup
RUN curl -LO https://storage.googleapis.com/kubernetes-release/release/`curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt`/bin/linux/amd64/kubectl  &&  chmod +x kubectl  &&  mv kubectl /usr/bin/
WORKDIR /home/jenkins
COPY ca.crt  /home/jenkins
COPY client.key  /home/jenkins
COPY client.crt  /home/jenkins
COPY  myinfo /root/.kube/config


RUN sudo chown -R jenkins /root/.kube

EXPOSE 22
CMD ["/usr/sbin/sshd","-D"]

4. Setting up Dynamic Slave Node in Jenkins

No alt text provided for this image
No alt text provided for this image
No alt text provided for this image

Jobs In Jenkins :

Job 1

It is run on the Master Node and it does the followings ---

  • Pulls the Github code whenever developer pushes
  • creates the application image
  • pushes it back to Docker hub
No alt text provided for this image
No alt text provided for this image
No alt text provided for this image

Job 2 :

It is run on the Dynamic Slave and does the followingd ---

  • Creates a Deployment on top of K8s
  • Exposes it and makes its volume Persistent
No alt text provided for this image
No alt text provided for this image
No alt text provided for this image

The YAML Code for creating this deployment is ---

---
apiVersion: v1
kind: Service
metadata:
  name: webapp
  labels:
    app: webapp
spec:
  selector:
    app: webapp
    env: prod
  type: NodePort
  ports:
    - port: 80
      targetPort: 80
      nodePort: 30000
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
    name: web-pv-claim
    labels:
        app: webapp
        env: prod
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 200Mi


---
apiVersion: apps/v1 
kind: Deployment
metadata:
  name: webapp
  labels:
    app: webapp
spec:
  selector:
    matchLabels:
      app: webapp
      env: prod
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: webapp
        env: prod
    spec:
      containers:
      - image: disha1822/my-apache2:v4
        name: webapp
        ports:
        - containerPort: 80
          name: webapp
        volumeMounts:
        - name: webapp-persistent-storage
          mountPath: /var/log/httpd
      volumes:
      - name: webapp-persistent-storage
        persistentVolumeClaim:
          claimName: web-pv-claim

Pipeline Looks Like :

No alt text provided for this image

After Deployment the Webpage Looks Like :

No alt text provided for this image

Conclusion :

We have configured a Dynamic slave in Jenkins that will launch a Deployment using kubectl hence this slave image needs kubectl configured in it. In this way we can create multiple images for different environment that we need to run different jobs.

Thank you!!





vijay garg

GIET Kota Rajasthan

4 年

Supper...

回复

要查看或添加评论,请登录

DISHA BHATTACHARYA的更多文章

社区洞察

其他会员也浏览了