Persistent Jenkins using Longhorn in Kubernetes

CI/CD consist of automation, there are so many tools that can be used to automate this process. One of them is Jenkins, in this article, I will show how to deploy Jenkins in kubernetes using persistent disk with Longhorn.

Below are the task that we will do to deploy jenkins persistent disk in kubernetes:

  • Create persistent volume yaml.
  • Create persistent volume claim yaml.
  • Create service account yaml.
  • Create deployment yaml.
  • Create service yaml.
  • Create ingress yaml.
  • Deploy the configuration.

Create persistent volume yaml

First, we need to create a folder called jenkins and then create this pv.yaml inside that folder:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: jenkins-pv
  namespace: apps
  labels:
    name: jenkins-data
    type: longhorn
spec:
  capacity:
    storage: 20G
  volumeMode: Filesystem
  storageClassName: longhorn
  accessModes:
    - ReadWriteOnce
  csi:
    driver: io.rancher.longhorn
    fsType: ext4
    volumeAttributes:
      numberOfReplicates: '2'
      staleReplicaTimeout: '20'
    volumeHandle: jenkins-data

Create persistent volume claim yaml

Create file pv-claim.yaml with this following content:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: jenkins-pv-claim
  labels:
    type: longhorn
    app: jenkins
spec:
  storageClassName: longhorn
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 20Gi

Create service account yaml

Create file jenkins-sa.yaml with this following content:
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: jenkins
  namespace: jenkins
---
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
  - ingresses
  verbs:
  - create
  - get
  - watch
  - delete
  - list
  - patch
  - update
- apiGroups:
  - ""
  resources:
  - nodes
  verbs:
  - get
  - list
  - watch
  - update
---
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

Create deployment yaml

Create file jenkins-deployment.yaml with this following content:
apiVersion: apps/v1
kind: Deployment
metadata:
  name: jenkins
spec:
  replicas: 1
  selector:
    matchLabels:
      app: jenkins
  template:
    metadata:
      labels:
        app: jenkins
    spec:
      containers:
      - name: jenkins
        image: jenkins/jenkins:lts-jdk11
        ports:
        - containerPort: 8080
        securityContext:
          allowPrivilegeEscalation: true
          privileged: true
          readOnlyRootFilesystem: false
          runAsUser: 0
        volumeMounts:
        - name: jenkins-persistent-storage
          mountPath: /var/jenkins_home
      volumes:
      - name: jenkins-persistent-storage
        persistentVolumeClaim:
          claimName: jenkins-pv-claim

Create service yaml

Create file jenkins-service.yaml with this following content:
kind: Service
apiVersion: v1
metadata:
  name: jenkins-frontend
  labels:
    app: jenkins
spec:
  selector:
    app: jenkins
  ports:
  - port: 80
    targetPort: 8080
  clusterIP: None

Create ingress yaml

Create file jenkins-ingress.yaml, and don't forget to change the hostname with yours:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: jenkins-ingress
spec:
  rules:
  - host: jenkins.example.com
    http:
      paths:
      - backend:
          serviceName: jenkins-frontend
          servicePort: 80

Deploy the configuration

When all configuration ready, do this following command:
kubectl apply -f ./jenkins/
After deployement finish, you can continue to access jenkins using the domain jenkins.example.com

Testing Persistent

To test the persistent disk, you can try to delete the container in kubernetes. The container should be automatically created again by kubernetes. If you access jenkins after that, you should not asked again for initial setup. If no initial setup come up, that means jenkins store the configuration in persistent disk correctly.

Resources

Comments

Popular Posts