-
Create a secret for the cloud storage credentials by running the following command:
$ oc create secret generic <secret_name> -n openshift-adp --from-file cloud=<credentials_file_path>
<secret_name>
-
Specifies the name of the cloud credentials secret.
<credentials_file_path>
-
Specifies the path to the file that contains the cloud storage credentials.
-
Create a DataProtectionApplication (DPA) CR with the VMFR feature enabled and the kubevirt plugin:
apiVersion: oadp.openshift.io/v1alpha1
kind: DataProtectionApplication
metadata:
name: vmfr-dpa
namespace: openshift-adp
spec:
backupLocations:
- velero:
credential:
key: cloud
name: <secret_name>
default: true
objectStorage:
bucket: <bucket_name>
prefix: velero
provider: <provider>
configuration:
velero:
defaultPlugins:
- csi
- openshift
- kubevirt
- <provider>
disableFsBackup: false
nodeAgent:
enable: true
uploaderType: kopia
vmFileRestore:
enable: true
<secret_name>
-
Specifies the name of the cloud credentials secret you created.
<bucket_name>
-
Specifies the name of the object storage bucket.
<provider>
-
Specifies the cloud provider plugin, such as aws, gcp, or azure.
vmFileRestore
-
Enables the VMFR feature by setting the enable field to true.
-
Apply the DPA configuration by running the following command:
$ oc apply -f <dpa_cr_filename>
-
Verify that the DPA is reconciled and the VMFR feature is enabled by running the following command:
$ oc get dpa -n openshift-adp -o yaml
In the output, verify that the status.conditions section includes a condition with type: VMFileRestoreReady and status: "True".
-
Verify that the velero, nodeAgent, and oadp-vm-file-restore-controller-manager pods are running by running the following command:
$ oc get pod -n openshift-adp
-
Generate an SSH key pair for accessing the VM:
$ ssh-keygen -t ed25519 -f ~/.ssh/<vm_key_name> -C "<vm_key_name>"
Replace <vm_key_name> with a name for the SSH folder and the key file.
-
Create a namespace for the VM by running the following command:
$ oc create ns <vm_namespace>
-
Create a Kubernetes secret with the SSH public key in the VM namespace:
$ oc create secret generic <ssh_secret_name> \
--from-file=key=<path_to_public_key> \
-n <vm_namespace>
<ssh_secret_name>
-
Specifies the name of the secret that contains the SSH public key.
<path_to_public_key>
-
Specifies the path to the SSH public key file you created in an earlier step. For example, $HOME/.ssh/vm-key.pub.
<vm_namespace>
-
Specifies the namespace for the VM.
-
Create a VirtualMachine CR by using the built-in VM template fedora-server-small:
$ oc process -n openshift fedora-server-small -p NAME=<vm_name> | oc apply -n <vm_namespace> -f -
<vm_name>
-
Specifies the name of the VM.
<vm_namespace>
-
Specifies the namespace for the VM.
-
Wait for the VM to be ready:
$ oc wait --for=condition=Ready vmi/<vm_name> -n <vm_namespace>
-
Patch the VM configuration accessCredentials object with the SSH public key:
$ oc patch vm <vm_name> -n <vm_namespace> --type=merge -p '{"spec":{"template":{"spec":{"accessCredentials":[{"sshPublicKey":{"propagationMethod":{"noCloud":{}},"source":{"secret":{"secretName":"<ssh_secret_name>"}}}}]}}}}'
<vm_name>
-
Specifies the name of the VM.
<vm_namespace>
-
Specifies the namespace for the VM.
<ssh_secret_name>
-
Specifies the name of the secret that contains the SSH public key.
-
SSH to the VM and create a test file:
$ virtctl ssh <vm_user>@vmi/<vm_name> \
-n <vm_namespace> \
--identity-file=$HOME/.ssh/<vm_key_name> \
--local-ssh-opts="-o StrictHostKeyChecking=no" \
-c "echo 'Test file for VMFR validation - $(date)' > /home/fedora/test-vmfr-file.txt"
<vm_user>
-
Specifies the name of the VM user. For the in-built VM template, the user name is fedora.
-
Create a Backup CR to back up the VM namespace:
apiVersion: velero.io/v1
kind: Backup
metadata:
name: <backup_name>
namespace: openshift-adp
spec:
includedNamespaces:
- <vm_namespace>
snapshotMoveData: true
-
Apply the Backup CR by running the following command:
$ oc apply -f <backup_cr_filename>
-
Verify that the backup is complete by running the following command:
$ oc get backup.velero <backup_name> -n openshift-adp -o jsonpath='{.status.phase}'
The output should display Completed.
-
Create a VirtualMachineBackupsDiscovery CR to identify which backups contain the target VM:
apiVersion: oadp.openshift.io/v1alpha1
kind: VirtualMachineBackupsDiscovery
metadata:
name: <vmbd_name>
namespace: openshift-adp
spec:
virtualMachineName: <vm_name>
virtualMachineNamespace: <vm_namespace>
-
Apply the VMBD CR by running the following command:
$ oc apply -f <vmbd_cr_filename>
-
Verify that the discovery is complete by running the following command:
$ oc get vmbd <vmbd_name> -n openshift-adp
The PHASE column should display Completed.
-
Create a VirtualMachineFileRestore CR with SSH access to restore files from the discovered backups:
apiVersion: oadp.openshift.io/v1alpha1
kind: VirtualMachineFileRestore
metadata:
name: <vmfr_name>
namespace: openshift-adp
spec:
backupsDiscoveryRef: <vmbd_name>
fileAccess:
ssh: {}
The ssh: {} configuration instructs the controller to autogenerate an SSH key pair and store it in a Kubernetes secret. The default SSH username is oadp.
-
Apply the VMFR CR by running the following command:
$ oc apply -f <vmfr_cr_filename>
-
Wait for the VMFR phase to complete:
$ oc get vmfr <vmfr_name> -n openshift-adp
The PHASE column should display Completed.
-
Retrieve the SSH access information by running the following command:
$ oc get vmfr <vmfr_name> -o jsonpath='{.status.fileServingInfo.ssh}' | jq
The output includes the clusterAccess URL and the credentialsSecretRef containing the name and namespace of the auto generated SSH key secret.
-
Retrieve the private key from the auto generated secret and save it to a file:
$ oc get secret <secret_name> -n <secret_namespace> -o jsonpath='{.data.privateKey}' | base64 -d > id-rsa
Replace <secret_name> and <secret_namespace> with the values from the status.fileServingInfo.ssh.credentialsSecretRef field.
-
Copy the private key to the VM so that you can use it for scp from within the VM:
$ virtctl scp id-rsa \
<vm_user>@vmi/<vm_name>:/home/<vm_user>/id-rsa \
-n <vm_namespace> \
--identity-file=$HOME/.ssh/<vm_key_name>
-
Update the file permissions on the private key inside the VM:
$ virtctl ssh <vm_user>@vmi/<vm_name> \
-n <vm_namespace> \
--identity-file=$HOME/.ssh/<vm_key_name> \
--local-ssh-opts="-o StrictHostKeyChecking=no" \
-c "chmod 600 /home/<vm_user>/id-rsa"
-
Get the name of the file server service created in the VMFR namespace:
$ SVC=$(oc get svc -n <created_namespace> | grep fileserver | awk '{print $1}')
Replace <created_namespace> with the value from the status.createdNamespace field of the VMFR CR.
-
Restore the file by using scp from within the VM. The remote path format is /restores/<date>/<backup_name>/<vm_name>/<path_to_file>:
$ virtctl ssh <vm_user>@vmi/<vm_name> \
-n <vm_namespace> \
--identity-file=$HOME/.ssh/<vm_key_name> \
--local-ssh-opts="-o StrictHostKeyChecking=no" \
-c "scp -P 2222 \
-i /home/<vm_user>/id-rsa \
-o StrictHostKeyChecking=no \
-o UserKnownHostsFile=/dev/null \
oadp@<fileserver_svc>.<created_namespace>.svc.cluster.local:<remote_path> \
/tmp/restored.txt"
<fileserver_svc>
-
Specifies the name of the file server service you retrieved in an earlier step.
<created_namespace>
-
Specifies the namespace from the status.createdNamespace field.
<remote_path>
-
Specifies the path to the file in the format /restores/<date>/<backup_name>/<vm_name>/<path_to_file>. For example, "/restores/2026-02-10/test-backup/fedora-vm-test/home/fedora/test-vmfr-file.txt"
-
Verify that the restored file is intact by comparing MD5 checksums:
$ virtctl ssh <vm_user>@vmi/<vm_name> \
-n <vm_namespace> \
--identity-file=$HOME/.ssh/<vm_key_name> \
--local-ssh-opts="-o StrictHostKeyChecking=no" \
-c "echo '===MD5 Checksums===' && md5sum /home/fedora/test-vmfr-file.txt /tmp/restored.txt"
The checksums of the original and restored files should match. You should see an output as shown in the following example:
===MD5 Checksums===
92245490c552e83baf5f2a2e898d9fff /home/fedora/test-vmfr-file.txt
92245490c552e83baf5f2a2e898d9fff /tmp/restored.txt
-
After you have recovered the files, delete the VMFR CR to clean up resources:
$ oc delete vmfr <vmfr_name> -n openshift-adp