Highly Available NFS Exports with DRBD & Pacemaker

Highly available NFS

This blog post explains how to configure an NFS server instance in a 3-node high availability (HA) active/passive Linux cluster using DRBD® and Pacemaker. You can implement this solution easily with enterprise Linux distributions such as Ubuntu LTS, or Red Hat Enterprise Linux (RHEL). The instructions in this article have been validated on both RHEL 9 and Ubuntu 24.04 LTS.

NFS is an excellent fit for many use cases, largely due to:

  • File Sharing – Enables multiple systems to access the same files where anyone (or any application) on the network can have access.
  • Centralized Storage – Reduces overall storage costs by sharing centralized storage, eliminating any need for local disk space for each user or application instance.

 

A few common NFS deployment solutions include:

  • Mapping user home directories
  • Storing virtual machines and containers
  • Using the ReadWriteMany (RWX) volume access mode in Kubernetes

System preparation requirements

The system preparation requirements for the NFS use case described in this article are:

  • You have a 3-node cluster consisting of two diskful nodes for data replication, and one diskless node for DRBD quorum purposes to prevent data divergence.
  • Cluster nodes are time-synchronized using Network Time Protocol (NTP).
  • The latest version of DRBD is installed and loaded into the kernel on all nodes. DRBD is available from its official Github repository, through LINBIT® customer repositories, or the LINBIT PPA for Ubuntu. Refer to the DRBD 9 User Guide for more details.
  • Your nodes have a dedicated network link for DRBD replication traffic only. This is a best practice. It is not mandatory.
  • Pacemaker and Corosync are installed, started, and enabled to start at boot.
  • The pcs cluster configuration tool is installed on all nodes for editing and managing Pacemaker’s configuration.
  • Applicable Open Cluster Framework (OCF) resource agents are installed on all nodes (resource-agents* packages).
  • NFS server software is installed on all nodes. The NFS server service should be disabled. Pacemaker will manage the NFS server related resources in the cluster, not systemd.
  • All cluster nodes can resolve each other’s hostnames. Verify through /etc/hosts or your local DNS server.
  • Firewalls in use are configured to allow appropriate traffic on all nodes.
    • Corosync: UDP ports 5404, 5405, and 5406.
    • DRBD: TCP port 7788 used in this setup for a single DRBD resource. Refer to the DRBD 9 User Guide for more information.
    • NFS: TCP/UDP port 2049

RHEL 9 specific instructions

If you are using RHEL 9, take the following steps to prepare your nodes.

Configure RHEL package repositories

You can install DRBD by using packages in the LINBIT customer repositories. Alternatively, DRBD and related utilities can be compiled from source.

Unless you are installing DRBD from source, enter the following command to install the DRBD kernel module and related utilities:

dnf install -y drbd kmod-drbd

Configure the RHEL High Availability Add-On

Install the RHEL High Availability Add-On. If you are a LINBIT customer, you can forego this and enable the pacemaker-2 repository on your nodes.

Enter the following command to install Pacemaker and related utilities:

dnf install -y pacemaker resource-agents iptables

Install NFS on RHEL

Install NFS and enable the rpcbind service1 by entering the following commands:

dnf install -y nfs-utils rpcbind
systemctl enable rpcbind --now

Configure the firewall on RHEL

If firewalld is enabled on your nodes, enter the following commands to allow necessary traffic through:

firewall-cmd --permanent --add-service=high-availability
firewall-cmd --permanent --add-service=nfs
firewall-cmd --permanent --add-port=7788/tcp
firewall-cmd --reload

Ubuntu 24.04 LTS specific instructions

If you are using Ubuntu 24.04 LTS, take the following steps to prepare your nodes.

Configure Ubuntu package repositories

You can install DRBD by using packages in the LINBIT customer repositories. Alternatively, you can use the LINBIT PPA. As always, the DRBD and related utilities can also be compiled from source.

Unless you are installing DRBD from source, enter the following commands to install DRBD and related utilities:

sudo apt install -y drbd-dkms drbd-utils

Enter the following command to install Pacemaker and related utilities:

sudo apt install -y pacemaker resource-agents-extra iptables

Install NFS on Ubuntu

Enter the following command to install NFS and related services and utilities:

sudo apt install -y nfs-kernel-server nfs-common

Allow Pacemaker to control NFS services

