Jenkins backup and restore strategy¶
For Jenkins deployments running on Kubernetes, particularly those managed via Helm, a robust backup and restore strategy is essential to prevent data loss. This typically involves utilizing cloud storage solutions, such as Google Cloud Storage (GCS) or AWS S3, and leveraging Kubernetes Jobs or CronJobs to handle data transfer.^[400-devops__06-Kubernetes__devops-helm__helm-jenkins__README.md]
Backup Strategy¶
The recommended approach for backing up Jenkins is to use a Kubernetes CronJob that periodically uploads data from the Jenkins Persistent Volume Claim (PVC) to a cloud storage destination^[400-devops__06-Kubernetes__devops-helm__helm-jenkins__README.md].
Prerequisites¶
Before enabling backups, ensure persistence is enabled in your Helm values to guarantee that a PVC exists to be backed up^[400-devops__06-Kubernetes__devops-helm__helm-jenkins__README.md].
persistence:
enabled: true
Configuration for Cloud Storage¶
To automate backups, you must provide credentials for the backup service to access your cloud storage.
-
Google Cloud Storage (GCS):
- Create a GCS bucket and a Service Account with the
roles/storage.adminrole^[400-devops__06-Kubernetes__devops-helm__helm-jenkins__README.md]. - Create a Service Account Key and store it as a Kubernetes Secret^[400-devops__06-Kubernetes__devops-helm__helm-jenkins__README.md].
[kubectl](<./kubectl.md>) -n jenkins create secret generic jenkinsgcp --from-file=sa-credentials.json=/path/to/sa_key.json - Create a GCS bucket and a Service Account with the
-
AWS S3:
- If the S3 bucket is not in the default region (
eu-central-1), you must explicitly provide the region via environment variables^[400-devops__06-Kubernetes__devops-helm__helm-jenkins__README.md].
- If the S3 bucket is not in the default region (
Enabling the Backup CronJob¶
You can enable the backup CronJob by modifying your values.yaml file. This configuration sets the schedule, destination, and the secret required for authentication^[400-devops__06-Kubernetes__devops-helm__helm-jenkins__README.md].
backup:
enabled: true
schedule: "0 2 * * *" # Run daily at 2 AM
existingSecret:
jenkinsgcp: # Matches the secret name
gcpcredentials: sa-credentials.json # Key in the secret
destination: "gcs://BUCKET_NAME/jenkins-k8s-backup"
Once deployed, the CronJob will create a time-stamped folder in the destination bucket during each execution^[400-devops__06-Kubernetes__devops-helm__helm-jenkins__README.md]. You can verify the success of the operation by checking the logs of the backup pod^[400-devops__06-Kubernetes__devops-helm__helm-jenkins__README.md].
Restore Strategy¶
Restoring Jenkins involves copying data from cloud storage back to the Jenkins PVC. Because the restore process requires writing to the volume of another Pod, specific RBAC resources must be created first^[400-devops__06-Kubernetes__devops-helm__helm-jenkins__README.md].
Step 1: Create RBAC Resources¶
You must define a ServiceAccount, ClusterRole, and ClusterRoleBinding to authorize the restore job to interact with the Jenkins Pod's filesystem^[400-devops__06-Kubernetes__devops-helm__helm-jenkins__README.md].
restore-rbac.yaml:
apiVersion: v1
kind: ServiceAccount
metadata:
name: skbn
namespace: jenkins
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: skbn
rules:
- apiGroups: [""]
resources: ["pods", "pods/log"]
verbs: ["get", "list"]
- apiGroups: [""]
resources: ["pods/exec"]
verbs: ["create"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: skbn
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: skbn
subjects:
- kind: ServiceAccount
name: skbn
namespace: jenkins
Apply this configuration with kubectl apply -f restore-rbac.yaml^[400-devops__06-Kubernetes__devops-helm__helm-jenkins__README.md].
Step 2: Create the Restore Job¶
The actual restore is performed by a Kubernetes Job utilizing the skbn tool, which copies files from the cloud storage source to the Kubernetes destination^[400-devops__06-Kubernetes__devops-helm__helm-jenkins__README.md].
restore.yaml:
apiVersion: batch/v1
kind: Job
metadata:
name: skbn
namespace: jenkins
spec:
template:
spec:
restartPolicy: OnFailure
serviceAccountName: skbn
containers:
- name: skbn
image: maorfr/skbn
command: ["skbn"]
args:
- "cp"
- "--src"
- "gcs://BUCKET_NAME/jenkins-k8s-backup/BACKUP_NAME"
- "--dst"
- "k8s://jenkins/jenkins-0/jenkins/var/jenkins_home"
env:
- name: GOOGLE_APPLICATION_CREDENTIALS
value: /var/run/secrets/jenkinsgcp/sa-credentials.json
volumeMounts:
- mountPath: /var/run/secrets/jenkinsgcp
name: jenkinsgcp
volumes:
- name: jenkinsgcp
secret:
secretName: jenkinsgcp
- Replace
BUCKET_NAMEandBACKUP_NAME(the time-stamped folder) with your specific values^[400-devops__06-Kubernetes__devops-helm__helm-jenkins__README.md]. - The destination path
k8s://jenkins/jenkins-0/jenkins/var/jenkins_homeassumes the Jenkins controller Pod is namedjenkins-0(StatefulSet) and data is stored in the default home directory^[400-devops__06-Kubernetes__devops-helm__helm-jenkins__README.md].
Deploy the job using kubectl apply -f restore.yaml and monitor the logs to ensure completion^[400-devops__06-Kubernetes__devops-helm__helm-jenkins__README.md].
Step 3: Finalize the Restore¶
Once the data has been copied to the disk, you must reload the configuration within the Jenkins UI^[400-devops__06-Kubernetes__devops-helm__helm-jenkins__README.md].
- Log in to Jenkins.
- Navigate to Manage Jenkins.
- Click Reload Configuration from Disk.
- Important: Log in using the credentials from the restored backup, not the credentials of the fresh installation^[400-devops__06-Kubernetes__devops-helm__helm-jenkins__README.md].
Sources¶
- 400-devops__06-Kubernetes__devops-helm__helm-jenkins__README.md