Monday, 27 April 2015

High-Availability (HA) Apache Cluster - CentOS 7

In this article, I would be walk through the steps required to build a high-availability apache cluster on CentOS 7. In CentOS 7(as in RHEL 7) the cluster stack has been moved to pacemaker/corosync, with a new command line tool(pcs) to manage the cluster.

Environment Description:
The cluster would be of 2-node(centos71 & centos72), iSCSI shared storage will be presented from the node iscsitarget which is around 1GB.
If you want to know on how to share disk from iscsi click here

Objective:
High availability cluster that is serving websites where its document root would be utilising a simple failover filesystem.
In a stable situation, cluster should look something like this:


There is one owner of the virtual IP, in this case that is centos71. The owner of the virtual IP also provides the service for the cluster at that moment. A client that is trying to reach our website via 192.168.229.134 will be served the webpages from the webserver running on centos71 . In the above situation, the second node is not doing anything besides waiting for centos71 to fail and take over. This scenario is called active-passive.

In case something happens to centos71 the system crashes, the node is no longer reachable or the webserver isn't responding anymore, centos72 will become the owner of the virtual IP and start its webserver to provide the same services as were running on centos71


Pre-requsites:
Configure both the cluster nodes with static IP, hostname, and make sure they are in the same subnet and could be reached each other by their nodenames.(either you could add it in /etc/hosts or configure your DNS server)

If you had configured your firewall, make sure you allow cluster traffic(incase if they are active on any nodes), in this example, I had shutdown the firewall.

Installation:
After your basic setup, install packages
[root@centos71 ~]# yum install corosync pcs pacemaker
[root@centos72 ~]# yum install corosync pcs pacemaker

To manage cluster nodes, we will use PCS. this allows us to have a single interface to manage all cluster nodes. By installing the necessary packages, Yum also created a user, hacluster, which can be used together with PCS to do the configuration of the cluster nodes.

[root@centos71 ~]# passwd hacluster
[root@centos72 ~]# passwd hacluster

Next, start the pcsd service on both nodes:
[root@centos71 ~]# systemctl start pcsd
[root@centos72 ~]# systemctl start pcsd

Since we will configure all nodes from one point, we need to authenticate on all nodes before we are allowed to change the configuration. Use the previously configured hacluster user and password to do this.

[root@centos71 ~]# pcs cluster auth centos71 centos72
From here, we can control the cluster by using PCS from centos71 It's no longer required to repeat all commands on both nodes.

Create the cluster and add nodes
[root@centos71 ~]# pcs cluster setup --name webcluster centos71 centos72

The above command creates the cluster node configuration in /etc/corosync.conf
After creating the cluster and adding nodes to it, we can start it
[root@centos71 ~]# pcs cluster start --all
centos72: Starting Cluster...
centos71: Starting Cluster...
[root@centos71 ~]#

check the status of the cluster after starting it:
[root@centos71 ~]# pcs status cluster
Cluster Status:
 Last updated: Sun Apr 26 18:17:32 2015
 Last change: Sun Apr 26 18:16:26 2015 via cibadmin on centos71
 Stack: corosync
 Current DC: centos71 (1) - partition with quorum
 Version: 1.1.10-29.el7-368c726
 2 Nodes configured
 0 Resources configured
[root@centos71 ~]#

Since we have simple cluster, we'll just disable the stonith and ignore quorum device.
[root@centos71 ~]# pcs property set stonith-enabled=false
[root@centos71 ~]# pcs property set no-quorum-policy=ignore

Next, create a partition on the 1GB LUN  – this will house a filesystem to be used as the DocumentRoot for our Apache installation.
I had configured multipath for the device, hence install device-mapper* on both nodes. 
[root@centos71 ~]# mpathconf --enable
[root@centos72 ~]# mpathconf --enable
[root@centos71 ~]# systemctl multipathd start
[root@centos72 ~]# systemctl multipathd start

Create partiton from any of the one node, and then only 'partprobe' the second by default you would have had the same mapper device for the newly added iSCSI device. 
[root@centos71 ~]# lsblk -i
sdb                       8:16   0 1016M  0 disk
`-mpatha                253:6    0 1016M  0 mpath
  `-mpatha1             253:7    0 1015M  0 part
[root@centos71 ~]#

[root@centos72 ~]# lsblk -i
sdb                       8:16   0 1016M  0 disk
`-mpatha                253:5    0 1016M  0 mpath
  `-mpatha1             253:6    0 1015M  0 part