Stop and disable NFS server and its related services in systemd because Pacemaker will control these.

sudo systemctl disable --now nfs-kernel-server.service

Configure the firewall in Ubuntu

If ufw is enabled on your nodes, enter the following commands to allow necessary traffic through the firewall:

sudo ufw allow 2049
sudo ufw allow 5404:5406/udp
sudo ufw allow 7788/tcp

Creating the initial Pacemaker cluster configuration

After taking preparatory steps specific to your operating system, the rest of the steps are identical for both RHEL 9 and Ubuntu 24.04 LTS, or any other modern Linux distribution.

❗ IMPORTANT: You will need to run nearly all of the commands in the remaining steps under the root user account, or preface the commands with sudo for Ubuntu users.

First, you will create an initial 3-node Pacemaker cluster configuration. Replace IP addresses and hostnames shown in commands and configurations with those particular to the nodes in your environment.

Enabling and starting the Pacemaker service

On all nodes, enable and start the pcsd.service:

systemctl enable pcsd --now

Setting the Pacemaker user password

On all nodes, set the hacluster user password (replace secretpassword):

echo 'hacluster:secretpassword' | chpasswd

Authenticating the Pacemaker cluster user

On one node, authenticate the hacluster user for each node in the cluster (replace secretpassword):

pcs host auth -u hacluster -p secretpassword \
  node-0 addr=192.168.222.90 \
  node-1 addr=192.168.222.91 \
  node-2 addr=192.168.222.92

Creating the Pacemaker cluster

On one node, create a Pacemaker cluster named “linbit-cluster”.

# single ring - use when only one network is available
pcs cluster setup --force linbit-cluster \
  node-0 addr=192.168.222.90 \
  node-1 addr=192.168.222.91 \
  node-2 addr=192.168.222.92

# redundant rings - use when more than one network is available (recommended)
pcs cluster setup --force linbit-cluster \
  node-0 addr=192.168.222.90 addr=172.16.0.90 \
  node-1 addr=192.168.222.91 addr=172.16.0.91 \
  node-2 addr=192.168.222.92 addr=172.16.0.92

Starting Pacemaker and Corosync services

On one node, start the Corosync and Pacemaker services (for all nodes in the cluster):

pcs cluster start --all

Verifying cluster services and state

Verify that everything has started and is working correctly by entering a pcs status command. It might take a few moments for the cluster to elect a designated coordinator (DC). You should get output similar to this:

Cluster name: linbit-cluster
Cluster Summary:
  * Stack: corosync
  * Current DC: node-2 (version 2.1.2.linbit-4.el9-ada5c3b36e2) - partition with quorum
  * Last updated: Wed Apr 16 18:02:40 2025
  * Last change:  Wed Apr 16 16:34:32 2025 by root via cibadmin on node-0
  * 3 nodes configured
  * 0 resource instances configured

Node List:
  * Online: [ node-0 node-1 node-2 ]

Full List of Resources:
  * No resources

Daemon Status:
  corosync: active/enabled
  pacemaker: active/enabled
  pcsd: active/enabled

Disabling STONITH

On one node, disable STONITH for the cluster.

pcs property set stonith-enabled=false

💡 TIP: While STONITH is highly recommended to prevent split-brains for 2-node clusters, configuring STONITH and fencing is still useful and recommended for 3-node clusters. Instructions for enabling STONITH and fencing will vary based on the equipment in your environment. For this reason, and for brevity, STONITH is disabled in these instructions.

Creating a logical volume and directory for the NFS share

Before creating a DRBD resource in the cluster, you need to initialize the physical storage device for use with LVM on your diskful nodes.

To do that, enter the following command:

pvcreate /dev/sdx

❗ IMPORTANT: Enter this and all other commands in this article from the root user account, or else prefaced with sudo from a privileged user account.

Here, “x” in sdx corresponds to the letter identifying your physical storage device.

Next, create a LVM volume group, named nfs_vg, by entering:

vgcreate nfs_vg /dev/sdx

Next, create the LVM logical volumes that DRBD will consume.

The first logical volume will be for storing NFS stateful connection information and the “tickle” directory used by the portblock OCF resource agent. If the NFS stateful connection is not highly available or otherwise synchronized between cluster nodes, then in some failover cases, it might take a long time for NFS exports to become available. This volume will not hold much data and 20M can be a sufficient size.

