Jenkins & K8S Creating Dynamically Scalable Jenkins Slaves with Docker and Kubernetes

Jenkins & K8S Creating Dynamically Scalable Jenkins Slaves with Docker and Kubernetes

We are going to create a Kubernetes template to run Jenkins pod as master and dynamically createable slaves which is created by Jenkins itself.

Jenkins & K8S : Creating Dynamically Scalable Jenkins Slaves with Docker and Kubernetes

So, first, we are going to create Jenkins master from Kubernetes itself. Then we are going to create the Jenkins template which can be created from Jenkins master’s UI.

To implement the above idea,

we are going to create the following steps to implement the dynamically Scalable Jenkins slaves.

  1. Jenkins Instance service
  2. Jenkins Service Discovery Service
  3. Creating Docker Image with required plugins
  4. Jenkins Deployment
  5. Configuring Jenkins Slaves
  6. Test The configuration — Create Jenkins jobs and run all together

1. Jenkins Instance Service

As discussed, we are going to use Kubernetes to dynamically create a Jenkins instance and provision it on a Jenkins server. To provision Jenkins instance, we need Jenkins Kubernetes service to create Jenkins instance in Kubernetes pods. I have a snippet of code to create a Jenkins instance service in NodePort to route external traffic to the Jenkins server. You can use an ingress or external load balancer to achieve this.

apiVersion: v1
kind: Service
metadata:
  name: jenkins-instance
  namespace: jenkins-instance
spec:
  ports:
    - protocol: TCP
      port: 8080
      targetPort: 8080
      name: master
  selector:
    app: master
  type: NodePort

Create a .yml file for our Jenkins instance service (in our case jenkins-instance-service.yml) and build the service. In this tutorial, I am using kubectl. we do this with orders

kubectl create -f jenkins-instance-service.yml

Output as Below:

service “Jenkins-instance” created

2. Jenkins Service Discovery Service

Next, we are going to create another service for service discovery that will help us route external traffic to our Jenkins-instance cluster. Just like we did for the Jenkins-instance service, we need to create a .yml file for Kubernetes to create the service discovery service. Copy the code and build Jenkins-

apiVersion: v1
kind: Service
metadata:
name: jenkins-service-discovery
namespace: jenkins
spec:
selector:
app: master
ports:
– protocol: TCP
port: 3838
targetPort: 3838
name: slaves

In this, we are defining port 3838 for service discovery ports. Make your network configuration according to that.

Just like Jenkins-instance service, pass the kubectl command to create the service discovery service.

kubectl create -f jenkins-service-discovery-service.yml

With the following output:

service “jenkins-service-discovery” created

Read Also – Spark Cast String Type to Integer Type (int)

3. Create Docker Image with required plugins

To create a Kubernetes cluster, Docker image is very important. So, we are going to create the Docker image and push it to your Docker registry so that we can use it when deploying the application to Kubernetes. Use the below Dockerfile to build a Docker image.

from jenkins/jenkins:ltsCOPY install-plugin.sh /usr/local/bin/install-plugin.sh
RUN /usr/local/bin/install-plugin.sh ssh-slaves
RUN /usr/local/bin/install-plugins.sh kubernetes

Then, from the directory of this Dockerfile, run below docker build command to create the docker image

docker build -t apotitech/Jenkins

Then, push the docker image created docker image by passing below command

docker push <Image ID> apotitech/Jenkins

4. Jenkins-instance Deploymen

Now we need to deploy the Jenkins-instance so that it is available as pods. Then, use the .yml code below to create a Kubernetes deployment script (jenkins-instance-deploy.yml).

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: jenkins-instance
namespace: jenkins-instance
spec:
replicas: 1
template:
metadata:
labels:
app: master
spec:
containers:
– image: apotitech/jenkins
name: jenkins-instance
ports:
– containerPort: 8080
name: jenkins-port
– containerPort: 3838
name: jenkins-sd-port
env:
– name: JAVA_OPTS
value: -Djenkins.install.runSetupWizard=false

To deploy the jenkins-instance, run the below kubectl command.

kubectl create -f jenkins-instance-deploy.yml

Then, this will create the pods and check whether all the pods are up and running by passing following command

kubectl get pods –namespace jenkins-instance

this will throw following output

NAME READY STATUS RESTARTS AGE
jenkins-instance-5ea2b32ace 1/1 Running 0 3m

5. Configuring Jenkins Slaves

Now, We need to configure the Jenkins slaves by configuring in the Jenkins UI itself. Follow the below steps to configure.

Go to Configure System from Manage Jenkins option and select Cloud section

From here, “Add New Cloud” and select “Kubernetes” the enter the required details of Kubernetes.

The, to get the details that need to be filled in Kubernetes form, get it by passing following command

kubectl describe pod –namespace jenkins-slave

Fill the details as mentioned in the below screenshot:

Jenkins & K8S : Creating Dynamically Scalable Jenkins Slaves with Docker and Kubernetes

6. Test The configuration — Create Jenkins jobs and run all together

To test the above configuration, create two tasks and keep it running for some time. Which means, create Jenkins jobs in such a way that both the jobs run at the same time. Then, once the jobs start running, check the pod status by running the following command.

kubectl get pods --namespace jenkins-instance

This should return output something like this

NAME READY STATUS RESTARTS AGE
jenkins-instance-5ea2b32ace 1/1 Running 0 3m
jenkins-slave-245da2c165 2/2 Running 0 1m

This means, Both jobs are running in two different the Jenkins pods and this will be deleted as soon as the jobs are finished running.

Then, All the codes used in this tutorial are available in this Github repo.

Hope you like this blog….

 

Mahesh Wabale
Latest posts by Mahesh Wabale (see all)

Leave a Comment