From 544d7965c6309267e52c8b2ae47bd3527f8365d4 Mon Sep 17 00:00:00 2001 From: Lyndon-Li Date: Wed, 27 Mar 2024 11:19:36 +0800 Subject: [PATCH] data mover micro service design Signed-off-by: Lyndon-Li --- changelogs/unreleased/7576-Lyndon-Li | 1 + .../vgdp-micro-service/vgdp-micro-service.md | 201 ++++++++++++++++++ design/vgdp-micro-service/vgdp-ms-1.png | Bin 0 -> 27690 bytes design/vgdp-micro-service/vgdp-ms-2.png | Bin 0 -> 37881 bytes design/vgdp-micro-service/vgdp-ms-3.png | Bin 0 -> 28578 bytes .../volume-snapshot-data-movement.md | 16 +- 6 files changed, 210 insertions(+), 8 deletions(-) create mode 100644 changelogs/unreleased/7576-Lyndon-Li create mode 100644 design/vgdp-micro-service/vgdp-micro-service.md create mode 100644 design/vgdp-micro-service/vgdp-ms-1.png create mode 100644 design/vgdp-micro-service/vgdp-ms-2.png create mode 100644 design/vgdp-micro-service/vgdp-ms-3.png diff --git a/changelogs/unreleased/7576-Lyndon-Li b/changelogs/unreleased/7576-Lyndon-Li new file mode 100644 index 000000000..7ba7086df --- /dev/null +++ b/changelogs/unreleased/7576-Lyndon-Li @@ -0,0 +1 @@ +Add the design for data mover micro service \ No newline at end of file diff --git a/design/vgdp-micro-service/vgdp-micro-service.md b/design/vgdp-micro-service/vgdp-micro-service.md new file mode 100644 index 000000000..8d777e17e --- /dev/null +++ b/design/vgdp-micro-service/vgdp-micro-service.md @@ -0,0 +1,201 @@ +# VGDP Micro Service For Volume Snapshot Data Movement + +## Glossary & Abbreviation + +**VGDP**: The collective of modules that is introduced in [Unified Repository design][1]. Velero uses these modules to finish data transmission for various purposes. It includes uploaders and the backup repository. +**Volume Snapshot Data Movement**: The backup/restore method introduced in [Volume Snapshot Data Movement design][2]. It backs up snapshot data from the volatile and limited production environment into the durable, heterogeneous and scalable backup storage. +**VBDM**: Velero Built-in Data Mover as introduced in [Volume Snapshot Data Movement design][2], it is the built-in data mover shipped along with Velero. +**Exposer**: Exposer is introduced in [Volume Snapshot Data Movement design][2] and is used to expose the volume snapshots/target volumes for VGDP to access locally. + +## Background +As the architecture introduced in [Volume Snapshot Data Movement design][2], VGDP instances are running inside the node-agent pods, however, more and more use cases require to run the VGDP instances in dedicated pods, or in another word, make them as micro services, the benefits are as below: +- This avoids VGDP to access volume data through host path, while host path access involves privilege escalations in some environments (e.g., must run under privileged mode), which makes challenge to users. +- This enable users to to control resource (i.e., cpu, memory) request/limit in a granular manner, e.g., control them per backup/restore of a volume +- This increases the resilience, crash of one VGDP activity won't affect others +- In the cases that the backup storage must be represented by a Kubernetes persistent volumes (i.e., nfs storage, [COSI][3]), this avoids to dynamically mount the persistent volumes to node-agent pods and cause node-agent pods to restart (this is not accepted since node-agent lose it current state after its pods restart) +- This prevents unnecessary full backup. Velero's fs uploaders support file level incremental backup by comparing the file name and metadata. However, at present the files are visited by host path, while pod and PVC's ID are part of the host path, so once the pod is recreated, the same file is regarded as a different file since the pod's ID has been changed. If the fs uploader is in a dedicated pod and files are visited by pod's volume path, files' full path are not changed after pod restarts, so incremental backups could continue. + +## Goals +- Create a solution to make VGDP instances as micro services +- Modify the VBDM to offload the VGDP work from node-agent to the VGDP micro service +- Create the mechanism for VBDM to control and monitor the VGDP micro services in various scenarios + +## Non-Goals +- The current solution covers Volume Snapshot Data Movement backup/restore type only, even though VGDP is also used by pod volume backup. It is less possible to do this for pod volume backup, since it must run inside the source workload pods. +- The current solution covers VBDM only. 3rd data movers still follow the **Replacement** section of [Volume Snapshot Data Movement design][2]. That is, 3rd data movers handle the DUCR/DDCR on their own and they are free to make themselves micro service style or monolith service style. + + +## Overview +The solution is based on [Volume Snapshot Data Movement design][2], the architecture is followed as is and existing components are not changed unless it is necessary. +Below lists the changed components, why and how: +**Exposer**: Exposer is to expose the snapshot/target volume as a path/device name/endpoint that are recognizable by VGDP. Varying from the type of snapshot/target volume, a pod may be created as part of the expose. Now, since we run the VGDP instance in a separate pod, a pod is created anyway, we assume exposer creates a pod all the time and make the appropriate exposing configurations to the pod so that VGDP instance could access the snapshot/target volume locally inside the pod. The pod is still called as backupPod or restorePod. +Then we need to change the command the backupPod/restorePod is running, the command launches VGDP-MS (VGDP Micro Service, see below) when the container starts up. +For CSI snapshot, the backupPod/restorePod is created as the result of expose, the only thing left is to change the backupPod/restorePod's image. +**VBDM**: VBDM contains the data mover controller, while the controller calls the Exposer and launches the VGDP instances. Now, since the VGDP instance is launched by the backupPod/restorePod, the controller should not launch the VGDP instance again. However, the controller still needs to monitor and control the VGDP instance. Moreover, in order to avoid any contest situations, the controller is still the only place to update DUCRs and DDCRs. + +Besides the changes to above existing components, we need to add below new components: +**VGDP Watcher**: We create a new module to help the data mover controller to watch activities of the VGDP instance in the backupPod/restorePod. VGDP Watcher is a part of VBDM. +**VGDP-MS**: VGDP Micro Service is the binary for the command backupPod/restorePod runs. It accepts the parameters and then launches the VGDP instance according to the request type, specifically, backup or restore. VGDP-MS also runs other modules to sync-up with the data mover controller. VGDP-MS is also a part of VBDM. + +Below diagram shows how these components work together: +![vgdp-ms-1.png](vgdp-ms-1.png) + +The [Node-agent concurrency][4] is still used to control the concurrency of VGDP micro services. When there are too many volumes in the backup/restore, which takes too much computing resources(CPU, memory, etc.) or Kubernetes resources(pods, PVCs, PVs, etc.), users could set the concurrency in each node so as to control the total number of concurrent VGDP micro services in the cluster. + +## Detailed Design +### Exposer +At present, the exposer creates backupPod/restorePod and sets ```velero-helper pause``` as the command run by backupPod/restorePod. +Now, VGDP-MS command will be used, and the ```velero``` image will be running inside the backupPod/restorePod. The command is like below: +```velero data-mover backup --volume-path xxx --volume-mode xxx --data-upload xxx --resource-timeout xxx --log-format xxx --log-level xxx``` +Or: +```velero data-mover restore --volume-path xxx --volume-mode xxx --data-download xxx --resource-timeout xxx --log-format xxx --log-level xxx``` + +The first one is for backup and the other one is for restore. +Below are the parameters of the commands: +**volume-path**: Deliver the full path inside the backupPod/restorePod for the volume to be backed up/restored. +**volume-mode**: Deliver the mode for the volume be backed up/restored, at present either ```Filesystem``` mode or ```Block``` mode. +**data-upload**: DUCR for this backup. +**data-download**: DDCR for this backup. +**resource-timeout**: resource-timeout is used to control the timeout for operations related to resources. It has the same meaning with the resource-timeout for node-agent. +**log-format** and **log-level**: This is to control the behavior of log generation inside VGDP-MS. + +In order to have the same capability and permission with node-agent, below pod configurations are inherited from node-agent and set to backupPod/restorePod's spec: +- Volumes: Some configMaps will be mapped as volumes to node-agent, so we add the same volumes of node-agent to the backupPod/restorePod +- Environment Variables +- Security Contexts +We may not actually need all the capabilities in the VGDP-MS as the node-agent. At present, we just duplicate all of them, if we find any problem in future, we can filter out the capabilities that are not required by VGDP-MS. +The backupPod/restorePod is not run in Privileged mode as it is not required since the volumes are visisted by pod path. +The root user is still required, especially by the restore (in order to restore the file system attributes, owners, etc.), so we will use root user for backupPod/restorePod. +We set backupPod/restorePod's ```RestartPolicy``` to ```RestartPolicyNever```, so that once VGDP-MS terminates in any reason, backupPod/restorePod won't restart and the DUCR/DDCR is marked as one of the terminal phases (Completed/Failed/Cancelled) accordingly. + + +### VGDP Watcher +#### Dual mode event watch +The primary task of VGDP Watcher is to watch the status change from backupPod/restorePod or the VGDP instance, so as to inform the data mover controller in below situations: +- backupPod/restorePod starts +- VGDP instance starts +- Progress update +- VGDP instance completes/fails/cancelled +- backupPod/restorePod stops + +We use two mechanism to make the watch: +**Pod Phases**: VGDP Watcher watches the backupPod/restorePod's phases updated by Kubernetes. That is, VGDP Watcher creates an informer to watch the pod resource for the backupPod/restorePod and detect that the pod reaches to one of the terminated phases (i.e., PodSucceeded, PodFailed). We also check the availability & status of the backupPod/restorePod at the beginning of the watch so as to detect the starting of the backupPod/restorePod. +**Custom Kubernetes Events**: VGDP-MS generates Kubernetes events and associates them to the DUCR/DDCR at the time of VGDP instance starting/stopping and progress update, then VGDP Watcher creates another informer to watch the Event resource associated to the DUCR/DDCR. + +Pod Phases watch covers the entire lifecycle of the backupPod/restorePod, but we don't know the status of the VGDP instance through it; and it can only deliver information by then end of the pod lifecycle. +Custom Event watch generates details of the VGDP instances and the events could be generated any time; but it cannot generate notifications before VGDP starts or in the case that VGDP crashes or shutdown abnormally. + +Therefore, we adopt the both mechanisms to VGDP Watcher. In the end, there will be two sources generating the result of VGDP-MS: +- The termination message of backupPod/restorePod +- The message along with the VGDP Instance Completes/Fails/Cancelled event + +On the one hand, in some cases only the backupPod/restorePod's termination message is available, e.g., the backupPod/restorePod crashes or or backupPod/restorePod quits before VGDP instance is started. So we refer to the first mechanism to get the notifications. +On the other hand, if they are both available, we have the results from them for mutual verification. + +Conclusively, under the help of VGDP Watcher, data mover controller starts VGDP-MS controllably and waits until VGDP-MS ends under any circumstances. + +#### AsyncBR adapter +VGDP Watcher needs to notify the data mover controller when one of the watched event happens, so that the controller could do the operations as if it receives the same callbacks from VGDP as the current behavior. In order not to break the existing code logics of data mover controllers, we make VGDP Watcher as an adapter of AsyncBR which is the interface implemented by VGDP and called by the data mover controller. +Since the parameters to call VGDP Watcher is different from the ones to call VGDP, we change the AsyncBR interface to hide some parameters from one another, the new interface is as below: +``` +type AsyncBR interface { + // Init initializes an asynchronous data path instance + Init(ctx context.Context, res *exposer.ExposeResult, param interface{}) error + + // StartBackup starts an asynchronous data path instance for backup + StartBackup(dataMoverConfig map[string]string, param interface{}) error + + // StartRestore starts an asynchronous data path instance for restore + StartRestore(snapshotID string, dataMoverConfig map[string]string) error + + // Cancel cancels an asynchronous data path instance + Cancel() + + // Close closes an asynchronous data path instance + Close(ctx context.Context) +} +``` +Some parameters are hidden into ```param```, but the functions and calling logics are not changed. + +VGDP Watcher should be launched by the data mover controller before VGDP instance starts, otherwise, multiple corner problems may happen. E.g., VGDP-MS may run the VGDP instance immediately after the backupPod/restorePod is launched and completes it before the data mover controller starts VGDP Watcher, as a result, multiple informs are missed from VGDP Watcher. +Therefore, the controller launches VGDP Watcher first and then set the DUCR/DDCR to ```InProgress```; on the other hand, VGDP-MS waits DUCR/DDCR turns to ```InProgress``` before running the VGDP instance. + +### VGDP-MS +VGDP-MS is represented by ```velero data-mover``` subcommand and has its own subcommand ```backup``` and ```restore```. +Below diagram shows the VGDP-MS workflow: +![vgdp-ms-2.png](vgdp-ms-2.png) + +**Start DUCR/DDCR Watcher**: VGDP-MS needs to watch the corresponding DUCR/DDCR so as to react on some events happening to the DUCR/DDCR. E.g., when the data movement is cancelled, a ```Cancel``` flag is set to the DUCR/DDCR, by watching the DUCR/DDCR, VGDP-MS is able to see it and cancel the VGDP instance. +**Wait DUCR/DDCR InProgress**: As mentioned above, VGDP-MS won't start the VGDP instance until DUCR/DDCR turns to ```InProgress```, by which time VGDP Watcher has been started. +**Record VGDP Starts**: This generates the VGDP Instance Starts event. +**VGDP Callbacks**: When VGDP comes to one of the terminal states (i.e., completed, failed, cancelled), the corresponding callback is called. +**Record VGDP Ends**: This generates the VGDP Instance Completes/Fails/Cancelled event, and also generates backupPod/restorePod termination message. +**Record VGDP Progress**: This periodically generates/updates the Progress event with totalBytes/bytesDone to indicate the progress of the data movement. +**Set VGDP Output**: This writes the termination message to the backupPod/restorePod's termination log (by default, it is written to ```/dev/termination-log```). + +If VGDP completes, VGDP Instance Completes event and backupPod/restorePod termination shares the same message as below: +``` +type BackupResult struct { + SnapshotID string `json:"snapshotID"` + EmptySnapshot bool `json:"emptySnapshot"` + Source exposer.AccessPoint `json:"source,omitempty"` +} +``` +``` +type RestoreResult struct { + Target exposer.AccessPoint `json:"target,omitempty"` +} +``` +``` +type AccessPoint struct { + ByPath string `json:"byPath"` + VolMode uploader.PersistentVolumeMode `json:"volumeMode"` +} +``` + +The existing VGDP result structures are actually being reused, we just add the json markers so that they can be marshalled. + +As mentioned above, once VGDP-MS ends in any way, the backupPod/restorePod terminates and never restarts, so the end of VGDP-MS means the end of DU/DD. + +For Progress update, the existing Progress structure is being reused: +``` +type Progress struct { + TotalBytes int64 `json:"totalBytes,omitempty"` + BytesDone int64 `json:"doneBytes,omitempty"` +} +``` + +### Log Collection +During the running of VGDP instance, some logs are generated which are important for troubleshooting. This includes all the logs generated by the uploader and repository. Therefore, it is important to collect these logs. +On the other hand, the logs are now generated in the backupPod/restorePod, while the backupPod/restorePod is deleted immediately after the data movement completes. Therefore, by default, ```velero debug``` is not able to collect these logs. + +As a solution, we use logrus's hook mechanism to redirect the backupPod/restorePod's logs into node-agent's log, so that ```velero debug``` could collect VGDP logs as is without any changes. + +Below diagram shows how VGDP logs are redirected: +![vgdp-ms-3.png](vgdp-ms-3.png) + +This log redirecting mechanism is thread safe since the hook acquires the write lock before writing the log buffer, so it guarantees that in the node-agent log there is no corruptions after redirecting the log, and the redirected logs and the original node-agent logs are not projected into each other. + +## node-agent +node-agent is still required. Even though VGDP is now not running inside node-agent, node-agent still hosts the data mover controller which reconciles DUCR/DDCR and operates DUCR/DDCR in other steps before the VGDP instance is started, i.e., Accept, Expose, etc. +Privileged mode and root user are not required for node-agent anymore by Volume Snapshot Data Movement, however, they are still required by PVB(PodVolumeBackup) and PVR(PodVolumeRestore). Therefore, we will keep the node-agent deamonset as is, for any users who don't use PVB/PVR and have concern about the privileged mode/root user, they need to manually modify the deamonset spec to remove the dependencies. + +## CRD Changes +There is no changes to any CRD. + +## Installation Changes +No changes to installation, the backupPod/restorePod's configurations are all inherited from node-agent. + +## Upgrade +Upgrade is not impacted. + +## CLI +CLI is not changed. + + + +[1]: ../Implemented/unified-repo-and-kopia-integration/unified-repo-and-kopia-integration.md +[2]: ../volume-snapshot-data-movement/volume-snapshot-data-movement.md +[3]: https://kubernetes.io/blog/2022/09/02/cosi-kubernetes-object-storage-management/ +[4]: ../Implemented/node-agent-concurrency.md + diff --git a/design/vgdp-micro-service/vgdp-ms-1.png b/design/vgdp-micro-service/vgdp-ms-1.png new file mode 100644 index 0000000000000000000000000000000000000000..b4758ef06565ae43b713ece70d07f6d86cf3b753 GIT binary patch literal 27690 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 literal 0 HcmV?d00001 diff --git a/design/vgdp-micro-service/vgdp-ms-2.png b/design/vgdp-micro-service/vgdp-ms-2.png new file mode 100644 index 0000000000000000000000000000000000000000..49898fc87dceb553def12e2fa489f409ccfed5e9 GIT binary patch literal 37881 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 Hr*HokG71vv literal 0 HcmV?d00001 diff --git a/design/vgdp-micro-service/vgdp-ms-3.png b/design/vgdp-micro-service/vgdp-ms-3.png new file mode 100644 index 0000000000000000000000000000000000000000..195d9589b5edbf55a003f9d91e1ca25d79ae21d4 GIT binary patch literal 28578 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 literal 0 HcmV?d00001 diff --git a/design/volume-snapshot-data-movement/volume-snapshot-data-movement.md b/design/volume-snapshot-data-movement/volume-snapshot-data-movement.md index d04a6d5b3..2b91c764e 100644 --- a/design/volume-snapshot-data-movement/volume-snapshot-data-movement.md +++ b/design/volume-snapshot-data-movement/volume-snapshot-data-movement.md @@ -37,7 +37,7 @@ Moreover, we would like to create a general workflow to variations during the da ## Architecture of Volume Snapshot Data Movement -## Workflows +### Workflows Here are the diagrams that illustrate components and workflows for backup and restore respectively. For backup, we intend to create an extensive architecture for various snapshot types, snapshot accesses and various data accesses. For example, the snapshot specific operations are isolated in Data Mover Plugin and Exposer. In this way, we only need to change the two modules for variations. Likely, the data access details are isolated into uploaders, so different uploaders could be plugged into the workflow seamlessly. @@ -52,7 +52,7 @@ Below is the backup workflow: Below is the restore workflow: ![restore-workflow.png](restore-workflow.png) -## Components +### Components Below are the generic components in the data movement workflow: **Velero**: Velero controls the backup/restore workflow, it calls BIA/RIA V2 to backup/restore an object that involves data movement, specifically, a PVC or a PV. @@ -69,13 +69,13 @@ DMs take the responsibility to handle DUCR/DDCRs, Velero provides a built-in DM **Velero Generic Data Path (VGDP)**: VGDP is the collective of modules that is introduced in [Unified Repository design][1]. Velero uses these modules to finish data transmission for various purposes. In includes uploaders and the backup repository. **Uploader**: Uploader is the module in VGDP that reads data from the source and writes to backup repository for backup; while read data from backup repository and write to the restore target for restore. At present, only file system uploader is supported. In future, the block level uploader will be added. For file system and basic block uploader, only Kopia uploader will be used, Restic will not be integrated with VBDM. -## Replacement +### Replacement 3rd parties could integrate their own data movement into Velero by replacing VBDM with their own DMs. The DMs should process DUCR/DDCRs appropriately and finally put them into one of the terminal states as shown in the DataUpload CRD and DataDownload CRD sections. Theoretically, replacing the DMP is also allowed. In this way, the entire workflow is customized, so this is out of the scope of this design. -# Detailed Design +## Detailed Design -## Backup Sequence +### Backup Sequence Below are the data movement actions and sequences during backup: ![backup-sequence.png](backup-sequence.png) @@ -150,7 +150,7 @@ We keep VGDP reused for VBDM, so everything inside VGDP are kept as is. For deta When VGDP completes backup, it returns an ID that represent the root object saved into the backup repository for this backup, through the root object, we will be able to enumerate the entire backup data. This Repo Snapshot ID will be saved along with the DUCR. -## DataUpload CRD +### DataUpload CRD Below are the essential fields of DataUpload CRD. The CRD covers below information: - The information to manipulate the specified snapshot - The information to manipulate the specified data mover @@ -351,7 +351,7 @@ spec: ``` -## Restore Sequence +### Restore Sequence Below are the data movement actions sequences during restore: ![restore-sequence.png](restore-sequence.png) @@ -387,7 +387,7 @@ This also means that Velero should not restore the PV if a data movement restore For restore, VBDM doesn’t need to persist anything. -## DataDownload CRD +### DataDownload CRD Below are the essential fields of DataDownload CRD. The CRD covers below information: - The information to manipulate the target volume - The information to manipulate the specified data mover