The second volume will store data that you will share by using NFS. You can replace the 4 GiB value with a size appropriate for your use, or else use the -l 100%FREE option rather than -L 4G in the command if you want the logical volume to use 100% of available space in the specified volume group.

lvcreate -L 20M -n ha_nfs_internal_lv nfs_vg
lvcreate -L 4G -n ha_nfs_exports_lv nfs_vg

After creating the logical volumes, create the directories that will serve as the mount point for your NFS share, and the mount point for cluster internal state information subdirectories.

mkdir -p /srv/drbd-nfs/exports/HA
mkdir -p /srv/drbd-nfs/internal

Configuring DRBD

After preparing your backing storage device and a file system mount point on your nodes, you can next configure DRBD to replicate the storage device across the nodes.

Creating a DRBD resource file

DRBD resource configuration files are located in the /etc/drbd.d/ directory. You need to create resource files on all cluster nodes. You can create a resource file on one node and then use an rsync or scp command to distribute the file to other nodes. Each DRBD resource that you define in the resource configuration file needs a different TCP port. There is only one defined resource in this configuration, so the configuration just uses one TCP port (7788) here. Use the text editor of your choice to create the following DRBD resource file. Change the hostnames and IP addresses to reflect your network configuration.

📝 NOTE: The third cluster node only provides quorum in the cluster. It is not involved in DRBD replication. This type of node is called a DRBD diskless node. In the configuration, this is specified by using the disk none option within the on "node 2" stanza, for each of the volumes, volume 0 and volume 1.

resource "ha_nfs" {
  volume 0 {
    device "/dev/drbd1000";
    disk "/dev/nfs_vg/ha_nfs_internal_lv";
    meta-disk internal;
  }
  volume 1 {
    device "/dev/drbd1001";
    disk "/dev/nfs_vg/ha_nfs_exports_lv";
    meta-disk internal;
   }
  options {
    on-no-quorum suspend-io;
    quorum majority;
  }
  on "node-0" {
    address 192.168.222.90:7788;
    node-id 0;
  }
  on "node-1" {
    address 192.168.222.91:7788;
    node-id 1;
  }
  on "node-2" {
    volume 0 {
      disk none;
    }
    volume 1 {
      disk none;
    }
    address 192.168.222.92:7788;
    node-id 2;
  }
  connection-mesh {
    hosts "node-0" "node-1" "node-2";
  }
}

Initializing the DRBD resource

After creating the DRBD resource configuration file, you need to initialize the DRBD resource. To do this, enter the following commands on both diskful cluster nodes:

drbdadm create-md ha_nfs
drbdadm up ha_nfs

Synchronizing the DRBD resource

Because this is a new file system with no data content, you can skip the initial synchronization.

⚠️ WARNING: Use caution with this command because it can delete any existing data on the logical volume.

Enter the following commands on a diskful node:

drbdadm new-current-uuid --clear-bitmap ha_nfs/0
drbdadm new-current-uuid --clear-bitmap ha_nfs/1

Next, enter and run the following commands on only one of the two diskful cluster nodes2.

drbdadm primary --force ha_nfs
mkfs.ext4 /dev/drbd1000
mkfs.ext4 /dev/drbd1001
mount /dev/drbd1000 /srv/drbd-nfs/internal
mkdir /srv/drbd-nfs/internal/nfs_info_dir
mkdir /srv/drbd-nfs/internal/portblock_tickle_dir
umount /dev/drbd1000

Entering these commands will do a few things:

  • Force the node to become primary.
  • Create the needed file systems on the DRBD devices.
  • Mount the “internal” DRBD device to a mount point.
  • Create two “internal” informational directories.
  • Unmount the “internal” DRBD device.

 

The nfs_info_dir directory will store stateful information related to NFS connections. The portblock_tickle_dir directory, also known as the “tickle” directory, will be used by a portblock OCF resource agent to store established TCP connections. Using the portblock resource agent with a “tickle” directory will allow clients to reconnect faster after failover events. Refer to man ocf_heartbeat_portblock for more information.

💡 TIP: When making a new file system on a large volume, you might consider using the -E nodiscard option with the mkfs.ext4 command. Using this option might make the command run faster.

Next, enter lsblk and drbdadm status ha_nfs commands. Output from these commands will be similar to the following:

