From a4ba4fe4e2a25be40251f45f4d7d93433498364a Mon Sep 17 00:00:00 2001 From: Tarashish Mishra Date: Tue, 17 Dec 2024 19:45:37 +0530 Subject: [PATCH] Improve NFS home directory restore documentation Also adds the option to mount an EBS volume to a pod through the deployer exec root-homes command. --- deployer/commands/exec/infra_components.py | 77 +++++++++++++++++++ .../filesystem-backups/restore-filesystem.md | 22 ++++-- 2 files changed, 91 insertions(+), 8 deletions(-) diff --git a/deployer/commands/exec/infra_components.py b/deployer/commands/exec/infra_components.py index beccd6f0d..855cb4142 100644 --- a/deployer/commands/exec/infra_components.py +++ b/deployer/commands/exec/infra_components.py @@ -37,6 +37,15 @@ def root_homes( extra_nfs_mount_path: str = typer.Option( None, help="Mount point for the extra NFS share" ), + restore_volume_id: str = typer.Option( + None, + help="ID of EBS volume to mount (e.g. vol-1234567890abcdef0) " + "to restore data from", + ), + restore_mount_path: str = typer.Option( + "/restore-volume", help="Mount point for the EBS volume" + ), + restore_volume_size: str = typer.Option("100Gi", help="Size of the EBS volume"), ): """ Pop an interactive shell with the entire nfs file system of the given cluster mounted on /root-homes @@ -82,6 +91,57 @@ def root_homes( } ] + if restore_volume_id: + # Create PV for EBS volume + pv_name = f"restore-{restore_volume_id}" + pv = { + "apiVersion": "v1", + "kind": "PersistentVolume", + "metadata": {"name": pv_name}, + "spec": { + "capacity": { + "storage": restore_volume_size + }, # Arbitrary size, actual size determined by EBS volume + "volumeMode": "Filesystem", + "accessModes": ["ReadWriteOnce"], + "persistentVolumeReclaimPolicy": "Retain", + "storageClassName": "", + "csi": { + "driver": "ebs.csi.aws.com", + "fsType": "xfs", + "volumeHandle": restore_volume_id, + }, + "mountOptions": [ + "rw", + "relatime", + "nouuid", + "attr2", + "inode64", + "logbufs=8", + "logbsize=32k", + "pquota", + ], + }, + } + + # Create PVC to bind to the PV + pvc = { + "apiVersion": "v1", + "kind": "PersistentVolumeClaim", + "metadata": {"name": pv_name, "namespace": hub_name}, + "spec": { + "accessModes": ["ReadWriteOnce"], + "volumeName": pv_name, + "storageClassName": "", + "resources": {"requests": {"storage": restore_volume_size}}, + }, + } + + volumes.append( + {"name": "ebs-volume", "persistentVolumeClaim": {"claimName": pv_name}} + ) + volume_mounts.append({"name": "ebs-volume", "mountPath": restore_mount_path}) + if extra_nfs_server and extra_nfs_base_path and extra_nfs_mount_path: volumes.append( { @@ -140,6 +200,17 @@ def root_homes( tmpf.flush() with cluster.auth(): + # If we have an EBS volume, create PV and PVC first + if restore_volume_id: + with tempfile.NamedTemporaryFile(mode="w", suffix=".json") as pv_tmpf: + json.dump(pv, pv_tmpf) + pv_tmpf.flush() + subprocess.check_call(["kubectl", "create", "-f", pv_tmpf.name]) + + with tempfile.NamedTemporaryFile(mode="w", suffix=".json") as pvc_tmpf: + json.dump(pvc, pvc_tmpf) + pvc_tmpf.flush() + subprocess.check_call(["kubectl", "create", "-f", pvc_tmpf.name]) try: # We are splitting the previous `kubectl run` command into a # create and exec couplet, because using run meant that the bash @@ -156,6 +227,12 @@ def root_homes( subprocess.check_call(exec_cmd) finally: if not persist: + # Clean up PV and PVC if we created them + if restore_volume_id: + subprocess.check_call( + ["kubectl", "-n", hub_name, "delete", "pvc", pv_name] + ) + subprocess.check_call(["kubectl", "delete", "pv", pv_name]) delete_pod(pod_name, hub_name) diff --git a/docs/howto/filesystem-management/filesystem-backups/restore-filesystem.md b/docs/howto/filesystem-management/filesystem-backups/restore-filesystem.md index 52e2a1fc2..ddb6f04da 100644 --- a/docs/howto/filesystem-management/filesystem-backups/restore-filesystem.md +++ b/docs/howto/filesystem-management/filesystem-backups/restore-filesystem.md @@ -25,18 +25,24 @@ To restore a home directory from a snapshot, we need to create a new EBS volume Please follow AWS's guidance for [restoring EBS volumes from a snapshot](https://docs.aws.amazon.com/prescriptive-guidance/latest/backup-recovery/restore.html#restore-files) to create a new EBS volume from the snapshot. ``` -Once we have created a new EBS volume from the snapshot, we need to mount it to the EC2 instance attached to the existing EBS volume containing the NFS home directories. To do this, we need to find the instance ID of the EC2 instance attached to the existing EBS volume. This involves the following steps: +Once we have created a new EBS volume from the snapshot, we can use the `deployer exec` command to mount the new EBS volume to a pod along with the existing NFS home directories volume. -1. Go to the EBS volumes page in the AWS console -2. Find the volume ID of the existing EBS volume containing the NFS home directories -3. Click on the volume ID and find the instance ID in the "Attached resources" section -4. Once we have the instance ID, we can mount the new EBS volume to the EC2 instance by following the steps outlined in the [Attaching an Amazon EBS volume to an instance](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebs-attaching-volume.html) guide. +```bash +deployer exec root-homes --restore-volume-id= --restore-mount-path=/restore-volume --restore-volume-size=100Gi +``` + +Now, the NFS home directories volume is mounted to the pod along with the new EBS volume. We can now copy the contents from the restored EBS volume to the NFS home directories volume. + +If we want to do a full restore and/or we are restoring data to a new and empty NFS home directories volume, we can use the following command to copy everything from the restored EBS volume to the NFS home directories volume. + +```bash +rsync -av --info=progress2 /restore-volume/ /root-homes/ +``` -Once we have mounted the new EBS volume to the EC2 instance, we can copy the contents from the restored EBS volume to the NFS home directories volume. This can be done by running the following commands on the EC2 instance: +If we want to do a partial restore and we are restoring only a subset of the data to an existing NFS home directories volume, we can use the following command to copy only the necessary data from the restored EBS volume to the NFS home directories volume. ```bash -# Copy the contents from the restored EBS volume to the NFS home directories volume -rsync -av --info=progress2 +rsync -av --info=progress2 /restore-volume/ /root-homes/ ``` Once we have copied the contents from the restored EBS volume to the NFS home directories volume, we can delete the EBS volume that was created from the snapshot.