[root@centos72 ~]#

[root@centos71 ~]# fdisk /dev/mapper/mpatha
[root@centos71 ~]# partprobe
[root@centos71 ~]# mkfs.ext4 /dev/mapper/mpatha1
[root@centos71 ~]# mount /dev/mapper/mpatha1 /var/www
[root@centos71 ~]# mkdir /var/www/html;mkdir /var/www/error; 
[root@centos71 ~]# echo "apache test page" >/var/www/html/index.html 
[root@centos71 ~]# umount /dev/mapper/mpatha1

Create the filesystem cluster resource fs_apache_shared, and would group it to "apachegroup" which will be used to group the resources together as one unit.
[root@centos71 ~]#  pcs resource create fs_apache_shared ocf:heartbeat:Filesystem device=/dev/mapper/mpatha1 fstype=ext4 directory="/var/www" --group=apachegroup
[root@centos71 ~]#

We will add a virtual IP to our cluster. This virtual IP is the IP address that which will be contacted to reach the services (the webserver in our case). A virtual IP is a resource.
[root@centos71 ~]# pcs resource create virtual_ip ocf:heartbeat:IPaddr2 ip=192.168.229.134 cidr_netmask=24 --group=apachegroup

Create a file /etc/httpd/conf.d/serverstatus.conf with the following contents on both nodes:
[root@centos71 ~]# cat /etc/httpd/conf.d/serverstatus.conf
Listen 127.0.0.1:80
 <Location /server-status>
 SetHandler server-status
 Order deny,allow
 Deny from all
 Allow from 127.0.0.1
 </Location>
[root@centos71 ~]#

Disable the current Listen-statement in the Apache configuration in order to avoid trying to listen multiple times on the same port.
[root@centos71 ~]#  grep -w "Listen 80" /etc/httpd/conf/httpd.conf
#Listen 80
[root@centos72 ~]#  grep -w "Listen 80" /etc/httpd/conf/httpd.conf
#Listen 80

Now that Apache is ready to be controlled by our cluster, we'll add a resource for the webserver
[root@centos71 ~]# pcs resource create webserver ocf:heartbeat:apache configfile=/etc/httpd/conf/httpd.conf statusurl="http://localhost/server-status" --group=apachegroup

Testing:
Browse http://192.168.229.134, it must display a test page. move your resource groups to partner node, where you shouldn't expect any downtime to your apache service.

[root@centos71 ~]# pcs status
Cluster name: webcluster
Last updated: Sun Apr 26 21:20:14 2015
Last change: Sun Apr 26 21:19:09 2015 via cibadmin on centos71
Stack: corosync
Current DC: centos71 (1) - partition with quorum
Version: 1.1.10-29.el7-368c726
2 Nodes configured
3 Resources configured

Online: [ centos71 centos72 ]

Full list of resources:

 Resource Group: apachegroup
     fs_apache_shared   (ocf::heartbeat:Filesystem):    Started centos71
     virtual_ip (ocf::heartbeat:IPaddr2):       Started centos71
     webserver  (ocf::heartbeat:apache):        Started centos71

PCSD Status:
  centos71: Online
  centos72: Online

Daemon Status:
  corosync: active/disabled
  pacemaker: active/disabled
  pcsd: active/disabled
[root@centos71 ~]#

[root@centos71 ~]# pcs resource move webserver
[root@centos71 ~]# pcs status
Cluster name: webcluster
Last updated: Sun Apr 26 21:21:00 2015
Last change: Sun Apr 26 21:20:57 2015 via crm_resource on centos71
Stack: corosync
Current DC: centos71 (1) - partition with quorum
Version: 1.1.10-29.el7-368c726
2 Nodes configured
3 Resources configured

Online: [ centos71 centos72 ]

Full list of resources:

 Resource Group: apachegroup
     fs_apache_shared   (ocf::heartbeat:Filesystem):    Started centos72
     virtual_ip (ocf::heartbeat:IPaddr2):       Started centos72
     webserver  (ocf::heartbeat:apache):        Started centos72

PCSD Status:
  centos71: Online
  centos72: Online

Daemon Status:
  corosync: active/disabled
  pacemaker: active/disabled
  pcsd: active/disabled
[root@centos71 ~]#

you can use df -h  to confirm file system failover, ip addr show to confirm IP address failover.