# Snapshot & Restore > Note: Based on thin-provisioning of volumes. Please refer to [thin-provisioning proposal doc](https://github.com/topolvm/topolvm/pull/442). ## Goals Allow users to create thin-snapshots from thinly-provisioned logical volumes. These thin-snapshots, then set the foundation for allowing creation of snapshots and clones of persistent volume claims. * **Allow Snapshot Creation**: Enable users to take snapshots of PVs that are provisioned by TopoLVM. * **Restoring Snapshots**: Based on a volumesnapshot, a new PVC can be created that contains the contents of the snapshot. * **Create Clones**: Allow users to create PVC to PVC clones; in which the clones are independent of the parent volumes. ## Introduction ### Thin-Snapshots * Snapshots of thin LVs are efficient because the data blocks common to a thin LV and its snapshot are shared. * As common data blocks are shared, A thin snapshot volume can reduce disk usage when there are multiple snapshots of the same origin volume. * The thin snapshot volume is independent of parent volume deletion; and can be used independently just like a standalone volume. * These thin logical volumes can be activated as `Read-Only` copies of the parent, and provided to kubernetes users as a VolumeSnapshotContent. ### Creating PVC Clones using thin-snapshots * By design, a thin-snapshot of thin-volumes behave just as a new thinly-provisioned volume which is pre-populated with data from the parent. * Thus, this thin-snapshot can be then provided to an user for Read-Write operations; on which, writes are performed on a Copy-On-Write basis (fast clones!). * These thin logical volumes can be activated as `Read-Write` copies of the parent, and provided to kubernetes users as a PersistentVolume object. * The PVC Clones created using thin-snapshots will also be `copy-on-write`, so increasing the number of clones of the origin should yield no major slowdown. > Note: Although both kubernetes snapshots and clones are thin-snapshots internally, their access is set by activating them for required permissions. So, a snapshot is just activated for Read-Only mode, on the other hand, clones are activated to allow Read-Write operations by a user. ### Restoring thin-snapshots * Thin snapshot volumes can be used as a logical volume origin for another snapshot. This allows for an arbitrary depth of recursive snapshots (snapshots of snapshots of snapshots ... ) * Blocks common to recursive snapshots are also shared in the thin pool. There is no limit to or degradation from sequences of snapshots. * To provide a restored PVC to the user, we create another thin-provisioned snapshot of the available snapshot; and since lvm snapshots, by design, are writable, so they can be provided to users to use as a volume for a new PVC. * This way, we also don't lose the identity of the snapshot after restoring; so we can restore a snapshot multiple times, to create multiple copies. * These thin snapshot volumes are activated as `Read-Write` copies of the parent, and provided to kubernetes users as a PersistentVolume object. ![](https://i.imgur.com/bwsK1Dl.png) > Note: The Snapshots, Restored volumes and Clones are all independent of their parent deletion. ## Flow of Operations for Snapshot Creation * An user creates a `VolumeSnapshot` custom resource. * The `snapshot-controller` which was watching the `VolumeSnapshot` object, sends a `Create VolumesnapshotContent` req to the api-server. * The `external-snapshotter` kubernetes sidecar receives this request, and then sends a `CreateSnapshot` gRPC call to TopoLVM CSI driver. * This `CreateSnapshot` request is received by the `topolovm-controller` which then create a `LogicalVolume` CR. * `topolvm-node` on the target node finds the earlier created `LogicalVolume` CR. * `topolvm-node` sends a volume create request to lvmd to create a thin-snapshot from the thin-volume datasource. * `lvmd` creates an LVM logical volume as requested. * `topolvm-node` updates the status of LogicalVolume. * `topolvm-controller` finds the updated status of LogicalVolume. * `topolvm-controller` sends the success (or failure) to `external-snapshotter` sidecar. ## Proposed LogicalVolume CR for Snapshots ```yaml apiVersion: topolvm.cybozu.com/v1 kind: LogicalVolume metadata: name: snapcontent-b083470e-8293-47cc-810d-9561bd1754e6 # restore pv name annotations: spec: name: snapcontent-b083470e-8293-47cc-810d-9561bd1754e6 nodeName: 192.168.26.40 # 'snapshot' is an optional field, that needs to specified only # in case of snapshot logical volume creation. snapshot: # 'type' specifies if the snapshot will be thick or thin provisioned. type: thin # 'dataSource' specifies the volumeID of the parent logical volume. dataSource: <string> # 'accessType' specifies how the user intents to consume the # thin-snapshot logical volume. # If the thin-snap lv is to be provided to user as a snapshot, # the accessType will be Read-Only. # On the other hand, if the lv is to be given as a persistent volume, # the accessType should be set to allow Read-Write operations. accessType: ro status: volumeID: <Store the volume id of the lvm snapshot as same as existing LV.> ``` ### Alternate Design of LogicalVolume CR for Snapshots ```yaml apiVersion: topolvm.cybozu.com/v1 kind: LogicalVolume metadata: name: snapcontent-b083470e-8293-47cc-810d-9561bd1754e6 annotations: spec: name: snapcontent-b083470e-8293-47cc-810d-9561bd1754e6 nodeName: 192.168.26.40 # type: optional parameter, needs to be mentioned only in case of snapshots type: thin-snapshot accessType: ro # dataSource field is nil when normal allocation. It specifies the volumeID of the parent logical volume(if present). dataSource: <string> status: volumeID: <Store the volume id of the lvm snapshot as same as existing LV.> ``` ## Proposed LogicalVolume CR for Restore operation ```yaml apiVersion: topolvm.cybozu.com/v1 kind: LogicalVolume metadata: name: pvc-42041aee-79a2-4184-91aa-5e1df6068b9f # restore pv name annotations: spec: name: pvc-42041aee-79a2-4184-91aa-5e1df6068b9f nodeName: 192.168.26.40 # 'snapshot' is an optional field, that needs to specified only # in case of snapshot logical volume creation. snapshot: # 'type' specifies if the snapshot will be thick or thin provisioned. type: thin # 'dataSource' specifies the volumeID of the parent logical volume. dataSource: <string> # 'accessType' specifies how the user intents to consume the # thin-snapshot logical volume. # If the thin-snap lv is to be provided to user as a snapshot, # the accessType can be Read-Only. # On the other hand, if the lv is to be given as a persistent volume (clone/restore), # the accessType should be set to allow Read-Write operations. accessType: rw status: volumeID: <Store the volume id of the lvm snapshot as same as existing LV.> ``` ### Alternate LogicalVolume CR for Restore operation ```yaml apiVersion: topolvm.cybozu.com/v1 kind: LogicalVolume metadata: name: pvc-42041aee-79a2-4184-91aa-5e1df6068b9f # restore pv name annotations: spec: name: pvc-42041aee-79a2-4184-91aa-5e1df6068b9f nodeName: 192.168.26.40 type: thin-snapshot # 'accessType' specifies how the user intents to consume the # thin-snapshot logical volume. # If the thin-snap lv is to be provided to user as a snapshot, # the accessType can be Read-Only. # On the other hand, if the lv is to be given as a persistent volume, # the accessType should be set to allow Read-Write operations. accessType: rw # dataSource field is nil when normal allocation. # It specifies the volumeID of the parent logical volume. dataSource: <string> status: volumeID: <Store the volume id of the lvm snapshot as same as existing LV.> ``` ## LV Operations * Snapshot creation from a thinly-provisioned volume: ```bash $ lvcreate -s --name thinsnap VG0/thinvolume ``` * Activation of a logical volume * A thinly-provisioned snapshot will be activated as Read-Only for snapshots and Read-Write for Clone/Restore scenarios. For e.g: Activating a logical volume for Read-Write operations: ```bash $ lvchange -ay -K VG0/thinsnap ``` * Restoring a Snapshot ```bash $ lvcreate -s --name thin-restored VG0/thinsnap ``` ## Deployment Changes * Add `external-snapshotter` sidecar. * Perform `snapshot-controller` deployment. ## Metrics and Monitoring Should be already covered during adding support for `thin` logical volumes. See [thin-provisioning proposal doc](https://github.com/topolvm/topolvm/pull/442). ## Additional Notes * When creating a thin snapshot volume, you do not specify the size of the volume. * Thin snapshot volumes are not supported across the nodes in a cluster. The snapshot volume must be exclusively activated on only one cluster node. # Cloning On creation of a thinly-provisioned snapshot volume from the parent, it becomes an independent thinly-provisioned volume. By design, thin-snapshots of thin-volumes behave as new thinly-provisioned volumes which are pre-populated with data from the parent. Thus, this thin-snapshot can be then provided to an user for rw operations(clones); on which, writes are performed on a Copy-On-Write basis (fast clones!). ![](https://i.imgur.com/bdyqraR.png) ## Proposed LogicalVolume CR for Clone operation ```yaml apiVersion: topolvm.cybozu.com/v1 kind: LogicalVolume metadata: name: pvc-42041aee-79a2-4184-91aa-5e1df6068b9f # restore pv name annotations: spec: name: pvc-42041aee-79a2-4184-91aa-5e1df6068b9f nodeName: 192.168.26.40 # 'snapshot' is an optional field, that needs to specified only # in case of snapshot logical volume creation. snapshot: # 'type' specifies if the snapshot will be thick or thin provisioned. type: thin # 'dataSource' specifies the volumeID of the data source. dataSource: <string> # 'accessType' specifies how the user intents to consume the # thin-snapshot logical volume. # If the thin-snap lv is to be provided to user as a snapshot, # the accessType can be Read-Only. # On the other hand, if the lv is to be given as a persistent volume (clone/restore), # the accessType should be set to allow Read-Write operations. accessType: rw status: volumeID: <Store the volume id of the lvm snapshot as same as existing LV.> ``` ### Alternate LogicalVolume CR for Clone operations ```yaml apiVersion: topolvm.cybozu.com/v1 kind: LogicalVolume metadata: name: pvc-42041aee-79a2-4184-91aa-5e1df6068b9f # clone pv name annotations: spec: name: pvc-42041aee-79a2-4184-91aa-5e1df6068b9f nodeName: 192.168.26.40 type: thin-snapshot accessType: rw # dataSource field is nil when normal allocation. dataSource: <string> status: volumeID: <Store the volume id of the lvm snapshot as same as existing LV.> ``` ## Deployment Changes No deployment changes required for adding support for cloning feature. ## Metrics and Monitoring Should be already covered during adding support for `thin` logical volumes. ## Open Questions - Should we only allow thick snapshot creation for thick volumes and thin-snapshots for thinly-provsioned volumes? - If yes, then we don't need to specify `type` parameter for snapshot volumes in the LogicalVolume CR; as we can assume thin-snapshots if the parent is a thinly-provisioned volume.