In this tutorial, we will do a very basic setup to build and publish Docker Image to an external Docker Registry with Jenkins Agent running on Openshift. We will use this Maven project as the example here.
Thus, you are expected to have basic knowledge of Jenkins, Openshift, and Docker as well as Maven to be able to follow up with this tutorial.
At the end of this tutorial, our pipeline will be able to do the below:
- Spin up a Jenkins Slave pod on Openshift
- Check out the target Maven project inside the Jenkins Slave pod and execute the maven install command
- Trigger Openshift Build from the Jenkins Slave pod to build the image with the provided Dockerfile inside the sample project. Besides, this also helps to push the image to an external Docker Registry
Prerequisite
Make sure the Jenkins server is accessible from the Openshift cluster and vice versa.
Get Openshift Ready
- Create your
ci-test
namespace:
oc new-project ci-test
2. Create a service account called jenkins
and give it the necessary permissions
oc create serviceaccount jenkinsoc adm policy add-cluster-role-to-user edit -z jenkinsoc adm policy add-scc-to-user anyuid -z jenkins
3. Print out and store the service account token for later use
oc serviceaccounts get-token jenkins -n ci-test
4. Since we want to push our image to an external Docker registry, we need a Secret
to store the credential to access the target Docker registry
oc create secret generic secret-2-docker --from-file=.dockerconfigjson=<path-to-your-dockerconfigjson> --type=kubernetes.io/dockerconfigjson
Whereas, the content of .dockerconfigjson
is as below (I used Gitlab in this case):
{
"auths": {
"registry.gitlab.com": {
"username": "<username>",
"password": "<password/token>",
"email": "<email>"
}
}
}
5. Create a BuildConfig
type binary
which will use the above secret:
oc new-build --name build-with-docker --binary --strategy docker --to-docker=true --to=<image repository> --push-secret=secret-2-docker
Now our namespace has everything ready.
Connect Jenkins to Openshift
We need to install Kubernetes Plugin for Jenkins before being able to connect to Openshift.
1. Add new Kubernetes configuration for Jenkins
Go to Manage Jenkins -> Manage Nodes and Clouds -> Configure Clouds
Kubernetes URL is the URL of our Openshift. It should be the same value as the one we used for login from the oc login
command
For simplicity, we will disable the certificate check in this tutorial.
2. Add Credentials
Click the Add button to add new Credentials
Choose Kind -> Secret text and paste the token we get from the previous section into the Secret field
Now, click the button Test Connection to ensure our Jenkins can connect to Openshift with the provided credential:
3. Add Pod Template
Click Add Pod Template and fill in the required information as below to config the Pod where the Jenkins agent will run later
We also need to specify the service account jenkins
to use for this pod
4. Add Containers
We will use the Maven project in this tutorial, so we need a Maven container inside our Pod.
We will use registry.hub.docker.com/adoptopenjdk/maven-openjdk11 image for the Maven container.
Additionally, we will also need a oc
container to trigger build to Openshift. The image that will be used here is registry.hub.docker.com/ebits/openshift-client
Now we are ready to create our Pipeline.
Create Jenkins Pipeline
Let’s have a look at our sample project structure first
This is a pretty simple Maven project. Please be noticed that our Dockerfile is located inside thesample-web
folder.
Now, let’s do the below:
- Create new Pipeline with name jenkins-openshift-test-pipeline
2. Use the below pipeline script for your build
pipeline {
agent {
kubernetes {
cloud 'openshift-test' #1
inheritFrom 'jenkins-agent' #2
}
}
stages {
stage('Checkout') {
steps {
git 'https://gitlab.com/linhvomedium/cicd/spring-boot-rest-api.git' #3
}
}
stage('Build') {
steps{
container('maven') {
sh "mvn -f sample-web/pom.xml clean install" #4
}
}
}
stage('Publish Image') {
steps{
container('oc') {
sh "oc start-build build-with-docker --from-dir sample-web" #5
}
}
}
}
}
#1: the name of our Cloud Config in the previous step
#2: the name of the pod template within that Cloud Config
#3: check out the target project
#4: run maven command
#5: trigger the Openshift build and point to the sample-web
folder where Dockerfile is located
Thus, our build is pretty simple with 3 stages:
- Checkout: checkout the project from the Git repository
- Build: build the project inside
maven
container - Publish Image: trigger the Openshift Build, which will also push the resulting image to the Docker registry, inside
oc
container
Time to build our pipeline
Let’s trigger the newly created Jenkins job
When the build is running, try to list all the pods on the namespace ci-test
oc get pods
We will see a new pod is created with 3 containers:
Let’s get more detail of this pod:
oc describe pod/jenkins-openshift-test-pipeline-10-k9n67-38hpk-1x66w
As the above result, we can see that there are 3 containers running inside the pod:
maven
andoc
: are configurated in our Container template earlierjnlp
: is the Jenkins agent container.
You can change this container spec by specifying a container with the same name in the Container template of our target Cloud Config
When the job completes, we can see one new build
has been triggered:
oc get build
Now, a new docker image should have been published to the target Docker Registry:
That’s it!