NAME                        MAJ:MIN  RM  SIZE RO TYPE MOUNTPOINTS
[...]
├─nfs_vg-ha_nfs_internal_lv 253:2     0   20M  0 lvm
│ └─drbd1000                147:1000  0   20M  0 disk
└─nfs_vg-ha_nfs_exports_lv  253:3     0    4G  0 lvm
  └─drbd1001                147:1001  0    4G  0 disk
ha_nfs role:Primary
  volume:0 disk:UpToDate open:no
  volume:1 disk:UpToDate open:no
  node-1 role:Secondary
    volume:0 peer-disk:UpToDate
    volume:1 peer-disk:UpToDate
  node-2 role:Secondary
    volume:0 peer-disk:Diskless
    volume:1 peer-disk:Diskless

The drbdadm status command should show that DRBD is in sync and UpToDate. If that is the case, use the following command to change the node from a primary DRBD role to a secondary.

drbdadm secondary ha_nfs

Creating NFS exports and Pacemaker resources

After configuring a DRBD resource as a foundation for a highly available NFS share, you can use Pacemaker to manage the DRBD resource and configure all the components to give you a complete high-availability NFS solution in your cluster. You will again use the pcs command-line tool to procedurally build the Pacemaker configuration.

Configuring the DRBD resource primitive in Pacemaker

First, create the DRBD primitive in the Pacemaker configuration for your cluster, by entering the following commands:

pcs cluster cib drbdconf
pcs -f drbdconf resource create p_drbd_ha_nfs ocf:linbit:drbd \
  drbd_resource=ha_nfs \
  op start interval=0s timeout=40s \
  stop interval=0s timeout=100s \
  monitor interval=31s timeout=20s role=Unpromoted \
  monitor interval=29s timeout=20s role=Promoted \
pcs -f drbdconf resource promotable p_drbd_ha_nfs \
  promoted-max=1 promoted-node-max=1 clone-max=3 clone-node-max=1 notify=true
pcs cluster cib-push drbdconf

Output from the last command should show CIB updated.

Verifying the DRBD resource primitive configuration in Pacemaker

If you enter another pcs status command, the output will show a clone set resource for your DRBD resource.

[...]
Full List of Resources:
  * Clone Set: p_drbd_ha_nfs-clone [p_drbd_ha_nfs] (promotable):
    * Promoted: [ node-0 ]
    * Unpromoted: [ node-1 node-2 ]
[...]

You can further verify that Pacemaker is now managing your DRBD resource by entering the following command:

drbdadm status ha_nfs

Command output will show the ha_nfs DRBD resource is in a primary role on one of your diskful nodes in your cluster, and in a (replicated) secondary role on the other nodes.

Configuring the file system primitive in Pacemaker

You need to configure a file system primitive in Pacemaker so that the file system that will back the NFS share is only mounted on a node in a primary role for the backing DRBD resource. The file system primitive is based on the Filesystem OCF resource agent and configures colocation and order constraints to accomplish this.

Because your DRBD resource has two volumes, you will need to configure two file system primitives in Pacemaker.

Enter the following commands to configure the file system primitive in Pacemaker, for the NFS stateful information directory:

pcs -f drbdconf resource create p_fs_nfs_internal_info_HA ocf:heartbeat:Filesystem \
  device=/dev/drbd1000 \
  directory="/srv/drbd-nfs/internal" \
  fstype=ext4 \
  run_fsck=no \
  op start interval=0s timeout=60s \
  stop interval=0s timeout=60s \
  monitor OCF_CHECK_LEVEL=0 interval=15s timeout=40s
pcs -f drbdconf constraint order \
  promote p_drbd_ha_nfs-clone then start p_fs_nfs_internal_info_HA
pcs -f drbdconf constraint colocation \
  add p_fs_nfs_internal_info_HA with p_drbd_ha_nfs-clone INFINITY with-rsc-role=Promoted

Enter the following commands to configure the file system primitive in Pacemaker, for the NFS data share directory:

pcs -f drbdconf resource create p_fs_nfsshare_exports_HA \
  ocf:heartbeat:Filesystem \
  device=/dev/drbd1001 \
  directory="/srv/drbd-nfs/exports/HA" \
  fstype=ext4 \
  run_fsck=no \
  op start interval=0s timeout=60s \
  stop interval=0s timeout=60s \
  monitor OCF_CHECK_LEVEL=0 interval=15s timeout=40s
