Automatic Scaling Jenkins Pods on Kubernetes
Introduction
Jenkins is one of the most popular CI/CD tools for many companies nowadays, but it doesn’t scale out of the box. One could simply add more nodes and connect them with the Master Jenkins node, but that would consume extra infrastructure resources with all the negatives that come with it. In this tutorial, you will learn how to configure Kubernetes and Jenkins, to dynamically provision Jenkins slaves as Kubernetes Pods while executing a pipeline job! After the job is finished, the pods will simply die freeing any resources they were consuming during job execution time.
Essentials
- A running Kubernetes Cluster. Follow How to install a Kubernetes Cluster to deploy one.
- A Running Jenkins Master. Refer to Jenkins installation on Kubernetes guide for instructions.
Step 1 – Jenkins Kubernetes plugin Installation
To make Jenkins communicate with Kubernetes API successfully, we need to install 2 plugins:
After you log in to Jenkins user interface, navigate to Manage Jenkins – > Manage Plugins -> Available, and filter the results by typing “Kubernetes plugin” and “Kubernetes Client API Plugin”
It would be a good idea also to install the Kubernetes CLI Plugin because it allows us to execute kubectl commands from within your pipeline. (optional)
Step 2 – Plugin Configuration
Now that the essential plugins are installed, you will have to follow the steps below:
- Go to Manage Jenkins – > Manage Nodes and Clouds -> Configure Clouds
- You will see a Drop Down menu named “Add New Cloud“. Click on it and choose “Kubernetes“
- Click on Kubernetes Cloud details
- Fill out plugin values
- Name: kubernetes
- Kubernetes URL: https://kubernetes.default
- Kubernetes Namespace: jenkins
- Credentials -> Add -> Jenkins (Choose Kubernetes service account option & Global + Save)
- Test Connection. It should be successful even without credentials since our Jenkins Master already uses the “jenkins” service account in the “jenkins” namespace and all permissions have been taking care of since the initial Jenkins installation stage.
- Jenkins URL: http://jenkins:8080
- Tunnel: jenkins:50000 (without the HTTP portion)
- Apply cap only on alive pods : yes!
- Add Kubernetes Pod Template
- Name: jenkins-slave
- Namespace: jenkins
- Labels: jenkins-slave (you will need to use this label on all jobs)
- Containers > Add Template
- Name: jnlp
- Docker Image: admintuts/jnlp-agent-docker:alpine
- Workin Directory: /home/jenkins/agent
- Command to run :
- Arguments to pass to the command:
- Allocate pseudo-TTY: yes
- Add Volume
- HostPath Volume
- HostPath: /var/run/docker.sock
- Mount Path: /var/run/docker.sock
- Timeout in seconds for Jenkins connection: 300
- Service Account: jenkins
- Save
That’s all the configuration needed. Now you will create a Jenkins pipeline to test everything.
Step 3 – Test Jenkins Slave Agent
Now it’s time to see our work finally taking shape.
- Create a new freestyle project with the name Test Slave Agent and hit OK.
- Click on Build Environment – > Build -> Add Build Step -> Execute Shell
- Paste the code:
Now click Save, and then Build Now.
Verifying the Slave Agent Pod is Running on Kubernetes
This is what you will see when you click on Build now:
- (pending—‘Jenkins’ is reserved for jobs with matching label expression)
- A loading indicator that confirms the job is running on a Kubernetes slave pod.
This can be also confirmed by executing:
Where we shall see:
The jenkins-0 pod is the Jenkins Master, and jenkins-slave-pccvz our dynamically spawned slave pod.
Now let’s check how jenkins master is handling the slave operations. Run the command:
Output:
The most important aspects of the log above are:
jenkins-slave-pccvz provisioning successfully completed. We have now 2 computer(s)
Accepted JNLP4-connect connection #8 from /10.244.1.84:57544
If a JNLP4 connection won’t take place, the slave pod will never be able to accept the job since it will not be able to accept job requests from the master. (useful for debugging issues)