This is not actually my kitchen sink by the way.
If you followed my last guide to spin up Jenkins in a brand new Google Kubernetes Engine cluster, you’re now probably itching to do something useful with it. The final goal will be to create a pipeline in Jenkins that manages our Terraform infrastructure, but before we get to that we’ll need to quickly pop through the looking glass into the world of custom Docker images.
If you’re not familiar with Jenkins (oh, you lucky soul), it is an automation server that relies on agents to run jobs or complete tasks. These agents can be processes on the master server itself, or more traditionally they are separate standalone machines. Helpfully, the Helm chart we used to install Jenkins to our GKE cluster also set up the Kubernetes plugin for us. This plugin allows Jenkins to spin up agents as short-lived Kubernetes deployments inside the same cluster, so we don’t actually have to configure any agent machines or worry about managing them.
By default Jenkins images will use the jenkins/jnlp-slave docker image. Will this image contain the tools necessary for us to complete the tasks in our pipeline? Probably not. However with Docker it’s easy to inherit an image and build your own custom version of it.
The Custom Image
Create a new directory on your local machine and grab the jenkins-agent script that the original image uses. Save it in your new directory, then create the following
As you can see, we build on an existing image from Jenkins, then add the tools we want: Docker, Kubectl, Terraform and the GCloud SDK.
Let’s build our custom image:
docker build -t my-custom-agent .
You should now have a custom Jenkins agent docker image ready to go. We can push it to Docker Hub, or Google Container Registry, and update our Jenkins Helm deployment to use this image for agent deployments. But wait:
Is this how I parking?
We’re Doing It Wrong
There is a better way. Creating a kitchen-sink Jenkins agent may be fine for experimenting with pipelines when you need every tool at your disposal quickly, but it’s actually an anti-pattern. Why?
- Containers should be as lightweight as possible
- Isolating tools allows you to manage them separately
- Pipelines can use multiple containers inside the same pod
The last point there is worth restating: You can define multiple containers within the same pipeline to carry out the various tasks and stages.
Thanks to the way the Kubernetes plugin works, each container will share the Jenkins home directory (in other words, the workspace of the pipeline) as they all exist within the same pod in your Kubernetes cluster.
In the next part of this series we’ll create our Terraform pipeline, and use-off-the shelf lightweight containers to run each specific stage. In the meantime, I hope my experience of learning to build a custom agent and then discovering why I shouldn’t use it was helpful to you!