VolumeReplicationGroup CRD
VolumeReplicationGroup CRD
Overview
The VolumeReplicationGroup (VRG) custom resource manages volume replication and Kubernetes object protection for an application on a managed cluster. VRGs are not directly created by users - they are automatically created and managed by the DRPlacementControl (DRPC) on the hub cluster via ManifestWork.
A VRG controls:
- Volume replication state (Primary/Secondary) for all PVCs matching the selector
- VolumeReplication or VolSync resource creation and management for data replication
- PV metadata storage in S3 for cross-cluster recovery
- Kubernetes object capture and recovery (via Velero and Recipe)
Lifecycle: Created by DRPC when enabling DR protection. Exists on the active cluster as Primary and on the peer cluster as Secondary. Deleted when DRPC is removed.
API Group and Version
- API Group:
ramendr.openshift.io - API Version:
v1alpha1 - Kind:
VolumeReplicationGroup - Short Name:
vrg - Scope: Namespaced (on managed clusters)
Spec Fields
Required Fields
pvcSelector (metav1.LabelSelector)
Label selector to identify PVCs that should be replicated as part of this group.
Example:
pvcSelector:
matchLabels:
app: myapp
replicationState (ReplicationState)
Desired replication state for all volumes in this group.
Valid values:
primary- Volumes are primary (writable), source of replicationsecondary- Volumes are secondary (read-only), target of replication
Example:
replicationState: primary
Important: This is managed by DRPC. When DRPC orchestrates Failover or
Relocate actions, it changes this from primary->secondary on the source and
secondary->primary on the target as required.
s3Profiles ([]string)
List of S3 profile names (from RamenConfig) used to store PV metadata.
Example:
s3Profiles:
- s3-profile-east
Purpose: PV and PVC specs are stored in S3 so the peer cluster can recreate them during failover or relocation.
Optional Fields
async (VRGAsyncSpec)
Configuration for Regional DR (asynchronous replication across regions).
Fields:
replicationClassSelector(metav1.LabelSelector) - Selects VolumeReplicationClassvolumeSnapshotClassSelector(metav1.LabelSelector) - Selects VolumeSnapshotClass (for VolSync async)volumeGroupSnapshotClassSelector(metav1.LabelSelector) - For volume group snapshotsschedulingInterval(string) - Replication frequency (e.g., “1h”, “30m”)peerClasses([]PeerClass) - Storage class peer relationships
Example:
async:
schedulingInterval: "1h"
replicationClassSelector:
matchLabels:
ramendr.openshift.io/replication-class: rbd-replication
sync (VRGSyncSpec)
Configuration for Metro DR (synchronous replication within same metro area).
Fields:
peerClasses([]PeerClass) - Storage class peer relationships
Example:
sync:
peerClasses:
- storageClassName: csi-cephfs
replicationID: cephfs-replication
volSync (VolSyncSpec)
Configuration for VolSync-based replication.
Fields:
disabled(bool) - Set to true to bypass VolSyncrdSpec([]VolSyncReplicationDestinationSpec) - ReplicationDestination specs for Secondary VRGmoverConfig([]MoverConfig) - Advanced VolSync mover configuration
Example:
volSync:
disabled: false
action (VRGAction)
The DR action being performed: Failover or Relocate.
Values:
Failover- Unplanned recoveryRelocate- Planned migration
Managed by: DRPC sets this field.
kubeObjectProtection (KubeObjectProtectionSpec)
Configuration for protecting Kubernetes objects (not just PVCs).
Fields:
captureInterval(metav1.Duration) - How often to capture objects (default: 5m)recipeRef(RecipeRef) - Reference to Recipe for custom workflowsrecipeParameters(map[string][]string) - Parameters for RecipekubeObjectSelector(metav1.LabelSelector) - Selector for objects to protect
Example:
kubeObjectProtection:
captureInterval: 5m
recipeRef:
name: mysql-recipe
namespace: mysql-app
protectedNamespaces ([]string)
List of namespaces to protect beyond the VRG namespace.
Requirements:
- VRG must be in RamenOpsNamespace
- Resources treated as unmanaged
- Typically used with Recipes
Example:
protectedNamespaces:
- app-frontend
- app-backend
prepareForFinalSync (bool)
Indicates VRG should prepare for the final sync during relocate (VolSync only).
Managed by: DRPC sets this during relocate operations.
runFinalSync (bool)
Indicates VRG should perform the final sync during relocate (VolSync only).
Managed by: DRPC sets this during relocate operations.
Status Fields
state (State)
Current replication state of the VRG.
Values:
Primary- VRG is successfully primarySecondary- VRG is successfully secondaryUnknown- State cannot be determined
protectedPVCs ([]ProtectedPVC)
List of PVCs that are protected by this VRG with their status.
ProtectedPVC fields:
name- PVC namenamespace- PVC namespaceprotectedByVolSync- Whether using VolSync for this PVCstorageClassName- StorageClass usedaccessModes- PVC access modesresources- Resource requirementsconditions- PVC-specific conditionslastSyncTime- Most recent sync timelastSyncDuration- Duration of last synclastSyncBytes- Bytes transferred in last sync
pvcgroups ([]Groups)
List of PVC groups for consistency group replication.
conditions ([]metav1.Condition)
Standard Kubernetes conditions for the VRG.
Common condition types:
DataReady- PV data is ready for application accessDataProtected- PV data is fully synced with remote peerClusterDataReady- PV cluster data restored and readyClusterDataProtected- PV cluster data uploaded to S3KubeObjectsReady- Kubernetes objects are ready (when using kubeObjectProtection)NoClusterDataConflict- No conflicts detected between primary and secondary
observedGeneration (int64)
The generation of the VRG spec that was last processed.
lastUpdateTime (metav1.Time)
When the status was last updated.
lastGroupSyncTime (metav1.Time)
Time of the most recent successful synchronization of all PVCs.
lastGroupSyncDuration (metav1.Duration)
Duration of the most recent group sync.
lastGroupSyncBytes (int64)
Total bytes transferred in the most recent group sync.
kubeObjectProtection (KubeObjectProtectionStatus)
Status of Kubernetes object protection.
Fields:
captureToRecoverFrom- Identifier of the capture to use for recovery
prepareForFinalSyncComplete (bool)
Whether prepare for final sync has completed (VolSync relocate).
finalSyncComplete (bool)
Whether the final sync has completed (VolSync relocate).
Examples
Example 1: Primary VRG (Managed Cluster)
This is what DRPC creates on the active cluster:
apiVersion: ramendr.openshift.io/v1alpha1
kind: VolumeReplicationGroup
metadata:
name: webapp-drpc
namespace: webapp
spec:
replicationState: primary
pvcSelector:
matchLabels:
app: webapp
s3Profiles:
- s3-profile-east
async:
schedulingInterval: "1h"
replicationClassSelector:
matchLabels:
ramendr.openshift.io/replication-class: rbd-replication
action: Relocate
kubeObjectProtection:
captureInterval: 5m
Example 2: Secondary VRG (Peer Cluster)
This is what DRPC creates on the standby cluster:
apiVersion: ramendr.openshift.io/v1alpha1
kind: VolumeReplicationGroup
metadata:
name: webapp-drpc
namespace: webapp
spec:
replicationState: secondary
pvcSelector:
matchLabels:
app: webapp
s3Profiles:
- s3-profile-west
async:
schedulingInterval: "1h"
replicationClassSelector:
matchLabels:
ramendr.openshift.io/replication-class: rbd-replication
volSync:
disabled: false
Note: Both async and volSync can be configured together. VRG decides
per-PVC which replication method to use based on available storage classes and
replication capabilities.
Example 3: Recipe-Based VRG
VRG with Recipe for custom capture/recovery workflows:
apiVersion: ramendr.openshift.io/v1alpha1
kind: VolumeReplicationGroup
metadata:
name: mysql-drpc
namespace: mysql-app
spec:
replicationState: primary
pvcSelector:
matchLabels:
app: mysql
s3Profiles:
- s3-profile-east
async:
schedulingInterval: "30m"
replicationClassSelector:
matchLabels:
ramendr.openshift.io/replication-class: rbd-replication
kubeObjectProtection:
captureInterval: 5m
recipeRef:
name: mysql-recipe
namespace: mysql-app
Understanding VRG Behavior
Primary VRG
When replicationState: primary:
- Creates VolumeReplication CRs (or ReplicationSource for VolSync) for each PVC
with
replicationState: primary - Stores PV metadata in S3
- Captures Kubernetes objects (if kubeObjectProtection is configured)
- Application can read/write to volumes
Secondary VRG
When replicationState: secondary:
- Creates VolumeReplication CRs (or ReplicationDestination for VolSync) for
each PVC with
replicationState: secondary - Volumes are read-only (no application access)
- Receives replicated data from primary
- No Kubernetes object capture (secondary is standby)
State Transitions
Initial Deployment:
- DRPC creates VRG on preferred cluster with
replicationState: primary - DRPC creates VRG on peer cluster with
replicationState: secondary
Failover:
- DRPC changes peer VRG from
secondary→primary - Application deploys on peer cluster
- Source VRG remains as
primarytill source is down, and is moved tosecondaryonce it is reachable
Relocate:
- DRPC performs final sync on source
- DRPC changes source VRG from
primary→secondary - DRPC changes target VRG from
secondary→primary - Application redeploys on target
Monitoring VRG
Note: VRG resources exist on managed clusters, not the hub. All monitoring commands below must be run on the managed cluster where the application is deployed.
Check VRG State
kubectl get vrg -n myapp
Output shows: name, desiredState, currentState.
Check Detailed Status
kubectl get vrg myapp-drpc -n myapp -o yaml
Check Protected PVCs
kubectl get vrg myapp-drpc -n myapp -o jsonpath='{.status.protectedPVCs}' | jq
Check Replication Status
# Last sync time
kubectl get vrg myapp-drpc -n myapp -o jsonpath='{.status.lastGroupSyncTime}'
# Sync bytes transferred
kubectl get vrg myapp-drpc -n myapp -o jsonpath='{.status.lastGroupSyncBytes}'
Check VolumeReplication Resources
# Created by VRG
kubectl get volumereplication -n myapp
kubectl describe volumereplication -n myapp
Troubleshooting
General Diagnosis
Check VRG status on the managed cluster:
kubectl get vrg -n myapp --context east-cluster
kubectl describe vrg myapp-drpc -n myapp --context east-cluster
VRG Not Reaching Desired State
Check: Verify VolumeReplication CRs are created and PVCs match selector.
kubectl get volumereplication -n myapp --context east-cluster
kubectl get pvc -n myapp -l app=myapp --context east-cluster
Common causes: VolumeReplicationClass not found, PVC selector mismatch, or S3 access issues.
Solution: Ensure VolumeReplicationClass exists, PVC labels match selector, and check VRG operator logs for S3 errors.
Replication Not Working
Check: Monitor lastGroupSyncTime and VolumeReplication status.
kubectl get vrg myapp-drpc -n myapp -o jsonpath='{.status.lastGroupSyncTime}' \
--context east-cluster
kubectl get volumereplication -n myapp -o yaml --context east-cluster
Common causes: Storage backend replication not configured or VRG not in primary state.
Solution: Verify storage replication is healthy and VRG state is Primary on source cluster.
VRG Stuck in Deletion
Check: Look for stuck finalizers or VolumeReplication cleanup issues.
kubectl get vrg myapp-drpc -n myapp -o jsonpath='{.metadata.finalizers}' \
--context east-cluster
kubectl get volumereplication -n myapp --context east-cluster
Common causes: VolumeReplication CRs not cleaned up or S3 cleanup pending.
Solution: Check VRG operator logs and manually clean up VolumeReplication resources if necessary.
Best Practices
Don’t create VRGs manually - Let DRPC manage them via ManifestWork
Monitor VRG status regularly - Check
lastGroupSyncTimeto ensure replication is workingCheck VRG state after DR operations - Verify state transitions complete:
- After failover: New primary should be
Primary, old primary should be deleted orSecondary - After relocate: Target should be
Primary, source should beSecondary
- After failover: New primary should be
Review protectedPVCs list - Ensure all expected PVCs are included
Monitor replication lag - Use
lastGroupSyncTimeandlastGroupSyncBytesmetricsCheck conditions - VRG conditions indicate issues with replication or S3 access
Understand primary/secondary roles - Only primary VRGs allow application writes
Advanced Topics
Volume Group Replication
For applications with multiple PVCs needing crash-consistent snapshots:
Requirements:
- Storage supports VolumeGroupReplicationClass or VolumeGroupSnapshotClass
- PVCs use compatible StorageClasses
- Properly configured in DRPolicy
Status: Check pvcgroups in VRG status for grouped PVCs.
S3 Metadata Storage
VRG stores these in S3:
- PV specs (for recreating PVs on peer cluster)
- VRG state metadata
- Protected PVC list
S3 bucket structure:
<bucket-name>/
<cluster-id>/
<namespace>/
<vrg-name>/
pv-<pv-name>.json
vrg-metadata.json
VolSync Integration
When using VolSync for replication:
- VRG creates ReplicationSource (primary) or ReplicationDestination (secondary)
- Final sync support for relocate operations
prepareForFinalSyncandrunFinalSynccoordinate the process
Related Resources
- DRPlacementControl CRD - Creates and manages VRGs
- DRPolicy CRD - Defines replication configuration used by VRG
- Usage Guide - How VRG fits into workload protection
- Recipe Documentation - For custom VRG workflows