Automating a Custom Jenkins in OpenShift 3.x with Your Plugins and Your Configuration
Jenkins comes inside OpenShift as a container and Jenkins Slave containers within the “openshift” namespace. This is plain vanilla Jenkins however. To customize it you have to log in, add plugins, setup configuration, and get it how you want for each Jenkins container in each project namespace! Unless you automate having a custom Jenkins with all that stuff setup already! I love automating non-value-added things and this is one of them. Let’s get started.
How Jenkins works within OpenShift
If your project template includes a Jenkinsfile like mine does here then when you apply a template and create your project in OpenShift the Jenkins image (:latest) inside the openshift namespace (Builds → Images) is used to create a Jenkins application for your project. The URL will be something like https://jenkins-namespace.root-url-of-openshift/. When all the pieces are deployed and running you can click on the Jenkins link in your Overview page and it will open a new browser window allowing you to log into Jenkins using your OpenShift login. It is really that easy. Then you can use Jenkins like you know and love!
How you can make Jenkins customized for YOUR projects easily
Now if you are like me then you ALWAYS, ALWAYS, ALWAYS have some kind of customization or added plugin you want and need in your Jenkins setup. Thankfully Red Hat documented that information here however it was a little cryptic for me to read until I got into it and tried a few things. So I am putting it here so you don’t have to and you can get this done, automate it, and move on to value-added work. You have to have a repo (I use GitHub) with a specific format and then add an ImageStream and BuildConfig to your OpenShift platform to set it in motion. The steps are below with screenshots.
I have a GH repo here that you can read from, clone, or fork to get your custom Jenkins setup how you wish. Mine has a few plugins included in the plugins.txt for SonarQube, Slack, Logins, and the like. You can easily add more by looking up the Jenkins plugin source and seeing the name in the pom.xml file for the source. OR you can add the plugin to your current Jenkins, then go into the Jenkins pod listed under your project’s Applications → Pods in your project and click the Terminal tab. Do an ls /var/lib/jenkins/plugins ( that is the EL ESS listing Linux command) command and find the name of the new plugin. Then just include that name (minus the .jpi) in the plugins.txt with “:latest” as the version and rebuild your custom Jenkins image!
The structure of the repo you have to point to for this process is basically like this:
- A plugins directory containing specific plugin binary objects you wish. I only did this with plugins that I received from paid-software-subscriptions that I cannot get out on GitHub or GitLab and the like.
- A plugins.txt file that has a list of plugins to install outside of the generic ones in the format of “plugin-name:pluginVersion”. I always use “latest” for my pluginVersion as you can see from my file in my GH repo.
- A configuration/jobs directory with job definitions if you have them. I did not include any.
- A configuration/config.xml file for custom configuration. I did not include this either for now.
- Any other files from the configuration directory in Jenkins you wish to copy in, i.e. credentials.xml
For my public repo I only used the plugins.txt file entries to start out but do as you see fit. I also have extra stuff in that repo like the Config Maps that I reference in another blog around here somewhere.
Building the Custom Jenkins Image and Using It
So now you have the Jenkins setup you wish with the right plugins. So you have to first build an image stream to publish the image to. And then you have to create a build for that image stream. Or basically apply the 2 files I have for you and explain below.
First things first: the Image Stream definition. It is quite simple actually and is below. There is really only 2 things to check. The name field is the name of the image you want to build. And the namespace is what namespace you will build it in. I chose “openshift” because every project can read from there by default. However, you must have access to do this or it fails. Or you need your SRE/Platform admin to do it for you once she allows it.
Next you have to create the BuildConfig which again I already made and linked in the repo above. This build configuration is again quite simple. There are a few things to point out like the git URL for my repo, the branch from the “ref” section, and then the output →to →name which is the name that should match the above Image Stream. If you change things, make sure all this matches. If you put it into a git repo that requires a login/pwd then just adjust with a secret and the same thing works.
Now you have to actually build it! Go into the namespace where you put the build and the image stream, find the build, and click the Start Build button on the Build Config screen. Let it build and finish completely. Then go into your project, click on the Jenkins deployment configuration, and choose the Actions → Edit button menu on the far right. Under “Images” find the namespace, image, and tag that you just build above and click the Save button at the bottom. Your new Jenkins configuration will setup and deploy and increase your deployment number. You can watch it happen on your Overview page. Give it some time to bring up the new image the first go around.
When it is up and running you are good! Click on the Jenkins URL, log in with your OpenShift credentials (or other login if you applied a custom config.xml!) and verify the plugins and setup under the Manage Jenkins listings. Not too bad once you understand it and run through it. Now you have to make some decisions. Namely, what to call the new image(s), what plugins, how many configurations, and where to put the new Jenkins image(s) you are creating. Let’s talk out some ideas below on that.
Possible Scenarios for Custom Jenkins in OpenShift
- You could have every single plugin you need for your organization or OpenShift platform in the jenkins:latest image in the openshift namespace and call it a day. That is quick and easy and just works. If/when you update to the next version I am not sure how well that will treat you but you have to try and then find out.
- You could leave the jenkins:latest alone and then have a different tag like jenkins:companyname that you pull into your deployment templates for your projects that need the “company compliant” Jenkins under configuration management.
- You could have a custom Jenkins image with a custom name (or names) that has pre-built Jenkins plugins and configuration that match the Config Maps for your Jenkins Slave Agent images and let people pick the one they need. I would guardrail this and structure it or you will have n+1 for every n projects you make. Developers love to believe their setup is the only one and is custom only to them! (Trust me. I Are One.)
- You could let your users create their own in their own namespace/project and give them the tools to do so if you wish to let them control their own destiny.
- Others that you are now thinking of…
I have another few blog posts here around this, one on Config Maps and an additional GH repo to show you how you can have custom Jenkins Slave images for things like SonarQube Scanner and such. You basically add the image stream in the openshift namespace, then create a BuildConfig to pull a Dockerfile script and make your image to push to the image stream. Then your Config Map takes over when you run Jenkins! They are worth checking out. It can save you about 10–15 minutes each time you setup a project.