{"id":7810,"date":"2019-05-03T16:47:08","date_gmt":"2019-05-03T08:47:08","guid":{"rendered":"http:\/\/rmohan.com\/?p=7810"},"modified":"2019-05-03T16:47:11","modified_gmt":"2019-05-03T08:47:11","slug":"simple-way-to-configure-ngnix-high-availability-web-server-with-pacemaker-and-corosync-on-centos7","status":"publish","type":"post","link":"https:\/\/mohan.sg\/?p=7810","title":{"rendered":"Simple way to configure Ngnix High Availability Web Server with Pacemaker and Corosync on CentOS7"},"content":{"rendered":"\n<p>Pacemaker is an open source cluster manager software which provide high availability of resources or services in CentOS 7 or RHEL 7 Linux. It has feature of scalable and advanced HA Cluster Manager. This HA cluster manager distributed by ClusterLabs.<\/p>\n\n\n\n<p>Corosync is the core of Pacemaker Cluster Manager as it is responsible for generating heartbeat communication between cluster nodes which make it capable of deploying High Availability in applications. Corosync is derived from an Open Source project OpenAIS under new BSD License.<\/p>\n\n\n\n<p>Pcsd is a Pacemaker command line interface (CLI) and GUI for managing the Pacemaker cluster. PCSD command pcs is use for creating, configuring and adding a new node to cluster.<\/p>\n\n\n\n<p>In this tutorial I will use pcsd in CLI for configuring Active\/Passive Pacemaker Cluster to provide high availability of Nginx webservice in CentOS 7. In this article I have tried to give basic idea of how to configure the Pacemaker cluster on CentOS 7 (applicable same to RHEL 7 as CentOS is mimic of RHEL). For basic cluster configuration I have disable the STONITH and ignore the Quorum but for Production environment I suggest to use STONITH feature of Pacemaker.<\/p>\n\n\n\n<p>Here is Short Defination of STONITH: STONITH or Shoot The Other Node In The Head is the fencing implementation on Pacemaker. It is a technique for fencing in computer clusters. Fencing is the isolation of a failed node so that it does not cause disruption to a computer cluster.<\/p>\n\n\n\n<p>For demonstration I have built two VMs (Virtual Machines) on KVM based on my Ubuntu 16.04 base machine and those VMs have private IP addresses.<\/p>\n\n\n\n<p>Note: I am referring my VMs as Cluster node for better presenting them in rest of the topics.<\/p>\n\n\n\n<p>Pre-requisite for configuring pacemaker cluster<\/p>\n\n\n\n<p>Minimum two CentOS 7 Server<br>\nwebserver01: 192.168.1.33<br>\nwebserver02: 192.168.1.34<br>\nFloating IP Address: 192.168.1.30<br>\nRoot Privilege<\/p>\n\n\n\n<p>Below are the points which I will follow for Installing and Configuring two node Pacemaker Cluster:<\/p>\n\n\n\n<ol><li>Mapping of Host File<\/li><li>Installation of Epel Repository and Nginx<\/li><li>Installation and Configuration of Pacemaker, Corosync, and Pcsd<\/li><li>Creation and Configuration of Cluster<\/li><li>Disabling of STONITH and Ignoring Quorum Policy<\/li><li>Adding of Floating-IP and Resources<\/li><li>Testing the Cluster service<\/li><\/ol>\n\n\n\n<p>Steps for Installation and configuration of pacemaker cluster<\/p>\n\n\n\n<ol><li>Mapping of host files:<\/li><\/ol>\n\n\n\n<p>As in my test lab I am not using DNS for resolving the both pacemaker cluster node hostname thus I have configured \/etc\/hosts file for resolving hostname of both nodes. But my suggestion is, though you have DNS in your environment for name resolution but still for better Pacemaker Cluster heartbeat communication between cluster nodes you should configure \/etc\/hosts file.<\/p>\n\n\n\n<p>Edit the \/etc\/hosts file with desire editor in both cluster nodes, below is example of \/etc\/hosts file which I have configured in both cluster nodes.<\/p>\n\n\n<p>[root@webserver01 ~]<\/p>\n\n\n\n<p># cat \/etc\/hosts<br>\n127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4<br>\n::1 localhost localhost.localdomain localhost6 localhost6.localdomain6<br>\n192.168.1.33 webserver01<br>\n192.168.1.34 webserver02<br><\/p>\n\n\n<p>[root@webserver01 ~]<\/p>\n\n\n\n<p># \n<\/p>\n\n\n<p>[root@webserver02 ~]<\/p>\n\n\n\n<p># cat \/etc\/hosts<br>\n127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4<br>\n::1 localhost localhost.localdomain localhost6 localhost6.localdomain6<br>\n192.168.1.33 webserver01<br>\n192.168.1.34 webserver02<br><\/p>\n\n\n<p>[root@webserver02 ~]<\/p>\n\n\n\n<p>#<br>\nPost \/etc\/hosts file configuration we will test the connectivity of both cluster nodes with each other through ping command:<br>\nExample:\n<\/p>\n\n\n\n<p>ping -c 3 webserver01<br>\nping -c 3 webserver02<br>\nIf we will get reply like below that means our webservers are communicating with each other.<\/p>\n\n\n<p>[root@webserver01 ~]<\/p>\n\n\n\n<p># ping -c 3 webserver02<br>\nPING webserver02 (192.168.1.34) 56(84) bytes of data.<br>\n64 bytes from webserver02 (192.168.1.34): icmp_seq=1 ttl=64 time=1.10 ms<br>\n64 bytes from webserver02 (192.168.1.34): icmp_seq=2 ttl=64 time=0.727 ms<br>\n64 bytes from webserver02 (192.168.1.34): icmp_seq=3 ttl=64 time=0.698 ms\n<\/p>\n\n\n\n<p>&#8212; webserver02 ping statistics &#8212;<br>\n3 packets transmitted, 3 received, 0% packet loss, time 2002ms<br>\nrtt min\/avg\/max\/mdev = 0.698\/0.843\/1.106\/0.188 ms<br>\n<\/p>\n\n\n<p>[root@webserver01 ~]<\/p>\n\n\n\n<p>#\n<\/p>\n\n\n<p>[root@webserver02 ~]<\/p>\n\n\n\n<p># ping -c 3 webserver01<br>\nPING webserver01 (192.168.1.33) 56(84) bytes of data.<br>\n64 bytes from webserver01 (192.168.1.33): icmp_seq=1 ttl=64 time=0.197 ms<br>\n64 bytes from webserver01 (192.168.1.33): icmp_seq=2 ttl=64 time=0.123 ms<br>\n64 bytes from webserver01 (192.168.1.33): icmp_seq=3 ttl=64 time=0.114 ms\n<\/p>\n\n\n\n<p>&#8212; webserver01 ping statistics &#8212;<br>\n3 packets transmitted, 3 received, 0% packet loss, time 1999ms<br>\nrtt min\/avg\/max\/mdev = 0.114\/0.144\/0.197\/0.039 ms<br>\n<\/p>\n\n\n<p>[root@webserver02~]<\/p>\n\n\n\n<p>#\n<\/p>\n\n\n\n<ol><li>Installation of Epel Repository and Nginx<\/li><\/ol>\n\n\n\n<p>In this Steps we will install EPEL (Extra Package for Enterprise Linux) repository and then Nginx. For Nginx installation EPEL repository package need to install first.<\/p>\n\n\n\n<p>yum -y install epel-release <br>\nNow install Nginx:<\/p>\n\n\n\n<p>yum -y install nginx<\/p>\n\n\n\n<ol><li>Install and Configure Pacemaker, Corosync, and Pcsd<\/li><\/ol>\n\n\n\n<p>Now we will install the pacemaker, pcs and corosync package with yum command. These package does not require seperate repository as they will use default CentOS repository.<\/p>\n\n\n\n<p>yum -y install corosync pacemaker pcs<br>\nOnce Cluster packages will install successfully enable the cluster services in startup through systemctl commands as mentioned below:<\/p>\n\n\n\n<p>systemctl enable pcsd<br>\nsystemctl enable corosync<br>\nsystemctl enable pacemaker<br>\nNow Start the pcsd service in both cluster nodes and also enable it in system startup.<\/p>\n\n\n\n<p>systemctl start pcsd.service<br>\nsystemctl enable pcsd.service<br>\nThe pcsd daemon works with the pcs command-line interface to manage synchronizing the corosync configuration across all nodes in the cluster.<\/p>\n\n\n\n<p>The user hacluster is created automatically with disable password during package installation this account is needed a login credential for syncing the corosync configuration, or starting and stopping the cluster service on other cluster nodes.<br>\nIn next step we will create a new password for hacluster user and we will use same password for rest cluster node as well.<\/p>\n\n\n\n<p>passwd hacluster<br>\nChanging password for user hacluster.<br>\nNew password:<br>\nRetype new password:<br>\npasswd: all authentication tokens updated successfully.<\/p>\n\n\n\n<ol><li>Creation and Configuration of Cluster<\/li><\/ol>\n\n\n\n<p>Note: This steps from Step 4 to 7 will only need to perform on webserver01 server.<br>\nThis step will cover the creating of new 2 nodes CentOS Linux cluster servers which will host Nginx resources and Floating IP Address.<\/p>\n\n\n\n<p>First of all to create cluster we need to authorize all servers using the pcs command and the hacluster user.<\/p>\n\n\n\n<p>Authorize both cluster webservers with the pcs command and hacluster user and password.<\/p>\n\n\n<p>[root@webserver01 ~]<\/p>\n\n\n\n<p># pcs cluster auth webserver01 webserver02<br>\nUsername: hacluster<br>\nPassword:<br>\nwebserver01: Authorized<br>\nwebserver02: Authorized<br><\/p>\n\n\n<p>[root@webserver01 ~]<\/p>\n\n\n\n<p>#<br>\nNote: If you are getting below error after running above auth command:\n<\/p>\n\n\n<p>[root@webserver01 ~]<\/p>\n\n\n\n<p># pcs cluster auth webserver01 webserver02<br>\nUsername: hacluster<br>\nPassword:<br>\nwebserver01: Authorized<br>\nError: Unable to communicate with webserver02<br>\nThen you need to define firewalld rules in both nodes which enable the communication of both Cluster nodes:\n<\/p>\n\n\n\n<p>Below are the example for adding rules for Cluster and ngnix as well<\/p>\n\n\n<p>[root@webserver01 ~]<\/p>\n\n\n\n<p># firewall-cmd &#8211;permanent &#8211;add-service=high-availability<br>\nsuccess<br><\/p>\n\n\n<p>[root@webserver01 ~]<\/p>\n\n\n\n<p># firewall-cmd &#8211;permanent &#8211;add-service=http<br>\nsuccess<br><\/p>\n\n\n<p>[root@webserver01 ~]<\/p>\n\n\n\n<p># firewall-cmd &#8211;permanent &#8211;add-service=https<br>\nsuccess<br><\/p>\n\n\n<p>[root@webserver01 ~]<\/p>\n\n\n\n<p># firewall-cmd &#8211;reload<br>\nsuccess<br><\/p>\n\n\n<p>[root@webserver01 ~]<\/p>\n\n\n\n<p># firewall-cmd &#8211;list-all<br>\npublic (active)<br>\ntarget: default<br>\nicmp-block-inversion: no<br>\ninterfaces: eth0<br>\nsources:<br>\nservices: ssh dhcpv6-client high-availability http https<br>\nports:<br>\nprotocols:<br>\nmasquerade: no<br>\nforward-ports:<br>\nsource-ports:<br>\nicmp-blocks:<br>\nrich rules:\n<\/p>\n\n\n<p>[root@webserver01 ~]<\/p>\n\n\n\n<p>#<br>\nNow we will define the cluster name and cluster node members.\n<\/p>\n\n\n\n<p>pcs cluster setup &#8211;name web_cluster webserver01 webserver02<br>\nNext start the all cluster services and enable them in system startup.<\/p>\n\n\n<p>[root@webserver01 ~]<\/p>\n\n\n\n<p># pcs cluster start &#8211;all<br>\nwebserver02: Starting Cluster\u2026<br>\nwebserver01: Starting Cluster\u2026<br><\/p>\n\n\n<p>[root@webserver01 ~]<\/p>\n\n\n\n<p># pcs cluster enable &#8211;all<br>\nwebserver01: Cluster Enabled<br>\nwebserver02: Cluster Enabled<br><\/p>\n\n\n<p>[root@webserver01 ~]<\/p>\n\n\n\n<p>#<br>\nRun the below command to check the Cluster status\n<\/p>\n\n\n\n<p>pcs status cluster<\/p>\n\n\n<p>[root@webserver01 ~]<\/p>\n\n\n\n<p># pcs status cluster<br>\nCluster Status:<br>\nStack: corosync<br>\nCurrent DC: webserver02 (version 1.1.18-11.el7_5.3-2b07d5c5a9) &#8211; partition with quorum<br>\nLast updated: Tue Sep 4 02:38:20 2018<br>\nLast change: Tue Sep 4 02:33:06 2018 by hacluster via crmd on webserver02<br>\n2 nodes configured<br>\n0 resources configured\n<\/p>\n\n\n\n<p>PCSD Status:<br>\nwebserver01: Online<br>\nwebserver02: Online<br>\n<\/p>\n\n\n<p>[root@webserver01 ~]<\/p>\n\n\n\n<p>#\n<\/p>\n\n\n\n<ol><li>Disabling of STONITH and Ignoring Quorum Policy<br>\nIn this tutorial we will disable the STONITH and Quorum policy as we are not using fencing device here. But if you want to implement Cluster in Production environment then I suggest to use Fencing and Quorum Policy.<\/li><\/ol>\n\n\n\n<p>Disable the STOITH:<\/p>\n\n\n\n<p>pcs property set stonith-enabled=false<br>\nIgnore the Quorum Policy:<\/p>\n\n\n\n<p>pcs property set no-quorum-policy=ignore<br>\nNow Check whether STONITH and Quorum policy are disable or not with below command:<\/p>\n\n\n\n<p>pcs property list<br>\n<\/p>\n\n\n<p>[root@webserver01 ~]<\/p>\n\n\n\n<p># pcs property list<br>\nCluster Properties:<br>\ncluster-infrastructure: corosync<br>\ncluster-name: web_cluster<br>\ndc-version: 1.1.18-11.el7_5.3-2b07d5c5a9<br>\nhave-watchdog: false<br>\nno-quorum-policy: ignore<br>\nstonith-enabled: false<br><\/p>\n\n\n<p>[root@webserver01 ~]<\/p>\n\n\n\n<p>#\n<\/p>\n\n\n\n<ol><li>Adding of Floating-IP and Resources<\/li><\/ol>\n\n\n\n<p>Floating IP address are cluster virtual IP address which float or move automatically from one cluster node to another cluster node in event of one Active Cluster node failure or disable which was hosting cluster resources.<\/p>\n\n\n\n<p>In this step we will add Floating IP and Nginx resources:<\/p>\n\n\n\n<p>Adding Floating IP<\/p>\n\n\n\n<p>pcs resource create virtual_ip ocf:heartbeat:IPaddr2 ip=192.168.1.30 cidr_netmask=32 op monitor interval=30s<br>\nAdding nginx resources<\/p>\n\n\n\n<p>pcs resource create webserver ocf:heartbeat:nginx configfile=\/etc\/nginx\/nginx.conf op monitor timeout=&#8221;5s&#8221; interval=&#8221;5s&#8221;<br>\nNow check newly added resources from below command:<\/p>\n\n\n\n<p>pcs status resources <\/p>\n\n\n<p>[root@webserver01 ~]<\/p>\n\n\n\n<p># pcs status resources<br>\nvirtual_ip (ocf::heartbeat:IPaddr2): Started webserver01<br>\nwebserver (ocf::heartbeat:nginx): Started webserver01<br><\/p>\n\n\n<p>[root@webserver01 ~]<\/p>\n\n\n\n<p># \n<\/p>\n\n\n\n<ol><li>Testing the Cluster service<\/li><\/ol>\n\n\n\n<p>To check cluster service running status<br>\nNow We will check the Cluster service status before moving to test nginx webservice failover in event of one Active Cluster node fail.<\/p>\n\n\n\n<p>To check running cluster service status below is the command with example:<\/p>\n\n\n<p>[root@webserver01 ~]<\/p>\n\n\n\n<p># pcs status<br>\nCluster name: web_cluster<br>\nStack: corosync<br>\nCurrent DC: webserver01 (version 1.1.18-11.el7_5.3-2b07d5c5a9) &#8211; partition with quorum<br>\nLast updated: Tue Sep 4 03:55:47 2018<br>\nLast change: Tue Sep 4 03:15:29 2018 by root via cibadmin on webserver01\n<\/p>\n\n\n\n<p>2 nodes configured<br>\n2 resources configured<\/p>\n\n\n\n<p>Online: [ webserver01 webserver02 ]<\/p>\n\n\n\n<p>Full list of resources:<\/p>\n\n\n\n<p>virtual_ip (ocf::heartbeat:IPaddr2): Started webserver01<br>\nwebserver (ocf::heartbeat:nginx): Started webserver01<\/p>\n\n\n\n<p>Daemon Status:<br>\ncorosync: active\/enabled<br>\npacemaker: active\/enabled<br>\npcsd: active\/enabled<br>\n<\/p>\n\n\n<p>[root@webserver01 ~]<\/p>\n\n\n\n<p>#<br>\nTo test ngnix webservice failover:\n<\/p>\n\n\n\n<p>First of we will create a webpages in both cluster nodes by below command:<br>\nIn webserver01:<\/p>\n\n\n\n<p>echo &#8216;<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">webserver01 &#8211; Web-Cluster-Testing<\/h1>\n\n\n\n<p>&#8216; &gt; \/usr\/share\/nginx\/html\/index.html<br>\necho &#8216;<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">webserver02 &#8211; Web-Cluster-Testing<\/h1>\n\n\n\n<p>&#8216; &gt; \/usr\/share\/nginx\/html\/index.html<br>\nNow open this web page with Floating IP address (192.168.1.30) which we had configured with Cluster resources in previous steps, you will see currently webpage is accessible from webserver01:\n<\/p>\n\n\n\n<p>Now stop the cluster service in webserver01 and after it again open the webpage with same floating IP address. Below is the command for Stopping pacemaker cluster in webserver01:<\/p>\n\n\n\n<p>pcs cluster stop webserver01<br>\nAfter stopping the pacemaker cluster in webserver01 this time webpage should be accessed from webserver02:<\/p>\n","protected":false},"excerpt":{"rendered":"\n<p>Pacemaker is an open source cluster manager software which provide high availability of resources or services in CentOS 7 or RHEL 7 Linux. It has feature of scalable and advanced HA Cluster Manager. This HA cluster manager distributed by ClusterLabs.<\/p>\n<p>Corosync is the core of Pacemaker Cluster Manager as it is responsible for generating [&#8230;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[73],"tags":[],"_links":{"self":[{"href":"https:\/\/mohan.sg\/index.php?rest_route=\/wp\/v2\/posts\/7810"}],"collection":[{"href":"https:\/\/mohan.sg\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mohan.sg\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mohan.sg\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/mohan.sg\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=7810"}],"version-history":[{"count":1,"href":"https:\/\/mohan.sg\/index.php?rest_route=\/wp\/v2\/posts\/7810\/revisions"}],"predecessor-version":[{"id":7811,"href":"https:\/\/mohan.sg\/index.php?rest_route=\/wp\/v2\/posts\/7810\/revisions\/7811"}],"wp:attachment":[{"href":"https:\/\/mohan.sg\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=7810"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mohan.sg\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=7810"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mohan.sg\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=7810"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}