pcs -f drbdconf constraint order \
  promote p_drbd_ha_nfs-clone then start p_fs_nfsshare_exports_HA
pcs -f drbdconf constraint colocation \
  add p_fs_nfsshare_exports_HA with p_drbd_ha_nfs-clone INFINITY with-rsc-role=Promoted

Next, enter the following command to push the updated changes to the Pacemaker CIB:

pcs cluster cib-push drbdconf

Output from this command should show CIB updated.

Verifying the file system primitive configuration in Pacemaker

If you enter another pcs status command, the output will show the two OCF Filesystem resources that you added:

[...]
Full List of Resources:
  * Clone Set: p_drbd_ha_nfs-clone [p_drbd_ha_nfs] (promotable):
    * Promoted: [ node-0 ]
    * Unpromoted: [ node-1 node-2 ]
  * p_fs_nfs_internal_info_HA   (ocf:heartbeat:Filesystem):  Started node-0
  * p_fs_nfsshare_exports_HA    (ocf:heartbeat:Filesystem):  Started node-0
[...]

You can enter a df -h command on the node in your cluster that the Filesystem resources are started on, to further verify that Pacemaker has mounted the two file systems, backed by the DRBD devices.

Filesystem                   Size  Used Avail Use% Mounted on
[...]
/dev/drbd1000                 18M   60K   16M   1% /srv/drbd-nfs/internal
/dev/drbd1001                3.9G  8.0K  3.7G   1% /srv/drbd-nfs/exports/HA
[...]

Configuring the NFS service and exports primitives in Pacemaker

After configuring the Pacemaker resource primitives that will back your HA NFS share, the DRBD volumes and the file systems that will mount on them, you can configure the Pacemaker primitives that will serve the NFS share in your cluster.

Configuring the NFS service primitive in Pacemaker

The first of these is the NFS service itself. Enter the following commands to configure the NFS service primitive in Pacemaker:

pcs -f drbdconf resource create p_nfsserver ocf:heartbeat:nfsserver \
  nfs_shared_infodir=/srv/drbd-nfs/internal/nfs_info_dir \
  nfs_ip=192.168.222.200 \
  op start interval=0s timeout=40s \
  stop interval=0s timeout=20s \
  monitor interval=10s timeout=20s
pcs -f drbdconf constraint colocation \
  add p_nfsserver with p_fs_nfs_internal_info_HA INFINITY
pcs -f drbdconf constraint order \
  p_fs_nfs_internal_info_HA then p_nfsserver

Configuring the NFS exports primitive in Pacemaker

The next Pacemaker resource primitive to configure, related to serving the NFS share in your cluster, is the exportfs OCF resource agent. This resource agent uses the exportfs Linux command to add the NFS export within your cluster. Enter the following commands to configure the NFS exports primitive in Pacemaker:

pcs -f drbdconf resource create p_exportfs_HA ocf:heartbeat:exportfs \
  clientspec=192.168.222.0/24 \
  directory=/srv/drbd-nfs/exports/HA fsid=1 \
  unlock_on_stop=1 options=rw,sync \
  op start interval=0s timeout=40s \
  stop interval=0s timeout=120s \
  monitor interval=10s timeout=20s
pcs -f drbdconf constraint order \
  p_nfsserver then p_exportfs_HA
pcs -f drbdconf constraint colocation \
  add p_exportfs_HA with p_nfsserver INFINITY

After adding these Pacemaker resource primitives, push the changes to your Pacemaker CIB.

pcs cluster cib-push drbdconf

Verifying the NFS service and exports primitives in Pacemaker

If you enter another pcs status command, the output will show the two OCF Filesystem resources that you added:

[...]
Full List of Resources:
  * Clone Set: p_drbd_ha_nfs-clone [p_drbd_ha_nfs] (promotable):
    * Promoted: [ node-0 ]
    * Unpromoted: [ node-1 node-2 ]
  * p_fs_nfs_internal_info_HA   (ocf:heartbeat:Filesystem):  Started node-0
  * p_fs_nfsshare_exports_HA    (ocf:heartbeat:Filesystem):  Started node-0
  * p_nfsserver (ocf:heartbeat:nfsserver):   Started node-0
  * p_exportfs_HA   (ocf:heartbeat:exportfs):    Started node-0
[...]

Configuring the virtual IP address primitive in Pacemaker

