Jenkins minimal installation on Kubernetes
Installing Jenkins on Kubernetes can be done in different ways. You can use Jenkins official helm chart or directly create resources in Kubernetes. Many times we need only Jenkins without much of the configuration. Let's see how we can install Jenkins on Kubernetes with minimal resources and configuration.
Create Persistent Volume for storage
For storing Jenkins Jobs, configuration files and Jenkins home we need persistent volume so even if pod crashes or restarts we have persisted data. For creating persistent volume we need to create PersistentVolumeClaim which will make sure to allocate said amount of storage.
More on PersistentVolumeClaim
- Modify storageClassName as per your cluster (you can find it in CRDs)
- Modify spec.resources.requests.storage according to your needs minimum required storage is 1Gi
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: jenkins-pvc
namespace: jenkins
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
storageClassName: cinder
PersistentVolumeClaim resource
Create Service Account for Jenkins
For accessing different resources of the cluster we need to have separate service account for Jenkins pod.
More on ServiceAccount
apiVersion: v1
kind: ServiceAccount
metadata:
name: jenkins
namespace: jenkins
ServiceAccount resource
Create ClusterRole
ClusterRole is required to create new cluster role and assign permissions to the same. If you require to spawn Jenkins jobs on Kubernetes cluster then you need to have ClusterRole with below permissions otherwise you can minimize resources access in ClusterRole.
More on ClusterRole and ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
annotations:
rbac.authorization.kubernetes.io/autoupdate: "true"
labels:
kubernetes.io/bootstrapping: rbac-defaults
name: jenkins
rules:
- apiGroups:
- '*'
resources:
- statefulsets
- services
- replicationcontrollers
- replicasets
- podtemplates
- podsecuritypolicies
- pods
- pods/log
- pods/exec
- podpreset
- poddisruptionbudget
- persistentvolumes
- persistentvolumeclaims
- jobs
- endpoints
- deployments
- deployments/scale
- daemonsets
- cronjobs
- configmaps
- namespaces
- events
- secrets
verbs:
- create
- get
- watch
- delete
- list
- patch
- update
- apiGroups:
- ""
resources:
- nodes
verbs:
- get
- list
- watch
- update
Create ClusterRoleBinding
ClusterRoleBinding will bind ClusterRole to created ServiceAccount which will eventually be used while running Jenkins pod.
Pod => ServiceAccount => ClusterRoleBinding => ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
annotations:
rbac.authorization.kubernetes.io/autoupdate: "true"
labels:
kubernetes.io/bootstrapping: rbac-defaults
name: jenkins
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: jenkins
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: Group
name: system:serviceaccounts:jenkins
ClusterRoleBinding resource
Create Jenkins deployment
Deployment is used to run Jenkins pod using all previously created resources like ServiceAccount, PersistentVolume, ClusterRole and ClusterRoleBinding.
More on Deployment
- You can modify image to official image from Jenkins
- We need two ports one for Jenkins UI and other for JNLP agent connector (which will be used to communicate with running node)
apiVersion: apps/v1
kind: Deployment
metadata:
name: jenkins
namespace: jenkins
spec:
replicas: 1
selector:
matchLabels:
app: jenkins
template:
metadata:
labels:
app: jenkins
spec:
containers:
- name: jenkins
image: suhasadhav/jenkins:2.289.2
ports:
- containerPort: 8080
name: http
- containerPort: 32000
protocol: TCP
name: jnlp-api
volumeMounts:
- name: jenkins-home
mountPath: /var/jenkins_home
volumes:
- name: jenkins-home
persistentVolumeClaim:
claimName: jenkins-pvc
serviceAccount: jenkins
securityContext:
fsGroup: 1000
runAsUser: 1000
Jenkins Deployment
Create Jenkins Service
We need networking interface i.e. Service which will eventually connect to underlying Jenkins pod on specified port.
More on Service
- Please note that we need NodePort service as JNLP connection to agent/node cannot be done over HTTP protocol so ingress will not work in case of JNLP.
- You can create Ingress for Jenkins UI separately and also if your cluster networking solution provides reverse proxy then you can create ingress for JNLP as well.
apiVersion: v1
kind: Service
metadata:
name: jenkins
namespace: jenkins
spec:
ports:
- name: http
protocol: TCP
port: 8080
targetPort: 8080
nodePort: 32500
- name: jnlp
protocol: TCP
port: 32000
targetPort: 32000
nodePort: 32000
selector:
app: jenkins
type: NodePort
Jenkins Service
You can find complete resource file to create Jenkins Deployment and all dependent resources here.