by John Turner
Posted on February 15, 2017
Kubernetes, Docker, Jenkins
In Building a Custom Jenkins Docker Image - Part 1 we disabled the Jenkins install wizard and installed the default plugins. In part 2, I want to focus on ensuring the build tools are installed. The target end state of our build infrastructure must include the installation and configuration of:
We can review the official Jenkins image source on the jenkinsci docker GitHub repository to understand which of these tools are already provided for. From the Dockerfile we can see the following:
FROM openjdk:8-jdk
RUN apt-get update && apt-get install -y git curl && rm -rf /var/lib/apt/lists/*
This means that the official Jenkins image is based on the openjdk:8-jdk image (Java 8 JDK is installed) and that the Git client is installed. There is nothing to suggest that Maven is installed and we can verify this by creating a new bash session in the container and listing the installed packages.
$ kubectl exec jenkins-155111175-p72qf -it -- bash
jenkins@jenkins-155111175-p72qf:/$ apt list --installed
Listing... Done
acl/now 2.2.52-2 amd64 [installed,local]
...
lsb-base/now 4.1+Debian13+nmu1 all [installed,local]
mawk/now 1.3.3-17 amd64 [installed,local]
mercurial/now 3.1.2-2+deb8u3 amd64 [installed,local]
mercurial-common/now 3.1.2-2+deb8u3 all [installed,local]
mime-support/now 3.58 all [installed,local]
mount/now 2.25.2-6 amd64 [installed,local]
multiarch-support/now 2.19-18+deb8u7 amd64 [installed,local]
ncurses-base/now 5.9+20140913-1 all [installed,local]
...
zlib1g/now 1:1.2.8.dfsg-2+b1 amd64 [installed,local]
jenkins@jenkins-155111175-p72qf:/$
To install maven we use the Docker RUN statement in the Jenkins/Dockerfile to invoke apt-get install. This requires us first to become the root user and subsequently to resume as the jenkins user.
# install Maven
USER root
RUN apt-get update && apt-get install -y maven
USER jenkins
I can now build a new Docker image:
from jenkins:2.32.2
# install plugins specified in https://github.com/kohsuke/jenkins/blob/master/core/src/main/resources/jenkins/install/platform-plugins.json
# install Organisation and Administration plugins
RUN /usr/local/bin/install-plugins.sh cloudbees-folder
RUN /usr/local/bin/install-plugins.sh antisamy-markup-formatter
# install Build Features plugins
RUN /usr/local/bin/install-plugins.sh build-timeout
RUN /usr/local/bin/install-plugins.sh credentials-binding
RUN /usr/local/bin/install-plugins.sh timestamper
RUN /usr/local/bin/install-plugins.sh ws-cleanup
# install Build Tools plugins
RUN /usr/local/bin/install-plugins.sh ant
RUN /usr/local/bin/install-plugins.sh gradle
# install Pipelines and Continuous Delivery plugins
RUN /usr/local/bin/install-plugins.sh workflow-aggregator:2.0
RUN /usr/local/bin/install-plugins.sh github-organization-folder:1.6
RUN /usr/local/bin/install-plugins.sh pipeline-stage-view:2.0
# install Source Code Management plugins
RUN /usr/local/bin/install-plugins.sh git
RUN /usr/local/bin/install-plugins.sh subversion
# install Distributed Builds plugins
RUN /usr/local/bin/install-plugins.sh ssh-slaves
# install User Management and Security plugins
RUN /usr/local/bin/install-plugins.sh matrix-auth
RUN /usr/local/bin/install-plugins.sh pam-auth
RUN /usr/local/bin/install-plugins.sh ldap
# install Notifications and Publishing plugins
RUN /usr/local/bin/install-plugins.sh email-ext
RUN /usr/local/bin/install-plugins.sh mailer
# install Maven
USER root
RUN apt-get update && apt-get install -y maven
USER jenkins
docker build -t monkeylittle/jenkins:1.1.0 .
Note that I have changed the version tag.
As this is a personal exercise in learning about Kubernetes and Docker, I attempted to perform a rolling update of the deployment but this required using hostPath persistent volumes. Minikube does not yet support running containers with non root users and hostPath volumes (which are provisioned by root user). See this guthub pull request for more information.
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: jenkins
spec:
replicas: 1
template:
metadata:
labels:
app: jenkins
spec:
containers:
- name: jenkins
image: monkeylittle/jenkins:1.1.0
env:
- name: JAVA_OPTS
value: -Djenkins.install.runSetupWizard=false
ports:
- name: http-port
containerPort: 8080
- name: jnlp-port
containerPort: 50000
volumeMounts:
- name: jenkins-home
mountPath: /var/jenkins_home
volumes:
- name: jenkins-home
emptyDir: {}
Then recreate the pod.
$ kubectl apply -f deployment.yaml
deployment "jenkins" configured
It’s possible to verify the update by describing the pod:
$ kubectl describe pod | grep Image:
Image: monkeylittle/jenkins:1.1.0
To validate that maven is now installed within the container I can create a new bash session in the container and run apt list –installed.
$ kubectl exec jenkins-258199304-4jf60 -it -- bash
jenkins@jenkins-258199304-4jf60:/$ apt list --installed | grep maven
WARNING: apt does not have a stable CLI interface yet. Use with caution in scripts.
libmaven-parent-java/stable,now 21-2 all [installed,automatic]
libmaven-scm-java/stable,now 1.3-5 all [installed,automatic]
libmaven2-core-java/stable,now 2.2.1-17 all [installed,automatic]
maven/stable,now 3.0.5-3 all [installed]
You can also go ahead and create a build job via the Jenkins UI for one of your Java maven projects (i used this one). A couple of things that I skipped over:
Those are a few follow up tasks I’ll get to over the next couple of weeks.