The next Pacemaker resource primitive to configure in your cluster will create and manage the virtual IP address for your NFS server. Using a virtual IP address makes the NFS server available within your network from a single, unchanging IP address, regardless of which node in your cluster is currently hosting the service. To add the virtual IP address to your Pacemaker-managed resources, enter the following commands:

pcs -f drbdconf resource create p_virtip_HA ocf:heartbeat:IPaddr2 \
  ip=192.168.222.200 cidr_netmask=24 \
  op monitor interval=20s timeout=20s \
  start interval=0s timeout=20s \
  stop interval=0s timeout=20s
pcs -f drbdconf constraint order \
  p_exportfs_HA then p_virtip_HA
pcs -f drbdconf constraint colocation \
  add p_virtip_HA with p_exportfs_HA INFINITY

After adding this Pacemaker resource primitive, push the changes to your Pacemaker CIB.

pcs cluster cib-push drbdconf

Verifying the virtual IP address

As you have done before, enter a pcs status command to verify that the Pacemaker resource primitive you just added shows up within the list of Pacemaker resources.

[...]
Full List of Resources:
  * Clone Set: p_drbd_ha_nfs-clone [p_drbd_ha_nfs] (promotable):
    * Promoted: [ node-0 ]
    * Unpromoted: [ node-1 node-2 ]
  * p_fs_nfs_internal_info_HA   (ocf:heartbeat:Filesystem):  Started node-0
  * p_fs_nfsshare_exports_HA    (ocf:heartbeat:Filesystem):  Started node-0
  * p_nfsserver (ocf:heartbeat:nfsserver):   Started node-0
  * p_exportfs_HA   (ocf:heartbeat:exportfs):    Started node-0
  * p_virtip_HA (ocf:heartbeat:IPaddr2):     Started node-0
[...]

With the virtual IP address resource started on a node in you cluster, you can also verify it by entering a ping command, from any node within your system that has a network route to the cluster.

ping -c 4 192.168.222.200

Configuring port block and unblock primitives in Pacemaker

The final Pacemaker resource primitives that you need to configure and add to your setup use the portblock OCF resource agent. Configuring this will allow for faster TCP reconnections for clients on failover. Enter the following commands to add these resource primitives:

pcs -f drbdconf resource create p_pb_block portblock \
  action=block \
  ip=192.168.222.200 \
  portno=2049 \
  protocol=tcp
pcs -f drbdconf constraint order \
  start p_pb_block then p_virtip_HA
pcs -f drbdconf constraint colocation \
  add p_pb_block with p_virtip_HA INFINITY
pcs -f drbdconf resource create p_pb_unblock portblock \
  action=unblock \
  ip=192.168.222.200 \
  portno=2049 \
  tickle_dir="/srv/drbd-nfs/internal/portblock_tickle_dir" \
  reset_local_on_unblock_stop=1 \
  protocol=tcp \
  op monitor interval=10s timeout=20s
pcs -f drbdconf constraint order \
  start p_virtip_HA then p_pb_unblock
pcs -f drbdconf constraint colocation \
  add p_pb_unblock with p_virtip_HA INFINITY

After adding these Pacemaker resource primitives, push the changes to your Pacemaker CIB.

pcs cluster cib-push drbdconf

Verifying the port block and unblock resources in Pacemaker

Enter a pcs status command to verify that the Pacemaker resource primitives you just added show up within the list of Pacemaker resources.

[...]
Full List of Resources:
  * Clone Set: p_drbd_ha_nfs-clone [p_drbd_ha_nfs] (promotable):
    * Promoted: [ node-0 ]
    * Unpromoted: [ node-1 node-2 ]
  * p_fs_nfs_internal_info_HA   (ocf:heartbeat:Filesystem):  Started node-0
  * p_fs_nfsshare_exports_HA    (ocf:heartbeat:Filesystem):  Started node-0
  * p_nfsserver (ocf:heartbeat:nfsserver):   Started node-0
  * p_exportfs_HA   (ocf:heartbeat:exportfs):    Started node-0
  * p_virtip_HA (ocf:heartbeat:IPaddr2):     Started node-0
  * p_pb_block  (ocf:heartbeat:portblock):   Started node-0
  * p_pb_unblock    (ocf:heartbeat:portblock):   Started node-0
[...]

