How to use Docker containers as build agents(Nodes) in Jenkins
If you install Jenkins for the first time, you will notice that you get a message at the top mentioning that you need to enable Nodes for security purposes.
In my previous builds of Jenkins, these have always been separate VM's running their own OS etc. Recently I have made the move over to Docker, and instead, I want to host the entire stack in Docker.
This guide will show you have to create Docker Jenkins agents to use as nodes. These nodes will spin up and down in docker as required.
Before you start, this guide assumes that the following is up and running in the first place.
- Jenkins Master - mine is running in Docker
Docker Plugin for Jenkinsis installed
- a Docker Host setup and running
- a test build job
Installing the Docker Plugin
We need to install the Docker plugin so that can have Jenkins spin up and down as many hosts as it needs, based on the number of build jobs running. The Docker plugin enabled the Jenkins master server to do this.
- Go to Manage Jenkins, then click on Manage Plugins.
2. Go to Available and search Docker in the search box. Select Docker and click on Install without restart.
3. Once installed restart Jenkins Master server. In my case, it's just a simple docker-compose down && docker-compose up -d.
Build Image for Docker Agent
Next, we need to create an image that implements a couple of prerequisites, SSHD and Java.
SSHD Config File
We need to create a config file for the Dockerfile which we will use shortly. Create a new file called sshd_config. Inside this file copy the following;
Port 22 Protocol 2 HostKey /etc/ssh/ssh_host_rsa_key HostKey /etc/ssh/ssh_host_dsa_key HostKey /etc/ssh/ssh_host_ecdsa_key HostKey /etc/ssh/ssh_host_ed25519_key LoginGraceTime 120 PermitRootLogin yes PubkeyAuthentication yes UsePAM yes
Next, we need to create a simple Dockerfile that will facilitate our Jenkins agent. Each time Jenkins Master server goes running a build job, it will grab this docker image and spin up another container to run it and then stop and remove it once it's finished.
Create a new file called Dockerfile and copy the following into the file;
FROM ubuntu RUN mkdir -p /var/run/sshd RUN apt -y update RUN apt install -y openjdk-8-jdk RUN apt install -y openssh-server RUN ssh-keygen -A ADD ./sshd_config /etc/ssh/sshd_config RUN echo root:mysecretpassword | chpasswd CMD ["/usr/sbin/sshd", "-D"]
The below example builds upon the above Dockerfile but also includes PowerShell and Git.
FROM ubuntu RUN mkdir -p /var/run/sshd RUN apt -y update RUN apt install -y openjdk-8-jdk RUN apt install -y openssh-server RUN apt install -y git wget apt-transport-https software-properties-common RUN wget -q https://packages.microsoft.com/config/ubuntu/20.04/packages-microsoft-prod.deb RUN dpkg -i packages-microsoft-prod.deb RUN apt -y update RUN add-apt-repository universe RUN apt install -y powershell RUN ssh-keygen -A ADD ./sshd_config /etc/ssh/sshd_config RUN echo root:mysecretpassword | chpasswd CMD ["/usr/sbin/sshd", "-D"]
This dockerfile does a number of things like installs Java and the OpenSSH-Server aptitude packages but also set the root password. Ideally, you could implement a secret here.
Build the Docker Agent image
We will need to run the following docker command to build the image.
docker image build --no-cache -t docker-agent .
We can also test the image after a successful build by running the following command;
docker run -d -ti -p 43498:22 docker-agent:latest
Finally, do a quick test to see if you can ssh into the container now using root as your username and the password you set.
ssh root@localhost -p 43498
If you can successfully do those things, you can move onto the next section.
Configure Jenkins Docker Agent
- Inside Jenkins, click on Manage Jenkins, Configuration, and click on Configure Clouds.
2. Next we need to connect Docker. Click on Add a new cloud and select Docker.
3. Give it a name, I gave mine Jenkins Agent.
4. Click on Click on Docker Cloud details...
Configure the following values:
|Docker Host URI||tcp://IP-of-Docker-Host:2375|
|▢ Enabled||Tick ▣ Enabled|
|Expose DOCKER_HOST||Tick ▣|
Adjust your container cap based on the number of build jobs you are running. I'm not a very heavy user of Jenkins yet, so 4 containers should be more than enough.
Lastly, before we move on to the next part, we need to validate that we can communicate to the docker host. Click on Test Connection and make sure that it returns a version number.
Docker Agent Template
Next, we need to set the parameters on how Jenkins interacts with Docker and creates the agents.
Click on Docker Agent templates...
Copy the following values;
|Remote File System Root||/root/jenkins|
|Connect Method||Connect with SSH - Add your root credentials to Jenkins from the Dockerfile here.|
Node Properties / Tool Locations / Docker Agent templates
Click on Save and that's it. You should be up and running.
For use to test this out, we need to do one more thing to our test build job. Open up the Configure page of the test build, and make sure to select the following;
Setting this, make Jenkins only use the docker agent to build this job.