Prerequisites
Kubernetes version requirements, required cluster permissions, and external dependencies
This page describes everything you need to have in place before installing Site Recovery. It covers the supported Kubernetes and OpenShift versions, required cluster topology, software dependencies, network and storage requirements, and the access permissions each cluster must grant. Reviewing these prerequisites before you begin will prevent the most common installation failures and ensure your environment can support the full DR lifecycle — including replication, failover, failback, and non-disruptive test failovers.
Verify each item below before proceeding to installation.
Kubernetes and OpenShift versions
| Distribution | Minimum version |
|---|---|
| Kubernetes | 1.28 |
| OpenShift | 4.14 |
Cluster topology
Site Recovery supports two deployment models with different cluster requirements:
| Model | Clusters required |
|---|---|
| DRBD Operator | 2 (primary + DR); a third quorum cluster is optional but recommended |
| Centralized storage | 3 (quorum + primary + DR) |
In both models, the quorum cluster hosts the management plane (failover controllers, protection controllers, Site Manager UI). It does not run application workloads and does not relay storage replication traffic.
Required software — all clusters
- kubectl — for applying manifests and inspecting resources
- Helm ≥ 3.0 — for deploying Site Recovery Helm charts
- Ansible — for running the provided deployment playbooks
- KubeVirt ≥ 1.0 — installed on the primary and DR clusters; this is the virtualization layer that runs the VMs you are protecting
- DRBD kernel module ≥ 9.0 — installed on all worker nodes of the primary and DR clusters that host VM storage; this is the kernel-level component that performs block replication
Required software — DRBD Operator model only
- DRBD Operator (minimum supported version required; check the release notes for the exact version pairing) — installed on both the primary and DR clusters; manages the lifecycle of DRBDVolume resources
Required software — test failover (DRBD Operator model only)
- VolumeSnapshot support (CSI snapshotter) — must be installed on both primary and DR clusters; test failover is only supported in the DRBD Operator deployment model
Kubeconfig files
You need a kubeconfig file with administrative access for each cluster:
- Quorum cluster kubeconfig
- Primary cluster kubeconfig
- DR cluster kubeconfig
These files are referenced throughout installation and are used by the controllers on the quorum cluster to communicate with the primary and DR clusters.
Network requirements
| Traffic | Protocol / Port | Between |
|---|---|---|
| DRBD replication | TCP 7000–7999 | Primary worker nodes ↔ DR worker nodes |
| Kubernetes API access | TCP 6443 | Quorum cluster → primary cluster API server |
| Kubernetes API access | TCP 6443 | Quorum cluster → DR cluster API server |
Latency requirement: For synchronous replication (Protocol C, RPO=0), round-trip latency between the primary and DR clusters must be less than 10 ms. Asynchronous replication (Protocol A) has no latency ceiling but accepts a small RPO window measured in seconds.
Storage requirements
- LVM thin-provisioned storage pools on the worker nodes of the primary and DR clusters; DRBD uses these pools to back replicated volumes
- Storage classes must be available on both clusters; in the DRBD Operator model, you will map primary storage class names to DR storage class names in a
DRBDReplicationPolicyresource
Cluster permissions
The kubeconfig for each cluster must grant sufficient permissions for Site Recovery controllers to:
- Create, update, and delete custom resources (
ProtectionGroup,ProtectionRequest,FailoverRequest,TestFailover,DRBDReplicationPolicy,DRBDVolume,RPOEvent,ReplicationGroupStatus) - Manage
PersistentVolumeClaimandVolumeSnapshotresources in the namespaces where protected VMs run - Read and patch
VirtualMachineandVirtualMachineInstanceresources (KubeVirt) - Create namespaces and deploy controller workloads (on the quorum cluster)
In practice, cluster-admin rights on each cluster satisfy all of these requirements and are the simplest way to get started. If your security policy requires scoped RBAC, refer to the RBAC manifests shipped with the Helm charts for the exact roles and bindings the controllers need.
Installation is covered in the deployment guide for each model. This section describes only the environment preparation steps that must be completed before you run any Helm or Ansible commands.
Step 1 — Obtain kubeconfig files
Collect a kubeconfig with cluster-admin access for each cluster and export the paths as environment variables. These variables are used in all subsequent commands.
export KUBECONFIG_QUORUM=~/.kube/config-quorum
export KUBECONFIG_CLUSTER1=~/.kube/config-cluster1
export KUBECONFIG_CLUSTER2=~/.kube/config-cluster2
Verify connectivity to each cluster:
kubectl --kubeconfig $KUBECONFIG_QUORUM cluster-info
kubectl --kubeconfig $KUBECONFIG_CLUSTER1 cluster-info
kubectl --kubeconfig $KUBECONFIG_CLUSTER2 cluster-info
Step 2 — Verify Kubernetes versions
kubectl --kubeconfig $KUBECONFIG_QUORUM version --short
kubectl --kubeconfig $KUBECONFIG_CLUSTER1 version --short
kubectl --kubeconfig $KUBECONFIG_CLUSTER2 version --short
Each cluster must report server version 1.28 or later (or OpenShift 4.14 or later).
Step 3 — Verify KubeVirt on primary and DR clusters
kubectl --kubeconfig $KUBECONFIG_CLUSTER1 get kubevirt -A
kubectl --kubeconfig $KUBECONFIG_CLUSTER2 get kubevirt -A
The KubeVirt resource must be present and its status must show version 1.0 or later.
Step 4 — Verify the DRBD kernel module on worker nodes
Run the following on each worker node of the primary and DR clusters:
modinfo drbd | grep ^version
The version must be 9.0 or later. If the module is not loaded, load it and confirm:
modprobe drbd
lsmod | grep drbd
Step 5 — Verify LVM thin pools
On each worker node, confirm that a thin-provisioned LVM pool exists and has sufficient free space for your replicated volumes:
lvs --select 'lv_layout=thin,pool'
Step 6 — Verify network ports
From a worker node on the primary cluster, confirm that TCP ports 7000–7999 are reachable on at least one worker node of the DR cluster:
nc -zv <dr-worker-ip> 7000
From the quorum cluster's API server address, confirm TCP 6443 is reachable on both the primary and DR cluster API servers:
nc -zv <primary-api-server-ip> 6443
nc -zv <dr-api-server-ip> 6443
Step 7 — Verify Helm
helm version --short
The output must show version 3.0 or later.
Step 8 (DRBD Operator model only) — Verify DRBD Operator installation
kubectl --kubeconfig $KUBECONFIG_CLUSTER1 get pods -n <drbd-operator-namespace>
kubectl --kubeconfig $KUBECONFIG_CLUSTER2 get pods -n <drbd-operator-namespace>
The DRBD Operator pods must be running on both the primary and DR clusters before you deploy Site Recovery components.
Step 9 (Test failover only, DRBD Operator model) — Verify VolumeSnapshot support
kubectl --kubeconfig $KUBECONFIG_CLUSTER1 get crd volumesnapshotclasses.snapshot.storage.k8s.io
kubectl --kubeconfig $KUBECONFIG_CLUSTER2 get crd volumesnapshotclasses.snapshot.storage.k8s.io
If either command returns Error from server (NotFound), install the CSI external-snapshotter before enabling test failover.
The prerequisites phase does not require product-specific configuration files, but the following environment decisions made at this stage directly affect how you configure Site Recovery later.
Replication protocol
Choose your DRBD replication protocol based on your network and RPO requirements. This choice is encoded in the drbdProtocol field of DRBDReplicationPolicy (DRBD Operator model) or in the replicationPolicy.type field of ProtectionGroup (centralized model).
| Protocol | Mode | RPO | Latency requirement |
|---|---|---|---|
C | Synchronous | Zero (RPO=0) | < 10 ms RTT between primary and DR clusters |
A | Asynchronous | Near-zero (seconds) | No ceiling; suitable for high-latency WAN links |
Protocol C writes are only acknowledged to the application after data commits to disk on both clusters. If your measured round-trip time between the primary and DR clusters exceeds 10 ms, use Protocol A to avoid write-performance degradation.
Storage class mappings
In the DRBD Operator model, you must map each storage class used by protected VMs on the primary cluster to a corresponding storage class on the DR cluster. This mapping is defined in DRBDReplicationPolicy.spec.storageClassMappings. Decide on these pairings before installation by inventorying the storage classes on both clusters:
kubectl --kubeconfig $KUBECONFIG_CLUSTER1 get storageclass
kubectl --kubeconfig $KUBECONFIG_CLUSTER2 get storageclass
Each primary storage class that backs a VM disk must have a corresponding DR storage class that also targets LVM thin-provisioned storage.
Deployment namespace naming
Each DR deployment is isolated in its own namespace on the quorum cluster using the naming convention dr-<name>. Choose a short, descriptive deployment name before installation — for example, dr-prod, dr-east, or dr-tenant-a. This name appears in namespace names, Helm release names, and resource metadata throughout the system.
Cluster topology decision
Decide which deployment model applies to your environment:
- DRBD Operator model: Use when you have the DRBD Operator installed on both clusters and prefer distributed storage management. Supports 2- or 3-cluster topologies. ProtectionRequest CRDs protect individual VMs. Test failover is available.
- Centralized storage model: Use when you need a shared storage controller. Requires a 3-cluster topology (quorum is mandatory). ProtectionGroup CRDs group VMs for coordinated failover.
This decision cannot be changed after installation without redeploying the control plane.
Once your environment satisfies all prerequisites, you interact with Site Recovery primarily through kubectl and YAML manifests for custom resources, and through the pgctl CLI and quorum-deployments.sh script for operational tasks. The Site Manager UI provides a web-based view of the same state.
Checking prerequisite status before install
Before running any deployment playbook, validate that all clusters are reachable and that the required CRD support is in place:
# Confirm all three clusters are reachable
kubectl --kubeconfig $KUBECONFIG_QUORUM get nodes
kubectl --kubeconfig $KUBECONFIG_CLUSTER1 get nodes
kubectl --kubeconfig $KUBECONFIG_CLUSTER2 get nodes
# Confirm KubeVirt is installed on workload clusters
kubectl --kubeconfig $KUBECONFIG_CLUSTER1 api-resources | grep kubevirt
kubectl --kubeconfig $KUBECONFIG_CLUSTER2 api-resources | grep kubevirt
What happens if prerequisites are not met
- Missing DRBD kernel module: The protection controller will be unable to establish replication. ProtectionRequest resources will stall in a validation phase and their status will reflect the error.
- Port 7000–7999 blocked: DRBD replication will not establish. DRBDVolume resources will show a sync status of
Degradedor will never reachConsistent. - Insufficient kubeconfig permissions: Controllers on the quorum cluster will log permission errors and will be unable to reconcile resources on the primary or DR clusters.
- Missing VolumeSnapshot support: TestFailover resources will fail during the
CreatingSnapshotsphase if VolumeSnapshot CRDs are not installed. - Latency > 10 ms with Protocol C: Writes will experience increased latency or timeouts. Switch to Protocol A if your link cannot meet the 10 ms requirement.
pgctl context setup
After installation, pgctl is the primary CLI for day-to-day operations. The first step is always to set the deployment context so the tool knows which quorum namespace to target:
pgctl config set-context --deployment dr-prod --kubeconfig $KUBECONFIG_QUORUM
pgctl config current-context
quorum-deployments.sh for operational tasks
The quorum-deployments.sh interactive script provides a menu-driven interface for more than 20 tasks including health checks that can help you confirm prerequisites are satisfied post-install:
bash quorum-deployments.sh
Select the health check option from the menu to validate controller status, replication connectivity, and cluster credentials.
Example 1 — Verify all three clusters meet version requirements
Run this before beginning any installation work to confirm Kubernetes versions and node readiness across all three clusters.
for CLUSTER in QUORUM CLUSTER1 CLUSTER2; do
KUBECONFIG_VAR="KUBECONFIG_${CLUSTER}"
echo "=== ${CLUSTER} ==="
kubectl --kubeconfig ${!KUBECONFIG_VAR} version --short 2>/dev/null | grep Server
kubectl --kubeconfig ${!KUBECONFIG_VAR} get nodes \
-o custom-columns='NAME:.metadata.name,STATUS:.status.conditions[-1].type,VERSION:.status.nodeInfo.kubeletVersion'
echo
done
Expected output (versions will vary):
=== QUORUM ===
Server Version: v1.29.3
NAME STATUS VERSION
quorum-node-1 Ready v1.29.3
=== CLUSTER1 ===
Server Version: v1.28.7
NAME STATUS VERSION
primary-worker-1 Ready v1.28.7
primary-worker-2 Ready v1.28.7
=== CLUSTER2 ===
Server Version: v1.28.7
NAME STATUS VERSION
dr-worker-1 Ready v1.28.7
dr-worker-2 Ready v1.28.7
Example 2 — Verify DRBD kernel module version on worker nodes
Run this on each worker node of the primary and DR clusters to confirm the DRBD kernel module meets the minimum version requirement.
# On each worker node
modinfo drbd | grep -E '^(version|filename)'
Expected output:
filename: /lib/modules/5.14.0-284.30.1.el9_2.x86_64/extra/drbd.ko
version: 9.1.11
The version must be 9.0 or later. If the module is not present:
# Load the module
modprobe drbd
# Confirm it loaded
lsmod | grep drbd
Example 3 — Verify TCP 7000–7999 reachability between clusters
Run this from a primary cluster worker node to confirm DRBD replication ports are open to the DR cluster.
# Replace with the actual IP of a DR cluster worker node
DR_WORKER_IP=10.0.2.10
for PORT in 7000 7001 7999; do
nc -zv -w 3 $DR_WORKER_IP $PORT 2>&1 && echo "Port $PORT: OPEN" || echo "Port $PORT: BLOCKED"
done
Expected output when ports are correctly open:
Connection to 10.0.2.10 7000 port [tcp/*] succeeded!
Port 7000: OPEN
Connection to 10.0.2.10 7001 port [tcp/*] succeeded!
Port 7001: OPEN
Connection to 10.0.2.10 7999 port [tcp/*] succeeded!
Port 7999: OPEN
Example 4 — Inventory storage classes for DRBDReplicationPolicy planning
Run this before defining your DRBDReplicationPolicy to see which storage classes are available on each cluster and plan your storageClassMappings.
echo "=== Primary cluster storage classes ==="
kubectl --kubeconfig $KUBECONFIG_CLUSTER1 get storageclass \
-o custom-columns='NAME:.metadata.name,PROVISIONER:.provisioner,RECLAIM:.reclaimPolicy'
echo
echo "=== DR cluster storage classes ==="
kubectl --kubeconfig $KUBECONFIG_CLUSTER2 get storageclass \
-o custom-columns='NAME:.metadata.name,PROVISIONER:.provisioner,RECLAIM:.reclaimPolicy'
Expected output (class names will vary by environment):
=== Primary cluster storage classes ===
NAME PROVISIONER RECLAIM
ocs-storagecluster-ceph-rbd openshift-storage.rbd.csi Delete
local-storage kubernetes.io/no-provisioner Retain
=== DR cluster storage classes ===
NAME PROVISIONER RECLAIM
ocs-storagecluster-ceph-rbd openshift-storage.rbd.csi Delete
local-storage-dr kubernetes.io/no-provisioner Retain
With this output, your storageClassMappings in DRBDReplicationPolicy would be:
spec:
storageClassMappings:
- primaryStorageClass: ocs-storagecluster-ceph-rbd
drStorageClass: ocs-storagecluster-ceph-rbd
- primaryStorageClass: local-storage
drStorageClass: local-storage-dr
Cluster is unreachable from the quorum cluster
Symptom: Controllers on the quorum cluster log authentication or connection-refused errors when trying to reconcile resources on the primary or DR cluster.
Likely cause: The kubeconfig stored for that cluster has expired credentials, an incorrect API server address, or TCP 6443 is blocked between the quorum cluster and the workload cluster.
Fix:
- Verify the kubeconfig works from outside the cluster:
kubectl --kubeconfig $KUBECONFIG_CLUSTER1 get nodes - Confirm TCP 6443 is open from the quorum cluster to the primary/DR API server IP.
- If credentials have expired, regenerate the kubeconfig and update the secret in the quorum cluster's deployment namespace (
dr-<name>).
DRBD kernel module not found on worker nodes
Symptom: ProtectionRequest resources stall in validation. Controller logs contain messages about DRBD not being available or volume creation failing.
Likely cause: The drbd kernel module is not installed or not loaded on one or more worker nodes.
Fix:
- On the affected worker node, run
lsmod | grep drbd. If no output, the module is not loaded. - Load it:
modprobe drbd - Confirm the version meets the minimum:
modinfo drbd | grep ^version— must be 9.0 or later. - To persist across reboots: add
drbdto/etc/modules-load.d/drbd.conf.
DRBD replication does not establish (DRBDVolume stays Degraded)
Symptom: After a ProtectionRequest is processed, the corresponding DRBDVolume resource reports a sync state of Degraded and replication never reaches Consistent.
Likely cause: TCP ports 7000–7999 are blocked between primary and DR worker nodes, or the replication endpoint addresses in DRBDReplicationPolicy are incorrect.
Fix:
- From a primary worker node, test port reachability:
nc -zv <dr-worker-ip> 7000 - If blocked, open TCP 7000–7999 bidirectionally between primary and DR worker nodes in your firewall or security group rules.
- Check the
replicationEndpointvalues in yourDRBDReplicationPolicyresource and confirm the IPs and ports match the actual worker node addresses.
Protocol C causing write latency or timeouts
Symptom: Application writes from VMs are slow or timing out. The primary and DR clusters are in different geographic regions or connected over a WAN link.
Likely cause: Round-trip latency between the clusters exceeds 10 ms. Protocol C (synchronous) holds the write acknowledgment until data commits on both clusters, so high latency directly increases write latency.
Fix:
- Measure RTT:
ping <dr-worker-ip>from a primary worker node. If consistently above 10 ms, Protocol C is not suitable for this link. - Update your
DRBDReplicationPolicyto use Protocol A (drbdProtocol: A). This acknowledges writes after local commit and replicates asynchronously, introducing a small RPO window measured in seconds. - Monitor replication lag using RPOEvent resources:
kubectl --kubeconfig $KUBECONFIG_QUORUM get rpoevents -A
VolumeSnapshot CRDs missing (test failover fails at CreatingSnapshots)
Symptom: A TestFailover resource transitions to Failed at the CreatingSnapshots phase. Controller logs show errors about VolumeSnapshot or VolumeSnapshotClass resources not found.
Likely cause: The CSI external-snapshotter is not installed on the primary or DR cluster. Test failover requires VolumeSnapshot support and is only available in the DRBD Operator deployment model.
Fix:
- Confirm whether the CRD is present:
kubectl --kubeconfig $KUBECONFIG_CLUSTER1 get crd volumesnapshotclasses.snapshot.storage.k8s.io - If missing, install the CSI external-snapshotter from the upstream Kubernetes CSI repository on both the primary and DR clusters.
- Confirm a VolumeSnapshotClass is configured with the correct CSI driver for your storage:
kubectl --kubeconfig $KUBECONFIG_CLUSTER1 get volumesnapshotclass
Helm version too old
Symptom: Helm chart installation fails with parse errors or missing feature flags.
Likely cause: The installed Helm version is below 3.0.
Fix:
- Check:
helm version --short - If below v3.0, upgrade Helm: follow the official Helm installation guide for your OS and install the latest 3.x release.
KubeVirt not detected on workload clusters
Symptom: The protection controller logs errors when validating VMs in a ProtectionRequest. The API group kubevirt.io is not present.
Likely cause: KubeVirt is not installed on the primary or DR cluster, or it is installed but the version is below 1.0.
Fix:
- Check:
kubectl --kubeconfig $KUBECONFIG_CLUSTER1 get kubevirt -A - If not found, install KubeVirt ≥ 1.0 on the cluster.
- If found, verify the version:
kubectl --kubeconfig $KUBECONFIG_CLUSTER1 get kubevirt -A -o jsonpath='{.items[*].status.observedKubeVirtVersion}'— must be 1.0 or later.