You can further verify the NFS port (2049) availability by using a utility such as nmap or telnet from a system on or with a route to the 192.168.222.0/24 network.

With that, you have configured an HA NFS cluster by using DRBD and Pacemaker. The NFS share is ready to be used by clients on your network. You can verify the availability of your NFS share by mounting from a root or privileged user account on any host that is on or has a route to the 192.168.222.0/24 network and has NFS client software.

mkdir -p /mnt/HA
mount 192.168.222.200:/srv/drbd-nfs/exports/HA /mnt/HA

At this point, root or a privileged user can read and write to the NFS share from a system that has mounted the share. Configuring the export for access from other user accounts is possible but outside the scope of this article.

Conclusion

With DRBD ensuring real-time, up-to-date data replication, and Pacemaker managing resources and services related to your NFS share, if one cluster node fails, the other diskful cluster node will take over seamlessly and automatically.

Some details of setting up this cluster were assumed in the preparation requirements section. If you might want more help with those preparatory steps, you can download a more detailed how-to guide from the LINBIT website: NFS High Availability Clustering Using DRBD and Pacemaker on RHEL 9.

Finally, you should consider the values and options used in this article as starting points. Depending on your environment, and the applications and services that you might be running, you might need to adjust things such as monitor intervals, timeouts, on error behaviors, and others. If you need help from our experienced team, or have questions about the particulars of setting up a HA NFS within your environment, you can contact the experts at LINBIT.

 


 

Changelog

2025-05-29:

  • Add specific steps for RHEL 9 and Ubuntu 24.04 LTS
  • Use pcs rather than crmsh commands
  • Add Pacemaker cluster initialization section
  • Build Pacemaker configuration step-by-step
  • Add more verification steps
  • Use updated Pacemaker terminology in primitives and constraints
  • Do not use showmount to verify NFS export
  • Make language clarity improvements

 

2024-09-23:

  • Technical improvements made to HA architecture.
  • Other improvements to technical details of instructions.

 

2024-07-15:

  • LINBIT technical review.

 

2023-12-04:

  • Added user submitted suggestions and LINBIT technical review.

 

2022-03-09:

  • Originally published.

 


 

  1. The rpcpind service is not strictly necessary for setups where only NFS v4 clients will be connecting, however, some NFS troubleshooting tools rely on it. It can still be useful to enable the service, even in NFS v4 only setups.↩︎
  2. If you had a logical volume, or volumes, with existing data “underneath” the DRBD resource, you would not enter the --clear-bitmap commands shown earlier. You would enter the commands on the node with data that you want to be the “good” source for initially synchronizing to other peer nodes. Forcing a node to be in a primary role for a DRBD resource, in the case where you have cleared the bitmap, initiates a full synchronization of data from the primary node to peer nodes. DRBD will replicate the file systems and the directories that the following commands create to the other “diskful” cluster node. Therefore, you only need to enter these commands on one node.↩︎
Picture of Yusuf Yıldız

Yusuf Yıldız

After nearly 15 years of system and storage management, Yusuf started to work as a solution architect at LINBIT. Yusuf's main focus is on customer success and contributing to product development and testing. As part of the solution architects team, he is one of the backbone and supporter of the sales team.

Talk to us

LINBIT is committed to protecting and respecting your privacy, and we’ll only use your personal information to administer your account and to provide the products and services you requested from us. From time to time, we would like to contact you about our products and services, as well as other content that may be of interest to you. If you consent to us contacting you for this purpose, please tick above to say how you would like us to contact you.

You can unsubscribe from these communications at any time. For more information on how to unsubscribe, our privacy practices, and how we are committed to protecting and respecting your privacy, please review our Privacy Policy.

By clicking submit below, you consent to allow LINBIT to store and process the personal information submitted above to provide you the content requested.

Talk to us

LINBIT is committed to protecting and respecting your privacy, and we’ll only use your personal information to administer your account and to provide the products and services you requested from us. From time to time, we would like to contact you about our products and services, as well as other content that may be of interest to you. If you consent to us contacting you for this purpose, please tick above to say how you would like us to contact you.

You can unsubscribe from these communications at any time. For more information on how to unsubscribe, our privacy practices, and how we are committed to protecting and respecting your privacy, please review our Privacy Policy.

By clicking submit below, you consent to allow LINBIT to store and process the personal information submitted above to provide you the content requested.