Documents things related to running Jenkins locally for testing of stuff / development.
We can run Jenkins locally to test out functionality related to Jenkins such as jobs/plugins or develop with Jenkins shared library instead of testing them on the actual deployed Jenkins.
The run.sh script makes use of the .env file and a .tmpl file to substitute values using envsubst generating a .yaml file, the final output which is the .yaml file is then used as a value file to helm.
Configure your local development environment.
Assumes deploying to minikube
using the VirtualBox driver
helm v3 CLI installed
envsubst installed
kubectl installed
kubernetes-chart git repository cloned
In your terminal, change to the kubernetes-charts/charts/jenkins folder
Create a .env file with the following content, see table below for an explanation of the properties:
Get your personal access token:https://docs.github.com/en/github/authenticating-to-github/creating-a-personal-access-token
1
GITHUB_TOKEN_JENKINS_EXCHANGE=<GITHUB PERSONAL ACCESS TOKEN>;
2
NAMESPACE=jenkins-test;
Run the run-local.sh script, run-local.sh local
Make sure minikube is running with enough memory allocation.
1
minikube start --memory=8g
runs of run-local.sh is idempotent, it will do a refresh reinstall, by deleting the helm release, and the PVC.
it also always switches your kubectl context to minikube
Check the namespace you installed to for the status of Jenkins pod to be ready:
kubectl get po -n jenkins-test
The installation can take up to 10 mins
When it is ready, we can access Jenkins by port-forwarding to the minikube port:
1
export POD_NAME=$(kubectl get pods --namespace jenkins-test -l "app.kubernetes.io/component=jenkins-master" -l "app.kubernetes.io/instance=jenkins" -o jsonpath="{.items[0].metadata.name}")
2
kubectl --namespace jenkins-test port-forward $POD_NAME 8080:8080
Access http://localhost:8080 with the following credentials:
Username: admin
Password: admin
.env file properties:
Key
Default Value
Description
GITHUB_TOKEN_JENKINS_EXCHANGE
to be filled
This is your personal Github token, this is used to create a Jenkins credential that will be used to access Github repositories
It is important to take note that the token is not checked-into git, as such the generated local.yaml file with the token is added to .gitignore
NAMESPACE
jenkins-test
The namespace where to deploy Jenkins, the value is also used in some parts of the Jenkins configuration, and in subsequent commands.
Jenkins jobs are essentially .xml files, we can retrieve these files by doing the following:
Going to the Jenkins home folder and copying the .xml file
adding /config.xml at the end of a job URL, to retrieve the .xml job config
The job config.xml can then be appended to the helm value for the job to be persisted on subsequent runs. See local.tmpl master.jobs section
The following test job will perform the following:
Pull dockerhub image alpine/git
test capability to pull images from the internet
Run commands in the container
test capability to run commands in the correct container
test capability to spin up a ephermeral container agent
Run the pipelinePrepare() function from jenkins-global-libraries and fail
This stage’s failure is to be expected.
test capability to use the global library
Create the test job through Jenkins UI New Item → Enter a job name → Pipeline → Scroll down to the Script textfield and copy paste the below:
1
@Library('jenkins-global-libraries') _
2
pipeline {
3
agent {
4
kubernetes {
5
yaml '''
6
apiVersion: v1
7
kind: Pod
8
spec:
9
containers:
10
- name: shell
11
image: alpine/git:v2.26.2
12
command:
13
- sleep
14
args:
15
- infinity
16
'''
17
defaultContainer 'shell'
18
}
19
}
20
stages {
21
stage('Test') {
22
steps {
23
sh 'hostname'
24
sh 'env'
25
}
26
}
27
stage('Test global library') {
28
environment {
29
PROJECT_NAME = 'local'
30
}
31
steps {
32
pipelinePrepare()
33
}
34
}
35
}
36
}
Using the filescm plugin, we can load a Jenkins shared library that is mounted to minikube from our local workstation, this allows us to test our locally developed shared library instead of pushing it to a remote Git repository.
This is done from the following block:
1
persistence:
2
volumes:
3
- name: source-code
4
hostPath:
5
path: /Users
6
mounts:
7
- mountPath: /Users
8
name: source-code
We mounted our host /Users directory to the pod, assuming our Jenkins shared library source codes are at /Users/mylib we can create a global Jenkins shared library under Manage Jenkins and use the FileSCM option to refer to /Users/mylib
We can test private repositories(AWS ECR) images by downloading them into the minikube docker daemon.
First, we mount the minikube docker daemon
1
eval $(minikube -p minikube docker-env)
2. Then we proceed to retrieve the required images, which will download them into the mounted minikube docker daemon:
3. In our Jenkins kubernetes agent, inorder to use the newly downloaded docker image , we need something like:
1
agent {
2
kubernetes {
3
defaultContainer 'diginex-cli'
4
yaml """
5
apiVersion: v1
6
kind: Pod
7
...
8
- name: diginex-cli
9
image: 929981421241.dkr.ecr.ap-southeast-1.amazonaws.com/diginex-cli:latest
10
imagePullPolicy: Never
11
...
12
"""
13
}
Note the imagePullPolicy:Never , this is important so that kubernetes will not attempt to reach out to the internet, and will instead use what is available.
4. Finally, when we are done we can unmount to ensure we are using our own docker daemon:
1
eval $(minikube -p minikube docker-env -u)