GitLab Backup and Restore Using Velero
This guide demonstrates how to implement GitLab backup and restore operations using Velero, an open-source cloud-native disaster recovery tool.
TOC
Applicability
This solution is applicable to GitLab instances running version 17.8 or later.
GitLab data comprises three primary components: PostgreSQL database, Git repositories, and uploaded artifacts (including user avatars, comment attachments, etc.). This solution provides backup support for Git repositories and uploaded artifacts only. The PostgreSQL database requires separate backup procedures according to your database service provider's backup strategy.
DANGER
This solution does not support GitLab instances deployed using HostPath storage.
Terminology
Term | Definition |
---|
Source Instance | The GitLab instance before backup |
Target Instance | The GitLab instance after restore |
Source Namespace | The namespace where the source instance is located |
Target Namespace | The namespace where the target instance is located |
GitLab CR Resource | Describes the deployment configuration of GitLab instance, used by the Operator to deploy GitLab instances |
Prerequisites
- Deploy MinIO Object Storage: The current backup and restore solution relies on object storage to save backup data, requiring a pre-deployed MinIO instance. ACP provides
MinIO Object Storage
for .
- Deploy Velero: Velero is a tool for backup and restore. ACP provides
Alauda Container Platform Data Backup for Velero
, you can deploy it in the Administrator
view, in the Marketplace
-> Cluster Plugins
page, search for Velero
and deploy it.
- Install mc Command-Line Tool: mc is MinIO's command-line tool for managing MinIO instances. For installation instructions, refer to the MinIO official documentation.
- Install kubectl Command-Line Tool: kubectl is Kubernetes' command-line tool for managing Kubernetes clusters. For installation instructions, refer to the Kubernetes official documentation.
For convenience in subsequent operations, please set the environment variables first:
export MINIO_HOST=<MinIO instance access address> # Example: http://192.168.1.100:32008
export MINIO_ACCESS_KEY=<MinIO instance access key> # Example: minioadmin
export MINIO_SECRET_KEY=<MinIO instance secret key> # Example: minioadminpassword
export MINIO_ALIAS_NAME=<MinIO instance alias name> # Example: myminio
export VELERO_BACKUP_BUCKET=<Velero backup bucket name> # Example: backup
export VELERO_BACKUP_REPO_NAME=<Velero backup repo name> # Example: gitlab-backup-repo
export GITLAB_NAMESPACE=<namespace of the GitLab instance to be backed up>
export GITLAB_NAME=<name of the GitLab instance to be backed up>
Execute the following commands to configure the mc command-line tool and test the connection:
mc alias set ${MINIO_ALIAS_NAME} ${MINIO_HOST} ${MINIO_ACCESS_KEY} ${MINIO_SECRET_KEY}
mc ping ${MINIO_ALIAS_NAME}
# Output:
# 1: http://192.168.131.56:32571:32571 min=98.86ms max=98.86ms average=98.86ms errors=0 roundtrip=98.86ms
# 2: http://192.168.131.56:32571:32571 min=29.57ms max=98.86ms average=64.21ms errors=0 roundtrip=29.57ms
# 3: http://192.168.131.56:32571:32571 min=29.57ms max=98.86ms average=52.77ms errors=0 roundtrip=29.88ms
If you can successfully ping the MinIO instance, it indicates that mc is configured correctly.
Backup
Preparation
Backup preparation involves two steps:
- Create Bucket
- Configure Velero backup repository
Create Bucket
Execute the following commands to create a bucket to store backup data:
mc mb ${MINIO_ALIAS_NAME}/${VELERO_BACKUP_BUCKET}
# Output:
# Bucket created successfully `myminio/backup`.
Configure Velero Backup Repository
Execute the following commands to create the Velero backup repository which is used to store backup data:
gitlab_backup_repo_credentials_secret_name="gitlab-backup-repo-credentials"
minio_gitlab_backup_bucket="${VELERO_BACKUP_BUCKET:-backup}"
minio_gitlab_backup_bucket_directory="gitlab"
kubectl apply -f - <<EOF
apiVersion: v1
stringData:
cloud: |
[default]
aws_access_key_id = ${MINIO_ACCESS_KEY}
aws_secret_access_key = ${MINIO_SECRET_KEY}
kind: Secret
metadata:
labels:
component: velero
cpaas.io/backup-storage-location-repo: ${VELERO_BACKUP_REPO_NAME}
name: ${gitlab_backup_repo_credentials_secret_name}
namespace: cpaas-system
type: Opaque
---
apiVersion: velero.io/v1
kind: BackupStorageLocation
metadata:
name: ${VELERO_BACKUP_REPO_NAME}
namespace: cpaas-system
spec:
config:
checksumAlgorithm: ""
insecureSkipTLSVerify: "true"
region: minio
s3ForcePathStyle: "true"
s3Url: ${MINIO_HOST}
credential:
key: cloud
name: ${gitlab_backup_repo_credentials_secret_name}
objectStorage:
bucket: ${minio_gitlab_backup_bucket}
prefix: ${minio_gitlab_backup_bucket_directory}
provider: aws
EOF
# Output
# secret/gitlab-backup-repo-credentials created
# backupstoragelocationrepo.ait.velero.io/gitlab-backup-repo created
Execute Backup
Manual backup consists of six steps:
- Label resources for backup
- Stop GitLab services
- Create backup pod
- Create backup schedule
- Execute backup
- Restore GitLab services
Label Resources for Backup
Execute the following script:
if [ -z "${GITLAB_NAMESPACE}" ] || [ -z "${GITLAB_NAME}" ]; then
cat <<EOF
Please set the correct namespace and instance name:
export GITLAB_NAME=<original GitLab instance name>
export GITLAB_NAMESPACE=<original namespace name>
EOF
return
fi
kubectl label gitlabofficial -n ${GITLAB_NAMESPACE} ${GITLAB_NAME} release=${GITLAB_NAME} --overwrite
secrets_to_label=()
root_password_secret_name=$(kubectl get gitlabofficial -n ${GITLAB_NAMESPACE} ${GITLAB_NAME} -o jsonpath='{.spec.helmValues.global.initialRootPassword.secret}')
secrets_to_label+=(${root_password_secret_name})
rails_secret_name=$(kubectl get gitlabofficial -n ${GITLAB_NAMESPACE} ${GITLAB_NAME} -o jsonpath='{.spec.helmValues.global.railsSecrets.secret}')
if [ -n "${rails_secret_name}" ]; then
echo "Found rails secret: ${rails_secret_name}"
secrets_to_label+=(${rails_secret_name})
fi
pg_connect_secret_name=$(kubectl get gitlabofficial -n ${GITLAB_NAMESPACE} ${GITLAB_NAME} -o jsonpath='{.spec.helmValues.global.psql.password.secret}')
secrets_to_label+=(${pg_connect_secret_name})
ingress_secret_name=$(kubectl get gitlabofficial -n ${GITLAB_NAMESPACE} ${GITLAB_NAME} -o jsonpath='{.spec.helmValues.global.ingress.tls.secretName}')
if [ -n "${ingress_secret_name}" ]; then
echo "Found ingress secret: ${ingress_secret_name}"
secrets_to_label+=(${ingress_secret_name})
fi
redis_connect_secret_name=$(kubectl get gitlabofficial -n ${GITLAB_NAMESPACE} ${GITLAB_NAME} -o jsonpath='{.spec.helmValues.global.redis.auth.secret}')
if [ -n "${redis_connect_secret_name}" ]; then
echo "Found redis auth secret: ${redis_connect_secret_name}"
secrets_to_label+=(${redis_connect_secret_name})
fi
redis_sentinel_connect_secret_name=$(kubectl get gitlabofficial -n ${GITLAB_NAMESPACE} ${GITLAB_NAME} -o jsonpath='{.spec.helmValues.global.redis.sentinelAuth.secret}')
if [ -n "${redis_sentinel_connect_secret_name}" ]; then
echo "Found redis sentinel connect secret: ${redis_sentinel_connect_secret_name}"
secrets_to_label+=(${redis_sentinel_connect_secret_name})
fi
object_store_secret_name=$(kubectl get gitlabofficial -n ${GITLAB_NAMESPACE} ${GITLAB_NAME} -o jsonpath='{.spec.helmValues.global.appConfig.object_store.connection.secret}')
if [ -n "${object_store_secret_name}" ]; then
echo "Found object storage connect secret: ${object_store_secret_name}"
kubectl label secret ${object_store_secret_name} -n ${GITLAB_NAMESPACE} release=${GITLAB_NAME}
fi
for secret_name in "${secrets_to_label[@]}"; do
echo "Add label to secret: ${secret_name}"
kubectl label secret ${secret_name} -n ${GITLAB_NAMESPACE} release=${GITLAB_NAME} --overwrite
done
kubectl get pvc -n ${GITLAB_NAMESPACE} --no-headers | grep ${GITLAB_NAME} | awk '{print $1}' | xargs -I {} kubectl label pvc {} release=${GITLAB_NAME} -n ${GITLAB_NAMESPACE}
kubectl get secret -n ${GITLAB_NAMESPACE} --no-headers | grep ${GITLAB_NAME} | awk '{print $1}' | xargs -I {} kubectl label secret {} release=${GITLAB_NAME} -n ${GITLAB_NAMESPACE}
# Output:
# secret/sh.helm.release.v1.xxx-gitlab.v9 not labeled
If additional resources need to be backed up, refer to the Label Additional Resources for Backup section.
Stop GitLab Services
All GitLab components must be stopped during backup:
kubectl annotate statefulset -n ${GITLAB_NAMESPACE} -l release=${GITLAB_NAME} skip-sync="true"
kubectl scale statefulset -n ${GITLAB_NAMESPACE} -l release=${GITLAB_NAME} --replicas=0
kubectl annotate deployment -n ${GITLAB_NAMESPACE} -l release=${GITLAB_NAME} skip-sync="true"
kubectl scale deployment -n ${GITLAB_NAMESPACE} -l release=${GITLAB_NAME} --replicas=0
kubectl delete pod -n ${GITLAB_NAMESPACE} -l release=${GITLAB_NAME} --ignore-not-found
# Output:
# statefulset.apps/xxxx-gitlab-gitaly annotated
# deployment.apps/xxxx-gitlab-webservice-default annotated
# deployment.apps/xxxx-gitlab-toolbox scaled
# deployment.apps/xxxx-gitlab-webservice-default scaled
Create Backup Pod
This step creates a pod that mounts GitLab's PVCs to enable Velero to complete PVC data backup.
image=''
if [ -z "${IMAGE}" ]; then
image=$(kubectl get deployment -n ${GITLAB_NAMESPACE} -l release=${GITLAB_NAME},app=gitlab-shell -o jsonpath='{range .items[0].spec.template.spec.containers[]}{.image}{"\n"}{end}' | head -n1)
fi
PVC_NAMES=($(kubectl get pvc -n ${GITLAB_NAMESPACE} -l release=${GITLAB_NAME} -o jsonpath='{range .items[*]}{.metadata.name}{" "}{end}'))
VOLUME_MOUNTS=""
VOLUMES=""
INDEX=0
for pvc in ${PVC_NAMES[@]}; do
VOLUME_MOUNTS="${VOLUME_MOUNTS}
- name: data-${INDEX}
mountPath: /mnt/data-${INDEX}"
VOLUMES="${VOLUMES}
- name: data-${INDEX}
persistentVolumeClaim:
claimName: ${pvc}"
INDEX=$((INDEX+1))
done
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: ${GITLAB_NAME}-backup-pod
namespace: ${GITLAB_NAMESPACE}
labels:
release: ${GITLAB_NAME}
spec:
containers:
- name: backup
image: ${image}
command: ["/bin/sh", "-c", "sleep 86400"]
resources:
limits:
cpu: 1
memory: 1Gi
volumeMounts:${VOLUME_MOUNTS}
volumes:${VOLUMES}
restartPolicy: Never
EOF
kubectl wait --for=condition=ready pod -n ${GITLAB_NAMESPACE} ${GITLAB_NAME}-backup-pod
# Output
# pod/xxxx-gitlab-backup-pod created
# pod/xxxx-gitlab-backup-pod condition met
Create Backup Volume Policy
Volume policy is used to specify the backup method for PVCs. The default policy is to backup PVCs using the fs-backup
method.
export BACKUP_POLICY_NAME=${BACKUP_POLICY_NAME:-gitlab-backup}
export VELERO_BACKUP_REPO_NAME=${VELERO_BACKUP_REPO_NAME:-backup}
kubectl apply -f - <<EOF
apiVersion: v1
kind: ConfigMap
metadata:
name: ${BACKUP_POLICY_NAME}-volume-policy
namespace: cpaas-system
data:
resourcepolicies: |
version: v1
volumePolicies:
- conditions:
csi: {}
action:
type: fs-backup
- conditions:
csi: {}
action:
type: fs-backup
EOF
# Output
# configmap/gitlab-backup-volume-policy created
If the PVC supports snapshot, you can use snapshot to backup pvc to speed up backup. You need to modify the volume policy configmap to specify that the storage class uses snapshot for backup. For example, if the ceph
storage class supports snapshot backup, you need to add the following configuration (the added condition should be placed at the top to get higher priority):
How to determine if the PVC supports snapshot?
WARNING
If you use pvc snapshot backup, you cannot change the storage class when restoring. Please adjust the storage class according to the actual situation.
apiVersion: v1
kind: ConfigMap
metadata:
name: ${BACKUP_POLICY_NAME}-volume-policy
namespace: cpaas-system
data:
resourcepolicies: |
version: v1
volumePolicies:
+ - conditions:
+ storageClass:
+ - ceph
+ action:
+ type: snapshot
- conditions:
csi: {}
action:
type: fs-backup
- conditions:
csi: {}
action:
type: fs-backup
WARNING
If the velero is not enabled CSI snapshot, you will get the following error when backup:
Skip action velero.io/csi-pvc-backupper for resource persistentvolumeclaims:xxx, because the CSI feature is not enabled.
To fix this, you need to add --features=EnableCSI
parameter to the velero deployment.
apiVersion: apps/v1
kind: Deployment
metadata:
name: velero
spec:
template:
spec:
containers:
- args:
- server
- --uploader-type=restic
+ - --features=EnableCSI
- --namespace=cpaas-system
command:
- /velero
name: velero
Execute Backup
Execute the following command to create a backup schedule and trigger a backup job:
export BACKUP_POLICY_NAME=${BACKUP_POLICY_NAME:-gitlab-backup}
export VELERO_BACKUP_REPO_NAME=${VELERO_BACKUP_REPO_NAME:-backup}
kubectl apply -f - <<EOF
apiVersion: velero.io/v1
kind: Schedule
metadata:
name: ${BACKUP_POLICY_NAME}
namespace: cpaas-system
spec:
schedule: '@every 876000h'
template:
defaultVolumesToFsBackup: true
hooks: {}
includedNamespaces:
- ${GITLAB_NAMESPACE}
includedResources:
- '*'
resourcePolicy:
kind: configmap
name: ${BACKUP_POLICY_NAME}-volume-policy
orLabelSelectors:
- matchLabels:
release: ${GITLAB_NAME}
storageLocation: ${VELERO_BACKUP_REPO_NAME}
ttl: 720h0m0s
EOF
kubectl create -f - <<EOF
apiVersion: velero.io/v1
kind: Backup
metadata:
labels:
velero.io/schedule-name: ${BACKUP_POLICY_NAME}
velero.io/storage-location: ${VELERO_BACKUP_REPO_NAME}
generateName: ${BACKUP_POLICY_NAME}-
namespace: cpaas-system
spec:
csiSnapshotTimeout: 10m0s
defaultVolumesToFsBackup: true
includedNamespaces:
- ${GITLAB_NAMESPACE}
includedResources:
- "*"
itemOperationTimeout: 4h0m0s
resourcePolicy:
kind: configmap
name: ${BACKUP_POLICY_NAME}-volume-policy
orLabelSelectors:
- matchLabels:
release: ${GITLAB_NAME}
snapshotMoveData: false
storageLocation: ${VELERO_BACKUP_REPO_NAME}
ttl: 720h0m0s
EOF
# Output
# schedule.velero.io/gitlab-backup created
# backup.velero.io/gitlab-backup-r6hht created
View backup logs:
kubectl logs -f -n cpaas-system -l app.kubernetes.io/instance=velero | grep gitlab-backup
# Output
# time="2025-07-01T07:29:54Z" level=info msg="PodVolumeBackup completed" controller=PodVolumeBackup logSource="pkg/controller/pod_volume_backup_controller.go:244" pvb=gitlab-backup-xxx-q7prc
Check task progress. If status is Completed, the backup was successful.
kubectl get backup -n cpaas-system -o jsonpath="{range .items[*]}{.metadata.name}{'\t'}{.status.phase}{'\t'}{.status.startTimestamp}{'\n'}{end}"
# Output
# Completed
Restore GitLab Services
Delete the backup pod and restore all GitLab components.
kubectl delete pod -n ${GITLAB_NAMESPACE} ${GITLAB_NAME}-backup-pod
kubectl annotate statefulset -n ${GITLAB_NAMESPACE} -l release=${GITLAB_NAME} skip-sync-
kubectl scale statefulset -n ${GITLAB_NAMESPACE} -l release=${GITLAB_NAME} --replicas=1
kubectl annotate deployment -n ${GITLAB_NAMESPACE} -l release=${GITLAB_NAME} skip-sync-
kubectl scale deployment -n ${GITLAB_NAMESPACE} -l release=${GITLAB_NAME} --replicas=1
After all components are restored, access the GitLab instance to ensure it is functioning normally.
Restore
Preparation
Restore preparation involves four steps:
- Restore PostgreSQL Database (Optional)
- Select a backup to restore
- Determine target namespace for restoration
- Uninstall Gitlab CE Operator
Restore PostgreSQL Database (Optional)
If the new instance will still use the same PostgreSQL instance and database, there's no need to restore the PostgreSQL database.
If the new instance will use a different PostgreSQL instance or database than the old instance, you need to restore the PostgreSQL database first. Refer to your PostgreSQL service provider's backup and restore documentation.
Select Backup Data to Restore
Execute the following command to view the list of successful backup records and select the desired backup based on start time.
kubectl get backup -n cpaas-system -o jsonpath="{range .items[*]}{.metadata.name}{'\t'}{.status.phase}{'\t'}{.status.startTimestamp}{'\n'}{end}" | grep Completed
# Output:
# gitlab-backup-xxx Completed 2025-07-01T07:29:19Z
Set the BACKUP_NAME environment variable:
export BACKUP_NAME=<selected backup record name>
Determine Target Namespace
We recommend restoring the instance to a new namespace. Set the following environment variables:
export NEW_GITLAB_NAMESPACE=<new namespace name>
kubectl create namespace ${NEW_GITLAB_NAMESPACE}
Uninstall Gitlab CE Operator
Execute the following command to uninstall the GitLab CE Operator:
kubectl get subscription --all-namespaces | grep gitlab-ce-operator | awk '{print "kubectl delete subscription "$2" -n "$1}' | sh
# Output:
# subscription.operators.coreos.com "gitlab-ce-operator" deleted
Why uninstall the GitLab operator?
During restoration, Velero needs to start backup pods to restore data in PVCs, which takes some time. If the operator is not uninstalled during restoration, the following issues may occur:
- The operator may recreate workload resources based on the GitLab CR, causing restored pods to restart or be recreated, ultimately leading to restoration interruption or failure.
- Some restored resources may conflict, such as ingress resources created by the operator based on the restored GitLab CR conflicting with the old instance's ingress resources.
Impact of Uninstalling Gitlab CE Operator
If the operator is uninstalled, modifications to the GitLab CR resource will not take effect, such as adjusting resources or storage size.
Uninstalling the operator will not cause existing instances to malfunction.
Restore Operations
Restore operations consist of five steps:
- Create restore configuration file
- Create restore task
- Clean up resources
- Modify GitLab CR resource
- Deploy Gitlab CE Operator
Create Restore Configuration File
Carefully read the comments in the YAML and make modifications according to your actual situation (such as changing storage class), then create the modified YAML.
# If you need to change storage class, set the following two environment variables
OLD_STORAGECLASS_NAME='' # Original storage class name
NEW_STORAGECLASS_NAME='' # New storage class name
if [ -n "${OLD_STORAGECLASS_NAME}" ] && [ -n "${NEW_STORAGECLASS_NAME}" ] && [ ${NEW_STORAGECLASS_NAME} != ${OLD_STORAGECLASS_NAME} ]; then
kubectl apply -f - <<EOF
apiVersion: v1
data:
resourcemodifier: |
version: v1
resourceModifierRules:
- conditions:
groupResource: persistentvolumeclaims
resourceNameRegex: .*
namespaces:
- "*"
patches: &a1
- operation: test
path: /spec/storageClassName
value: ${OLD_STORAGECLASS_NAME}
- operation: replace
path: /spec/storageClassName
value: ${NEW_STORAGECLASS_NAME}
- conditions:
groupResource: persistentvolume
resourceNameRegex: .*
namespaces:
- "*"
patches: *a1
- conditions:
groupResource: persistentvolumeclaims
resourceNameRegex: .*
namespaces:
- "*"
patches:
- operation: test
path: "/metadata/annotations/meta.helm.sh~1release-namespace"
value: ${GITLAB_NAMESPACE}
- operation: replace
path: "/metadata/annotations/meta.helm.sh~1release-namespace"
value: ${NEW_GITLAB_NAMESPACE}
kind: ConfigMap
metadata:
labels:
component: velero
name: gitlab-restore-modifier
namespace: cpaas-system
EOF
else
kubectl apply -f - <<EOF
apiVersion: v1
data:
resourcemodifier: |
version: v1
resourceModifierRules:
- conditions:
groupResource: persistentvolumeclaims
resourceNameRegex: .*
namespaces:
- "*"
patches:
- operation: test
path: "/metadata/annotations/meta.helm.sh~1release-namespace"
value: ${GITLAB_NAMESPACE}
- operation: replace
path: "/metadata/annotations/meta.helm.sh~1release-namespace"
value: ${NEW_GITLAB_NAMESPACE}
kind: ConfigMap
metadata:
labels:
component: velero
name: gitlab-restore-modifier
namespace: cpaas-system
EOF
fi
Create Restore Task
Execute the following command to create the restore task:
kubectl create -f - <<EOF
apiVersion: velero.io/v1
kind: Restore
metadata:
generateName: ${GITLAB_NAME}-restore-
namespace: cpaas-system
spec:
backupName: ${BACKUP_NAME}
hooks: {}
includedNamespaces:
- ${GITLAB_NAMESPACE}
includedResources:
- persistentvolumeclaims
- persistentvolumes
- secrets
- pods
- gitlabofficials.operator.alaudadevops.io
- volumesnapshots
- volumesnapshotcontents
itemOperationTimeout: 10h0m0s
namespaceMapping:
${GITLAB_NAMESPACE}: ${NEW_GITLAB_NAMESPACE}
resourceModifier:
kind: configmap
name: gitlab-restore-modifier
EOF
View restore logs:
kubectl logs -f -n cpaas-system -l app.kubernetes.io/instance=velero | grep gitlab-restore
# Output
# time="2025-07-01T08:01:41Z" level=info msg="Async fs restore data path completed" PVR=xxxx-gitlab-restore-mv6l5-sc4pk controller=PodVolumeRestore logSource="pkg/controller/pod_volume_restore_controller.go:275" pvr=xxxx-gitlab-restore-mv6l5-sc4pk
# time="2025-07-01T08:01:41Z" level=info msg="Restore completed" controller=PodVolumeRestore logSource="pkg/controller/pod_volume_restore_controller.go:327" pvr=xxxx-gitlab-restore-mv6l5-sc4pk
Check task progress. If status is Completed
, the restore was successful.
kubectl get restore -n cpaas-system -o jsonpath="{range .items[*]}{.metadata.name}{'\t'}{.status.phase}{'\t'}{.status.startTimestamp}{'\n'}{end}"
# Output
# xxx-gitlab-restore-xxx InProgress 2025-07-01T10:18:17Z
Clean Up Resources
Ensure the restore operation is complete before proceeding!
Execute the following commands to complete resource cleanup.
kubectl get pod -n ${NEW_GITLAB_NAMESPACE} | grep ${GITLAB_NAME} | awk '{print $1}' | xargs kubectl delete pod -n ${NEW_GITLAB_NAMESPACE}
kubectl get secret -n ${NEW_GITLAB_NAMESPACE} | grep sh.helm.release.v1.${GITLAB_NAME} | awk '{print $1}' | xargs kubectl delete secret -n ${NEW_GITLAB_NAMESPACE}
Modify GitLab CR Resource
kubectl edit gitlabofficial ${GITLAB_NAME} -n ${NEW_GITLAB_NAMESPACE}
The new instance CR resource may need the following modifications. Please make changes according to your actual situation.
- Domain Name:
- Applicable scenario: Original instance was deployed via domain name
- Why modify: Identical domain names in ingress resources created by old and new instances will cause conflicts, leading to failure in creating the new instance's ingress resources
- Modification recommendations:
- (Recommended) Change the original instance's domain to a temporary domain, leave the new instance unchanged
- Keep the original instance's domain unchanged, change the new instance's domain to a new one
- How to modify: Please refer to Configure Instance Network Access to modify the instance access domain name.
- NodePort:
- Applicable scenario: Original instance was deployed via NodePort
- Why modify: Identical NodePorts in service resources created by old and new instances will cause conflicts, leading to failure in creating the new instance's service resources
- Modification recommendations:
- (Recommended) Change the original instance's NodePort to a temporary port, leave the new instance unchanged
- Keep the original instance's NodePort unchanged, change the new instance's NodePort to a new port
- How to modify: Please refer to Configure Instance Network Access to modify the instance access configuration.
- Storage Class:
- Applicable scenario: Original instance was deployed with storage class and there's a change in storage class between old and new instances (e.g., original used NFS, new uses Ceph)
- Why modify: If not modified, the operator will still use the old storage class to create PVCs, which will conflict with the restored PVCs
- Modification recommendation: Change the storage class to the correct value
- How to modify: Please refer to Configure Instance Storage to modify the instance storage configuration.
- PostgreSQL Connection Information:
- Applicable scenario: New instance and old instance plans to use different PostgreSQL instances or databases
- Why modify: If not modified, the new instance will still connect to the old PostgreSQL instance or database
- Modification recommendation: Change the PostgreSQL connection information to the correct values
- How to modify: Please refer to Configure PostgreSQL Access Credential Configuration to modify the PostgreSQL access credential configuration.
Deploy Gitlab CE Operator
Navigate to the Administrator
view, go to Marketplace -> OperatorHub
page and redeploy the Alauda Build of Gitlab
operator.
After deploying the Operator, operator will deploy the new instance according to the GitLab CR. You can view the instance deployment progress in instance detail page.
After waiting for the instance status to return to normal, login to GitLab to check if the data has been restored successfully. Check items include but are not limited to:
- Groups
- Repositories
- Users
- Merge Requests
Q & A
Label Additional Resources for Backup
This step is optional. If you have other resources in the same namespace that you want to backup together, you can add a release label to the corresponding resources. The label value should be the original GitLab instance name, for example:
metadata:
labels:
release: gitlab-g6zd4
How to determine if the PVC supports snapshot?
To determine whether a PVC supports snapshot, you need to check if its underlying StorageClass supports snapshot functionality. A PVC supports snapshot if there is a VolumeSnapshotClass in the cluster whose driver
matches the StorageClass's provisioner
. If such a VolumeSnapshotClass exists, the StorageClass (and therefore the PVC) supports snapshot functionality.
Example Configuration:
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: ceph
provisioner: rook-ceph.cephfs.csi.ceph.com
parameters:
clusterID: rook-ceph
csi.storage.k8s.io/controller-expand-secret-name: rook-csi-cephfs-provisioner
csi.storage.k8s.io/controller-expand-secret-namespace: rook-ceph
csi.storage.k8s.io/node-stage-secret-name: rook-csi-cephfs-node
csi.storage.k8s.io/node-stage-secret-namespace: rook-ceph
csi.storage.k8s.io/provisioner-secret-name: rook-csi-cephfs-provisioner
csi.storage.k8s.io/provisioner-secret-namespace: rook-ceph
fsName: cephfs
pool: cephfs-data0
reclaimPolicy: Delete
volumeBindingMode: Immediate
allowVolumeExpansion: true
---
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshotClass
metadata:
name: csi-cephfs-snapshotclass
deletionPolicy: Delete
driver: rook-ceph.cephfs.csi.ceph.com
parameters:
clusterID: rook-ceph
csi.storage.k8s.io/snapshotter-secret-name: rook-csi-cephfs-provisioner
csi.storage.k8s.io/snapshotter-secret-namespace: rook-ceph
Key Points:
- StorageClass
provisioner
must exactly match VolumeSnapshotClass driver
- Both resources must exist in the cluster
- The CSI driver must support snapshot operations