Restoring Volumes for Kubernetes Stateful Sets
Longhorn supports restoring backups, and one of the use cases for this feature is to restore data for use in a Kubernetes Stateful Set
, which requires restoring a volume for each replica that was backed up. To restore, follow the below instructions based on which plugin you have deployed. The example below uses a Stateful Set with one volume attached to each Pod and two replicas.
CSI Instructions
- Connect to the
Longhorn UI
page in your web browser. Under theBackup
tab, select the name of the Stateful Set volume. Click the dropdown menu of the volume entry and restore it. Name the volume something that can easily be referenced later for thePersistent Volumes
.
- Repeat this step for each volume you need restored.
- For example, if restoring a Stateful Set with two replicas that had volumes named
pvc-01a
andpvc-02b
, the restore could look like this:
Backup Name | Restored Volume |
---|---|
pvc-01a | statefulset-vol-0 |
pvc-02b | statefulset-vol-1 |
- In Kubernetes, create a
Persistent Volume
for each Longhorn volume that was created. Name the volumes something that can easily be referenced later for thePersistent Volume Claims
.storage
capacity,numberOfReplicas
,storageClassName
, andvolumeHandle
must be replaced below. In the example, we’re referencingstatefulset-vol-0
andstatefulset-vol-1
in Longhorn and usinglonghorn
as ourstorageClassName
.
apiVersion: v1
kind: PersistentVolume
metadata:
spec:
capacity:
storage: <size> # must match size of Longhorn volume
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Delete
csi:
driver: io.rancher.longhorn # driver must match this
fsType: ext4
volumeAttributes:
numberOfReplicas: <replicas> # must match Longhorn volume value
staleReplicaTimeout: '30'
volumeHandle: statefulset-vol-0 # must match volume name from Longhorn
storageClassName: longhorn # must be same name that we will use later
---
apiVersion: v1
kind: PersistentVolume
metadata:
spec:
capacity:
storage: <size> # must match size of Longhorn volume
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Delete
csi:
driver: io.rancher.longhorn # driver must match this
fsType: ext4
volumeAttributes:
numberOfReplicas: <replicas> # must match Longhorn volume value
staleReplicaTimeout: '30'
volumeHandle: statefulset-vol-1 # must match volume name from Longhorn
storageClassName: longhorn # must be same name that we will use later
- Go to General Instructions.
Flexvolume Instructions
Because of the implementation of Flexvolume
, creating the Longhorn volumes from the Longhorn UI
manually can be skipped. Instead, follow these instructions:
- Connect to the
Longhorn UI
page in your web browser. Under theBackup
tab, select the name of theStateful Set
volume. Click the dropdown menu of the volume entry and selectGet URL
.
- Repeat this step for each volume you need restored. Save these URLs for the next step.
- If using NFS backups, the URL will appear similar to:
nfs://longhorn-nfs-svc.default:/opt/backupstore?backup=backup-c57844b68923408f&volume=pvc-59b20247-99bf-11e8-8a92-be8835d7412a
.
- If using S3 backups, the URL will appear similar to:
s3://backupbucket@us-east-1/backupstore?backup=backup-1713a64cd2774c43&volume=longhorn-testvol-g1n1de
- Similar to
Step 2
for CSI, create aPersistent Volume
for each volume you want to restore.storage
capacity,storageClassName
, and the Flexvolumeoptions
must be replaced. This example useslonghorn
as thestorageClassName
.
apiVersion: v1
kind: PersistentVolume
metadata:
spec:
capacity:
storage: <size> # must match "size" parameter below
accessModes:
- ReadWriteOnce
storageClassName: longhorn # must be same name that we will use later
flexVolume:
driver: "rancher.io/longhorn" # driver must match this
fsType: "ext4"
options:
size: <size> # must match "storage" parameter above
numberOfReplicas: <replicas>
staleReplicaTimeout: <timeout>
fromBackup: <backup URL> # must be set to Longhorn backup URL
---
apiVersion: v1
kind: PersistentVolume
metadata:
spec:
capacity:
storage: <size> # must match "size" parameter below
accessModes:
- ReadWriteOnce
storageClassName: longhorn # must be same name that we will use later
flexVolume:
driver: "rancher.io/longhorn" # driver must match this
fsType: "ext4"
options:
size: <size> # must match "storage" parameter above
numberOfReplicas: <replicas>
staleReplicaTimeout: <timeout>
fromBackup: <backup URL> # must be set to Longhorn backup URL
- Go to General Instructions.
General Instructions
Make sure you have followed either the CSI or Flexvolume instructions before following the steps in this section.
- In the
namespace
theStateful Set
will be deployed in, create Persistent Volume Claims for eachPersistent Volume
.
- The name of the
Persistent Volume Claim
must follow this naming scheme:<name of Volume Claim Template>-<name of Stateful Set>-<index>
. Stateful Set Pods are zero-indexed. In this example, the name of theVolume Claim Template
isdata
, the name of theStateful Set
iswebapp
, and there are two replicas, which are indexes0
and1
.
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 2Gi # must match size from earlier
storageClassName: longhorn # must match name from earlier
volumeName: statefulset-vol-0 # must reference Persistent Volume
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 2Gi # must match size from earlier
storageClassName: longhorn # must match name from earlier
volumeName: statefulset-vol-1 # must reference Persistent Volume
- Create the
Stateful Set
:
apiVersion: apps/v1beta2
kind: StatefulSet
metadata:
spec:
selector:
matchLabels:
app: nginx # has to match .spec.template.metadata.labels
serviceName: "nginx"
replicas: 2 # by default is 1
template:
metadata:
labels:
app: nginx # has to match .spec.selector.matchLabels
spec:
terminationGracePeriodSeconds: 10
containers:
image: k8s.gcr.io/nginx-slim:0.8
ports:
- containerPort: 80
volumeMounts:
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
- metadata:
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: longhorn # must match name from earlier
resources:
requests:
storage: 2Gi # must match size from earlier
The restored data should now be accessible from inside the Stateful Set
Pods
.