In the previous post we were configuring an active/standby cluster with Corosync and Pacemaker.
However, we saw that a functional cluster needs file replication between the two nodes of the cluster.
In this post we will finish configuring the cluster by adding the replication of the /var/www directory of both Apache servers. For this we will use the DRBD tool which is a distributed replicated storage system for Linux platforms.
The topology used for this post is the same as the previous post:
1. Install DRBD on each node
First of all we need to install DRBD package on each node:
1 2 3 |
rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-3.el7.elrepo.noarch.rpm yum install drbd90-utils kmod-drbd90 |
It is recommended to disable selinux completely or at least set to permissive mode for drbd services:
1 |
semanage permissive -a drbd_t |
We must allow DRBD communication between nodes:
Node 1:
1 2 |
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.125.12" port port="7789" protocol="tcp" accept' firewall-cmd --reload |
Node 2:
1 2 |
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.125.11" port port="7789" protocol="tcp" accept' firewall-cmd --reload |
2. Allocate a disk volume for DRBD
DRBD will need its own block device on each node. This can be a physical disk partition or logical volume, of whatever size you need for your data.
Since in this tutorial I’m using virtual machines I added a new 20GB physical disk ‘sdb’ to each node:
1 2 3 4 5 6 7 8 9 10 |
[root@node1 ~]# lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT sda 8:0 0 200G 0 disk +-sda1 8:1 0 5G 0 part /boot +-sda2 8:2 0 100G 0 part / +-sda3 8:3 0 5G 0 part [SWAP] +-sda4 8:4 0 1K 0 part +-sda5 8:5 0 90G 0 part /home sdb 8:16 0 20G 0 disk sr0 11:0 1 1024M 0 rom |
After that I used ‘fdisk’ utility to create a partition (sdb1) into ‘sdb’ on each node:
1 2 3 4 5 6 7 8 9 10 11 |
[root@node1 ~]# lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT sda 8:0 0 200G 0 disk +-sda1 8:1 0 5G 0 part /boot +-sda2 8:2 0 100G 0 part / +-sda3 8:3 0 5G 0 part [SWAP] +-sda4 8:4 0 1K 0 part +-sda5 8:5 0 90G 0 part /home sdb 8:16 0 20G 0 disk +-sdb1 8:17 0 20G 0 part sr0 11:0 1 1024M 0 rom |
You could use a logical volume instead of a physical partition.
3. Configure DRBD
We create a new DRBD resource on each node where we configure the partition to be used and the nodes involved on that DRBD communication.
1 2 |
cd /etc/drbd.d/ vi wwwdata.res |
On ‘wwwdata.res’ we insert the following config:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
resource wwwdata { on node1 { device /dev/drbd1; disk /dev/sdb1; address 192.168.125.11:7789; meta-disk internal; } on node2 { device /dev/drbd1; disk /dev/sdb1; address 192.168.125.12:7789; meta-disk internal; } } |
With the configuration in place, we can now get DRBD running.
These commands create the local metadata for the DRBD resource and bring up the DRBD resource:
1 2 3 4 5 6 |
[root@node1 drbd.d]# drbdadm create-md wwwdata initializing activity log initializing bitmap (640 KB) to all zero Writing meta data... New drbd meta data block successfully created. success |
1 |
[root@node1 drbd.d]# systemctl start drbd.service |
IMPORTANT: DRBD service will not start until we run the same commands (‘drbadm create-md’ and ‘systemctl start’) on the other node.
Now we can check the status with the command ‘drbdadm status‘.
You can see the state has changed to Connected, meaning the two DRBD nodes are communicating properly, and both nodes are in Secondary role with Inconsistent data.
To make the data consistent, we need to tell DRBD which node should be considered to have the correct data. In this case, since we are creating a new resource, both have garbage, so we’ll just pick ‘node1’ and run this command on it:
1 |
[root@node1 ~]# drbdadm primary --force wwwdata |
1 2 3 4 5 |
[root@node1 ~]# drbdadm status wwwdata role:Primary disk:UpToDate node2 role:Secondary replication:SyncSource peer-disk:Inconsistent done:78.76 |
We can see that this node has the Primary role, the partner node has the Secondary role, this node’s data is now considered UpToDate, the partner node’s data is still Inconsistent because is synchronizing 78.76 %. We must wait for node 2 to finish synchronizing
1 2 3 4 5 |
[root@node1 ~]# drbdadm status wwwdata role:Primary disk:UpToDate node2 role:Secondary peer-disk:UpToDate |
4. Add the replication path to DRBD
Now, we’ve come to the final part which is testing of the DRBD service to ensure it meets the objective. First, let’s mount the DRBD partition.
IMPORTANT: Do the below steps once on the primary server node1 ONLY!
On the node with the primary role (node1 in this example), create a filesystem on the DRBD device:
1 |
[root@node1 proc]# mkfs.xfs /dev/drbd1 |
Mount the newly created filesystem, populate it with our web document and then unmount it (the cluster will handle mounting and unmounting it later):
1 2 3 4 5 6 7 8 |
[root@node1 ~]# mount /dev/drbd1 /mnt [root@node1 ~]# cat <<-END >/mnt/index.html <html> <body>DRBD Test site !!!</body> </html> END [root@node1 ~]# umount /dev/drbd1 |
Now, we will create a cluster resource for the DRBD device, and an additional clone resource to allow the resource to run on both nodes at the same time.
1 |
pcs cluster cib drbd_cfg |
NOTE: Using the pcs -f option, make changes to the configuration saved in the drbd_cfg file. These changes will not be seen by the cluster until the drbd_cfg file is pushed into the live cluster’s CIB later.
1 2 |
pcs -f drbd_cfg resource create WebData ocf:linbit:drbd \ drbd_resource=wwwdata op monitor interval=60s |
1 2 3 |
pcs -f drbd_cfg resource master WebDataClone WebData \ master-max=1 master-node-max=1 clone-max=2 clone-node-max=1 \ notify=true |
After you are satisfied with all the changes, you can commit them all at once by pushing the drbd_cfg file into the live CIB:
1 2 |
[root@node1 ~]# pcs cluster cib-push drbd_cfg CIB updated |
1 2 3 4 5 6 7 8 9 |
[root@node1 ~]# pcs status [...] Full list of resources: ClusterIP (ocf::heartbeat:IPaddr2): Started node1 WebSite (ocf::heartbeat:apache): Started node1 Master/Slave Set: WebDataClone [WebData] Masters: [ node1 ] Slaves: [ node2 ] |
The resource agent should load the DRBD module when needed if it’s not already loaded. If that does not happen, configure your operating system to the module at boot time. For CentOS 7.1, you would run this on both nodes:
1 |
echo drbd >/etc/modules-load.d/drbd.conf |
Now that we have a working DRBD device, we need to mount its filesystem. In addition to defining the filesystem, we also need to tell the cluster where it can be located (only on the DRBD Primary) and when it is allowed to start (after the Primary was promoted).
1 2 3 |
[root@node1 ~]# pcs cluster cib fs_cfg [root@node1 ~]# pcs -f fs_cfg resource create WebFS Filesystem \ device="/dev/drbd1" directory="/var/www/html" fstype="xfs" |
1 |
[root@node1 ~]# pcs -f fs_cfg constraint colocation add WebFS with WebDataClone INFINITY with-rsc-role=Master |
1 |
[root@node1 ~]# pcs -f fs_cfg constraint order promote WebDataClone then start WebFS |
We also need to tell the cluster that Apache needs to run on the same machine as the filesystem and that it must be active before Apache can start.
1 2 |
[root@pcmk-1 ~]# pcs -f fs_cfg constraint colocation add WebSite with WebFS INFINITY [root@pcmk-1 ~]# pcs -f fs_cfg constraint order WebFS then WebSite |
1 |
[root@node1 ~]# pcs cluster cib-push fs_cfg |
Now if we check the status of the DRBD resoruce:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
[root@node1 ~]# pcs status Full list of resources: ClusterIP (ocf::heartbeat:IPaddr2): Started node1 WebSite (ocf::heartbeat:apache): Started node1 Master/Slave Set: WebDataClone [WebData] Masters: [ node1 ] Slaves: [ node2 ] WebFS (ocf::heartbeat:Filesystem): Started node1 Daemon Status: corosync: active/enabled pacemaker: active/enabled pcsd: active/enabled |
Since node1 is running the web server right now, the WebFS is mounted on node1.
Now if we perform a request against http://192.168.125.10 we will see the index.html created on ‘/dev/drbd1’
Now we proceed to change the index.html mounted on node1 on /var/www/ and we change the HTML body:
1 2 3 |
<html> <body>DRBD This site has been modified!!!</body> </html> |
And we force a failover to node2 putting node1 in standby mode:
1 2 3 4 5 6 7 8 9 10 |
[root@node1 ~]# pcs cluster standby node1 [root@node1 ~]# pcs status Full list of resources: ClusterIP (ocf::heartbeat:IPaddr2): Started node2 WebSite (ocf::heartbeat:apache): Started node2 Master/Slave Set: WebDataClone [WebData] Masters: [ node2 ] Stopped: [ node1 ] WebFS (ocf::heartbeat:Filesystem): Started node2 |
If we perform ‘drbdadm’ status on node2 we don’t see node1 and node2 is now primary:
1 2 3 4 |
[root@node2 ~]# drbdadm status wwwdata role:Primary disk:UpToDate node1 connection:Connecting |
And finally if we check the content of /var/www/index.html on node2 we can see the file with the new HTML body that we changed on node1!!!
1 2 3 4 |
[root@node2 ~]# cat /var/www/html/index.html <html> <body>DRBD This site has been modified!!!</body> </html> |
We activate again node1:
1 |
[root@node1 ~]# pcs cluster unstandby node1 |
With the above steps and steps and steps followed on the previous post you should be able to set up your own HA cluster active/standby.
Good job, I’ll be waiting for some new posts.
👍👍
very useful and interesting article