OS : Centos 5 , Kernel 2.6.18-53.1.4.el5

Notes : DRBD is of newer version in this setup. A little sharp edged! Be careful!

This is a partial extract from a setup I did recently. (now a year ago, when I am uploading it).

DB Servers:

hostname : db1.example.com
Public IP = 10.1.1.130
Private IP = 192.168.1.130

hostname : db2.example.com
Public IP = 10.1.1.131
Private IP = 192.168.1.131

Webmail Servers:

Public IP: 10.1.1.132
Private IP = 192.168.1.132

Public IP: 10.1.1.133
Private IP = 192.168.1.133

.134 = DB VIP
.135 = WEB VIP

The DB servers are the DNS as well.

On both servers:

yum  install bind bind-chroot caching-nameserver  
  
cp /etc/named.conf /var/named/chroot/etc  
rm -f /etc/named.conf  
ln -s /var/named/chroot/etc/named.conf /etc/named.conf  
  
vi /etc/named.conf       
. . .  
. . .  
view    "external"  
{  
/* This view will contain zones you want to serve only to "external" clients  
* that have addresses that are not on your directly attached LAN interface subnets:  
*/  
match-clients           { !localnets; !localhost; };  
match-destinations      { !localnets; !localhost; };  

recursion no;

you’d probably want to deny recursion to external clients, so you don’t
end up providing free DNS service to all takers

all views must contain the root hints zone:
include “/etc/named.root.hints”;

These are your “authoritative” external zones, and would probably
contain entries for just your web and mail servers:


      zone "my.external.zone" {  
              type master;  
              file "my.external.zone.db";  
      };  
  
zone "example.com" {  
type master;  
file "example.com.zone";  
};  
  
};  
  

vi /var/named/chroot/var/named/example.com.zone

$ORIGIN example.com.
$TTL 3600
@ IN SOA ns1.example.com. kamran.wbitt.com. (
20071214 ; serial (d. adams)
3H ; refresh
15M ; retry
1W ; expiry
1D ) ; minimum

@ IN NS ns1.example.com.
@ IN NS ns2.example.com.
@ IN MX 10 mail1.example.com.
@ IN MX 20 mail2.example.com.

ns1.example.com. IN A 10.1.1.130
ns2.example.com. IN A 10.1.1.131
webmail1.example.com. IN A 10.1.1.132
webmail2.example.com. IN A 10.1.1.133
db1.example.com. IN A 10.1.1.130
db2.example.com. IN A 10.1.1.131
mail1.example.com. IN CNAME webmail1.example.com.
mail2.example.com. IN CNAME webmail2.example.com.

Disable SELINUX on all 4 servers

chkconfig --level 35 named on  
chkconfig --level 35 sendmail off  
chkconfig --level 35 cups off  
chkconfig --level 35 pcmcia off  
  
  
[root@db1 ~]# service named start  
Starting named:  
Error in named configuration:  
/etc/named.conf:58: open: /etc/named.root.hints: file not found  
[FAILED]  
[root@db1 ~]#      
  
  
!OHHH!  
  
  
[root@db1 ~]# ls -l /var/named/chroot/var/named/named.ca  
-rw-r----- 1 root named 2518 Nov 10 07:22 /var/named/chroot/var/named/named.ca  
[root@db1 ~]#       

Now either I can copy the file found above, as in /var/named/chroot/etc/named.root.hints file.
And create it’s symbolic link in /etc/

Or:

I can simply query the latest name servers and put them directly in the file /var/named/chroot/etc/named.root.hints and create a symbolic link in /etc.

dig ns .  >  /var/named/chroot/etc/named.root.hints  
ln -s /var/named/chroot/etc/named.root.hints /etc/  
   
[root@db1 ~]# service named restart  
Stopping named:                                            [FAILED]  
Starting named:  
Error in named configuration:  
/etc/named.root.hints:2: '}' expected near ';'  
[FAILED]  
[root@db1 ~]#  

I think there is a bug in /etc/named.conf. The # should not be used for a comment . rather a

all views must contain the root hints zone:

include “/etc/named.root.hints”;

But even correcting that gives this error.

[root@db1 ~]# service named restart  
Stopping named:                                            [FAILED]  
Starting named:  
Error in named configuration:  
/etc/named.root.hints:2: '}' expected near ';'  
[FAILED]  
[root@db1 ~]#

OK I removed the following two lines from the top of hints file:

; DiG 9.3.3rc2 ns .

Still the same problem:

[root@db1 ~]# service named restart  
Stopping named:                                            [FAILED]  
Starting named:  
Error in named configuration:  
/etc/named.root.hints:1: '}' expected near ';'  
[FAILED]  
[root@db1 ~]#  

Problem is in /etc/named.conf, NOT root hints file.

Removed all views and placed a simple zone:

zone "example.com" {  
type master;  
file "example.com.zone";  
}; 

OK New problem:

[root@db1 ~]# service named restart  
Stopping named:                                            [FAILED]  
Starting named:                                            [FAILED]  
[root@db1 ~]#  
  
Dec 13 22:46:09 db1 named[3511]: /etc/named.conf:46: configuring key 'ddns_key': bad base64 encoding  
  
  
There is a section in /etc/named.conf  
  
key ddns_key  
{  
algorithm hmac-md5;  
secret "use /usr/sbin/dns-keygen to generate TSIG keys";  
};  

So ran the program :

[root@db1 ~]# /usr/sbin/dns-keygen  
9lc0vhBNGHgFpZ7k7rH7KjgSEg7uUZCRt4PZZYpsLqctWnlZMd7WQdCFMBo7  
[root@db1 ~]#  

Now lets copy and paste this key in /etc/named.conf . The code looks like this now:

key ddns_key  
{  
algorithm hmac-md5;  
secret "9lc0vhBNGHgFpZ7k7rH7KjgSEg7uUZCRt4PZZYpsLqctWnlZMd7WQdCFMBo7";  
};
  
[root@db1 ~]# service named restart  
Stopping named:                                            [FAILED]  
Starting named:                                            [  OK  ]  
[root@db1 ~]#     

Alhumdulillah.

The /etc/resolv.conf now looks like this:

nameserver 127.0.0.1
nameserver 10.2.2.160.16
nameserver 10.2.2.170.17

Zone transfers were not working. Turned out to be firewall problem. Turned off firewall on both DNS servers.

DNS done. Alhumdulillah. The traditional way.

DRBD setup:

yum -y install kernel kernel-devel kmod-drbd drbd

This will install newer kernel as well. Which will need a reboot.

The kernel on both servers is now:-

[root@db1 ~]# uname -r  
2.6.18-53.1.4.el5  
[root@db1 ~]#  
  
[root@db2 ~]# uname -r  
2.6.18-53.1.4.el5  
[root@db2 ~]#  

On both DB servers (Watch for the DRBD version):-

cp /usr/share/doc/drbd-8.0.6/drbd.conf /etc/

Then , on both DB servers:

vi /etc/drbd.conf  
  
global { usage-count yes; }  
common { syncer { rate 10M; } }  
resource r0 {  
protocol C;  
net {  
}  
on db1.example.com {  
device    /dev/drbd0;  
disk      /dev/sda6;  
address   192.168.1.130:7789;  
flexible-meta-disk  /dev/sda5;  
}  
on db2.example.com {  
device    /dev/drbd0;  
disk      /dev/sda6;  
address   192.168.1.131:7789;  
flexible-meta-disk  /dev/sda5;  
}  
}  

Then, on both DB servers:

modprobe drbd

This time modprobe was successful

echo "modprobe drbd" >> /etc/rc.local

Then on both DB servers:

drbdadm up all
. . .

Failure: (119) No valid meta-data signature found.

==> Use ‘drbdadm create-md res’ to initialize meta-data area. <==

Command ‘drbdsetup /dev/drbd0 disk /dev/sda6 /dev/sda5 flexible –set-defaults –create-device’ terminated with exit code 10
[root@db1 ~]#

OK let’s create md devices first on both DB servers.

drbdadm create-md all  
  
[root@db1 ~]# drbdadm create-md all  
v08 Magic number not found  
v07 Magic number not found  
About to create a new drbd meta data block  
on /dev/sda5.  
  
==> This might destroy existing data! <==  
  
Do you want to proceed?  
[need to type 'yes' to confirm] yes  
  
Creating meta data...  
initialising activity log  
NOT initialized bitmap (1003995 KB)  
New drbd meta data block sucessfully created.  
success  
[root@db1 ~]#    
  
[root@db2 ~]# drbdadm create-md all  
v08 Magic number not found  
v07 Magic number not found  
About to create a new drbd meta data block  
on /dev/sda5.  
  
==> This might destroy existing data! <==  
  
Do you want to proceed?  
[need to type 'yes' to confirm] yes  
  
Creating meta data...  
initialising activity log  
NOT initialized bitmap (1003995 KB)  
New drbd meta data block sucessfully created.  
success  
[root@db2 ~]#     

Now, again on both servers, turn on the drbd devices:

drbdadm up all  
  
Once this command is issued, both servers will have the status of Secondary/Secondary:  
  
[root@db1 ~]# cat /proc/drbd  
version: 8.0.6 (api:86/proto:86)  
SVN Revision: 3048 build by buildsvn@c5-i386-build, 2007-12-08 01:17:51  
0: cs:Connected st:Secondary/Secondary ds:Inconsistent/Inconsistent C r---  
ns:0 nr:0 dw:0 dr:0 al:0 bm:0 lo:0 pe:0 ua:0 ap:0  
resync: used:0/31 hits:0 misses:0 starving:0 dirty:0 changed:0  
act_log: used:0/127 hits:0 misses:0 starving:0 dirty:0 changed:0  
[root@db1 ~]#  
  
[root@db2 ~]# cat /proc/drbd  
version: 8.0.6 (api:86/proto:86)  
SVN Revision: 3048 build by buildsvn@c5-i386-build, 2007-12-08 01:17:51  
0: cs:Connected st:Secondary/Secondary ds:Inconsistent/Inconsistent C r---  
ns:0 nr:0 dw:0 dr:0 al:0 bm:0 lo:0 pe:0 ua:0 ap:0  
resync: used:0/31 hits:0 misses:0 starving:0 dirty:0 changed:0  
act_log: used:0/127 hits:0 misses:0 starving:0 dirty:0 changed:0  
[root@db2 ~]#  

You see that both DB servers say that they are secondary and that the data is inconsistant. This is because no initial sync has been made yet.

I want to make DB1 the primary DB/NFS server and DB2 the “hot-standby”, If DB1 fails, DB2 takes over, and if DB1 comes back then all data that has changed in the meantime is mirrored back from DB2 to DB1 so that data is always consistent.

Perfrom this step ONLY on DB1 (This will start the sync process and may take hours, depending on the IO speed of your setup):-

drbdadm -- --overwrite-data-of-peer primary all

Now you can keep checking the progress of both PCs, by monitoring the /proc/drbd file. Optionally you can watch for this file on both servers.

[root@db1 ~]# cat  /proc/drbd  
version: 8.0.6 (api:86/proto:86)  
SVN Revision: 3048 build by buildsvn@c5-i386-build, 2007-12-08 01:17:51  
0: cs:SyncSource st:Primary/Secondary ds:UpToDate/Inconsistent C r---  
ns:466944 nr:0 dw:0 dr:466944 al:0 bm:28 lo:0 pe:0 ua:0 ap:0  
[>...................] sync'ed:  0.3% (194865/195321)M  
finish: 4:48:41 speed: 11,460 (10,376) K/sec  
resync: used:0/31 hits:29155 misses:29 starving:0 dirty:0 changed:29  
act_log: used:0/127 hits:0 misses:0 starving:0 dirty:0 changed:0  
[root@db1 ~]#  

Started process on:

[root@db1 ~]# date  
Fri Dec 14 02:46:16 PST 2007  
[root@db1 ~]#  
  
[root@db2 ~]# cat /proc/drbd  
version: 8.0.6 (api:86/proto:86)  
SVN Revision: 3048 build by buildsvn@c5-i386-build, 2007-12-08 01:17:51  
0: cs:SyncTarget st:Secondary/Primary ds:Inconsistent/UpToDate C r---  
ns:0 nr:1799168 dw:1799168 dr:0 al:0 bm:109 lo:0 pe:0 ua:0 ap:0  
[>...................] sync'ed:  1.0% (193564/195321)M  
finish: 4:46:45 speed: 11,460 (10,280) K/sec  
resync: used:0/31 hits:112338 misses:110 starving:0 dirty:0 changed:110  
act_log: used:0/127 hits:0 misses:0 starving:0 dirty:0 changed:0  
[root@db2 ~]#  

After around 4 hours, I notice the status as:

[root@db1 ~]# cat /proc/drbd  
version: 8.0.6 (api:86/proto:86)  
SVN Revision: 3048 build by buildsvn@c5-i386-build, 2007-12-08 01:17:51  
0: cs:Connected st:Primary/Secondary ds:UpToDate/UpToDate C r---  
ns:200009218 nr:0 dw:0 dr:200009218 al:0 bm:12208 lo:0 pe:0 ua:0 ap:0  
resync: used:0/31 hits:12488370 misses:12208 starving:0 dirty:0 changed:12208  
act_log: used:0/127 hits:0 misses:0 starving:0 dirty:0 changed:0  
[root@db1 ~]#  


[root@db2 ~]# cat /proc/drbd  
version: 8.0.6 (api:86/proto:86)  
SVN Revision: 3048 build by buildsvn@c5-i386-build, 2007-12-08 01:17:51  
0: cs:Connected st:Secondary/Primary ds:UpToDate/UpToDate C r---  
ns:0 nr:200009218 dw:200009218 dr:0 al:0 bm:12208 lo:0 pe:0 ua:0 ap:0  
resync: used:0/31 hits:12488370 misses:12208 starving:0 dirty:0 changed:12208  
act_log: used:0/127 hits:0 misses:0 starving:0 dirty:0 changed:0  
[root@db2 ~]#  

I also see the status as “Connected” .

As per my understanding the following was only required in previous versions of DRBD.

# drbdadm -- connect all

It is not required in newer versions.

And if you issue this command in this state, you will get the following error:

[root@db1 ~]# drbdadm -- connect all  
Failure: (125) Device has a net-config (use disconnect first)  
Command 'drbdsetup /dev/drbd0 net 192.168.1.130:7789 192.168.1.131:7789 C --set-defaults --create-device' terminated with exit code 10  
drbdsetup exited with code 10  
[root@db1 ~]#  

And if you are “too determined” to issue this command in any case, then you need to disconnect the devices first:

# drbdadm -- disconnect all

# drbdadm -- connect all

Time to format the DRBD device.

Only on DB1:

mke2fs -v -j /dev/drbd0

Then on both servers, create a mount point:

mkdir /data

Now mount /dev/drbd0 on /data ONLY on DB1. Make sure that you DO NOT mention the mounting in /etc/fstab as that will be controlled through heartbeat.

mount -t ext3 /dev/drbd0 /data # only on DB1

Verify by using “mount” and df -h on DB1.

[root@db1 ~]# df -h  
Filesystem            Size  Used Avail Use% Mounted on  
/dev/sda1              19G  1.3G   17G   7% /  
tmpfs                1014M     0 1014M   0% /dev/shm  
/dev/drbd0            188G  188M  179G   1% /data  
  
  
[root@db1 ~]# mount  
...  
/dev/sda1 on / type ext3 (rw)  
/dev/drbd0 on /  
...  

Alhumdulillah.

Question: Do I need to format the same device on DB2 too ????

Answer: No. The DRBD is handling it. And on slave node, which this DB2 is, it will be readonly anyway.

Time to create the directories in /data, only on DB1, where your drbd0 device is mounted currently.

mkdir -p /data/nfs # This will serve for correct functionality of DB server  
mkdir -p /data/mysql # The /var/lilb/mysql will be linked here. Will be used for locally running MySQL server.  
mkdir -p /data/home # This will be mounted on /home on host1 and host2.  
mkdir -p /data/www # This will be mounted on /var/www on host1 and host2.  

You will need to change ownership of /data/mysql directory as it will be used at /var/lib/mysql. The uid and gid of user/group mysql MUST be same on both DB servers.

You may need to make sure that mysql-server package is installed. You may need to install it before moving ahead.

yum install mysql-server  
  
chown mysql:mysql /data/mysql  

Setup NFS exports file on BOTH DB servers:

vi /etc/exports
put the ip addresses of the webmail servers here /data/home 10.1.1.132(rw,no_root_squash) 10.1.1.133(rw,no_root_squash)
/data/www 10.1.1.132(rw,no_root_squash) 10.1.1.133(rw,no_root_squash)

Make sure that the NFS service is stopped on both NFS servers.

service nfs stop

Both servers:

cd /var/lib  
mv nfs nfs.old  

Now link the nfs from the /data/nfs to this place on both servers. This will create a valid link on DB1 and invalid link on DB2.

On both servers:

ln -s /data/nfs nfs

only on DB1:

cp -r nfs.old/* nfs/

If you start NFS service on DB1 only, now, then NFS will create new files in /var/lib/nfs -> /data/nfs for itself. Good.

But I am not going to start NFS now.

HEARTBEAT:

Lets install Heartbeat and IPVSADM , etc on both DB servers.

Lets install heartbeat and related packages on BOTH DB servers:

yum install curl perl-Crypt-SSLeay perl-HTML-Parser perl-LDAP perl-Net-DNS perl-libwww-perl libidn perl-Convert-ASN1 perl-Digest-HMAC perl-HTML-Tagset perl-URI perl-XML-SAX perl-Digest-SHA1 perl-XML-NamespaceSupport perl-Mail-IMAPClient heartbeat ipvsadm

Now, on both DB servers, create this file:

vi /etc/ha.d/ha.cf  
logfacility     local0  
keepalive 2  
#deadtime 30 # USE THIS!!!  
deadtime 10  
bcast   eth1  
#serial /dev/ttyS0  
#baud 19200  
auto_failback off  
node db1.example.com db2.example.com  

Now create haresources file on both DB servers. 10.1.1.134 will be the cluster IP.

DB1:

vi /etc/ha.d/haresources  
  
db1.example.com IPaddr::10.1.1.134/27/eth0 drbddisk::r0 Filesystem::/dev/drbd0::/data::ext3 nfs  

DB2:

vi /etc/ha.d/haresources  
  
db2.example.com IPaddr::10.1.1.134/27/eth0 drbddisk::r0 Filesystem::/dev/drbd0::/data::ext3 nfs  

Both servers:

vi /etc/ha.d/authkeys  
  
auth 3  
3 md5 redhat  

Both DB servers:

chmod 600 /etc/ha.d/authkeys  
  
Time to start DRBD and Heartbeat services on both servers.  
  
[root@db1 ~]# service drbd start  
Starting DRBD resources:    [ ].  
[root@db1 ~]#  
  
[root@db2 ~]# service drbd start  
Starting DRBD resources:    [ ].  
[root@db2 ~]#  
  
[root@db1 ~]# service heartbeat start  
Starting High-Availability services:  
2007/12/15_11:38:45 INFO:  Resource is stopped  
[  OK  ]  
[root@db1 ~]#  
  
  
[root@db2 ~]# service heartbeat start  
Starting High-Availability services:  
2007/12/15_11:40:13 INFO:  Resource is stopped  
[  OK  ]  
[root@db2 ~]#  

Ifconfig reveals the following on each server:

[root@db1 ~]# ifconfig  
eth0      Link encap:Ethernet  HWaddr 00:20:30:61:AF:94  
inet addr:10.1.1.130  Bcast:10.1.1.159  Mask:255.255.255.224  
inet6 addr: fe80::230:48ff:fe61:af94/64 Scope:Link  
UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1  
RX packets:132587 errors:0 dropped:0 overruns:0 frame:0  
TX packets:115896 errors:0 dropped:0 overruns:0 carrier:0  
collisions:0 txqueuelen:100  
RX bytes:32074701 (30.5 MiB)  TX bytes:11049930 (10.5 MiB)  
Base address:0x2000 Memory:d8920000-d8940000  
  
eth0:0    Link encap:Ethernet  HWaddr 00:20:30:61:AF:94  
inet addr:10.1.1.134  Bcast:10.1.1.159  Mask:255.255.255.224  
UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1  
Base address:0x2000 Memory:d8920000-d8940000  
...  
  
  
  
[root@db2 ~]# ifconfig  
eth0      Link encap:Ethernet  HWaddr 00:20:30:61:AF:4E  
inet addr:10.1.1.131  Bcast:10.1.1.159  Mask:255.255.255.224  
inet6 addr: fe80::230:48ff:fe61:af4e/64 Scope:Link  
UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1  
RX packets:132652 errors:0 dropped:0 overruns:0 frame:0  
TX packets:117073 errors:0 dropped:0 overruns:0 carrier:0  
collisions:0 txqueuelen:100  
RX bytes:33537810 (31.9 MiB)  TX bytes:10732645 (10.2 MiB)  
Base address:0x2000 Memory:d8920000-d8940000  
...  

Now on both DB servers:

chkconfig --level 35 drbd on  
chkconfig --level 35 heartbeat on  

Now create an account for webmaster on all 4 servers, with same uid/gid

Both NFS servers:

groupadd -g 509 webmaster  
useradd -u 509 -g 509  -s /bin/bash -d /var/www/vhosts webmaster  
passwd webmaster  
  
**Lets check and then mount the exported directories on web servers:**
  
[root@webmail1 ~]# showmount -e 10.1.1.134  
Export list for 10.1.1.134:  
/data/www  10.1.1.133,10.1.1.132  
/data/home 10.1.1.133,10.1.1.132  
  
  
[root@webmail2 ~]# showmount -e 10.1.1.134  
Export list for 10.1.1.134:  
/data/www  10.1.1.133,10.1.1.132  
/data/home 10.1.1.133,10.1.1.132  

Now mount the /data/www on /var/www/ on each webserver:

mount -t nfs 10.1.1.134:/data/www /var/www/  
 
[root@webmail1 ~]# mount -t nfs 10.1.1.134:/data/www /var/www/  
  
[root@webmail1 ~]# df -h  
Filesystem            Size  Used Avail Use% Mounted on  
/dev/sda1              20G  1.1G   18G   6% /  
tmpfs                 1.5G     0  1.5G   0% /dev/shm  
10.1.1.134:/data/www  
188G  188M  179G   1% /var/www  
[root@webmail1 ~]#  
  
  
[root@webmail2 ~]#  mount -t nfs 10.1.1.134:/data/www /var/www/  
  
[root@webmail2 ~]# df -h  
Filesystem            Size  Used Avail Use% Mounted on  
/dev/sda1              20G  1.1G   18G   6% /  
tmpfs                 1.5G     0  1.5G   0% /dev/shm  
10.1.1.134:/data/www  
188G  188M  179G   1% /var/www  
[root@webmail2 ~]#  

Now on both WEB Servers:

vi /etc/fstab  
. . .  
. . .  
10.1.1.134:/data/www     /var/www                nfs     defaults        0 0  

Alright. It’s time to sync the old webserver’s content with this new one. I will log on to the old server at liquid web as root and sync content via rsync to the primary db server, here.

On host1.example.com, as root, do the following:

rsync -avz -e ssh /var/www/ root@10.1.1.130:/data/www/

MYSQL:

If you create the a symbolic link from /data/mysql to /var/lib/mysql. It will NOT work and everytime mysql WILL FAIL TO START. MySQL expects this to be a directory, not a symbolic link. The solution is to edit the /etc/my.cnf and change the directives from from “/var/lib” to “/data” . So when mysqld is started, it will automatically create the /data/mysql directory. And will start fine. Thanks to Naveed Ahmad (naveed@wbitt.com) for pointing this out.

On both Servers:

cp /etc/my.cnf /etc/my.cnf.orig  
  
vi /etc/my.cnf  
  
[mysqld]  
# datadir=/var/lib/mysql  
datadir=/data/mysql  
#socket=/var/lib/mysql/mysql.sock  
socket=/data/mysql/mysql.sock  
# Default to using old password format for compatibility with mysql 3.x  
# clients (those using the mysqlclient10 compatibility package).  
old_passwords=1  
  
[mysql.server]  
user=mysql  
#basedir=/var/lib  
basedir=/data  
  
[mysqld_safe]  
log-error=/var/log/mysqld.log  
pid-file=/var/run/mysqld/mysqld.pid  
  
[mysql]  
socket=/data/mysql/mysql.sock  

Before actually starting the mysql service, do the following:

The /etc/init.d/mysqld script has a section as :

  • Spin for a maximum of N seconds waiting for the server to come up.
  • Rather than assuming we know a valid username, accept an “access
  • denied” response as meaning the server is functioning.
echo "result of starting mysqld_safe is $ret"          
if [ $ret -eq 0 ]; then              
STARTTIMEOUT=30              
while [ $STARTTIMEOUT -gt 0 ]; do                  
RESPONSE=`/usr/bin/mysqladmin -uUNKNOWN_MYSQL_USERping 2>&1` && break                  
echo "$RESPONSE" | grep -q "Access denied for user" && break                  
sleep 1                  
let STARTTIMEOUT=${STARTTIMEOUT}-1              
done              
if [ $STARTTIMEOUT -eq 0 ]; then                      
echo "Timeout error occurred trying to start MySQL Daemon."  
action $"Starting $prog: " /bin/false  
else                      
action $"Starting $prog: " /bin/true              
fi          
else              
action $"Starting $prog: " /bin/false  
fi  

The cause of error / FAILED is this line:

RESPONSE=/usr/bin/mysqladmin -uUNKNOWN_MYSQL_USERping 2>&1 && break

The problem is that the mysqld_safe program line (not shown here) is given an argument to load the variable values from a default file “/etc/my.cnf”, in this script file. However, the RESPONSE line shown here does not account for socket path and keeps looking for a socket at default location /var/lib/mysql/mysql.sock . Whereas in our situation, we have moved the entire /var/lib/mysql to /data , or so to speak . The solution is to pass the “–socket $socketfile” or “-S $socketfile” parameter to the RESPONSE line above. Changing it to look like:

RESPONSE=/usr/bin/mysqladmin -S $socketfile -uUNKNOWN_MYSQL_USERping 2>&1 && break

After saving this file you can easily start and stop mysql . Make sure that you copy the modified script to the other node as well.

Note : Do this only on the primary DB server, not on the slave one!

[root@db1 ~]# service mysqld start  
Starting MySQL:                                            [  OK  ]  
[root@db1 ~]#     
  
  
Once it is tested, stop it again. Also make sure it does not start at boot time. As we want to control it through heartbeat.  
  
[root@db1 var]# service mysqld stop  
Stopping MySQL:                                            [  OK  ]  
[root@db1 var]# chkconfig --level 35 mysqld off  

Add mysqld to /etc/ha.d/haresources file on both NFS servers.

vi /etc/ha.d/haresources  
db1.example.com IPaddr::10.1.1.134/27/eth0 drbddisk::r0 Filesystem::/dev/drbd0::/data::ext3 nfs mysqld  
  
  
vi /etc/ha.d/haresources  
db2.example.com IPaddr::10.1.1.134/27/eth0 drbddisk::r0 Filesystem::/dev/drbd0::/data::ext3 nfs mysqld  

Also updated the DNS zone for db.example.com against the cluster IP 10.1.1.134, on master DNS .

vi /var/named/chroot/var/named/example.com.zone

And restarted DNS service on both nodes.

service named restart

Now it is time to add users/hosts to mysql server:

mysql>  GRANT ALL PRIVILEGES ON *.* TO 'root'@'10.1.1.130'  IDENTIFIED BY 'redhat' with grant option;  
Query OK, 0 rows affected (0.00 sec)  
  
mysql>  GRANT ALL PRIVILEGES ON *.* TO 'root'@'10.1.1.131'  IDENTIFIED BY 'redhat' with grant option;  
Query OK, 0 rows affected (0.00 sec)  
  
mysql>  GRANT ALL PRIVILEGES ON *.* TO 'root'@'10.1.1.132'  IDENTIFIED BY 'redhat' with grant option;  
Query OK, 0 rows affected (0.00 sec)  
  
mysql>  GRANT ALL PRIVILEGES ON *.* TO 'root'@'10.1.1.133'  IDENTIFIED BY 'redhat' with grant option;  
Query OK, 0 rows affected (0.00 sec)  
  
mysql>  GRANT ALL PRIVILEGES ON *.* TO 'root'@'10.1.1.134'  IDENTIFIED BY 'redhat' with grant option;  
Query OK, 0 rows affected (0.00 sec)  
  
mysql>  GRANT ALL PRIVILEGES ON *.* TO 'root'@'10.1.1.135'  IDENTIFIED BY 'redhat' with grant option;  
Query OK, 0 rows affected (0.00 sec)  
  
  
mysql> GRANT ALL PRIVILEGES ON *.* TO 'root'@'db1.example.com'  IDENTIFIED BY 'redhat' with grant option;  
Query OK, 0 rows affected (0.00 sec)  
  
mysql> GRANT ALL PRIVILEGES ON *.* TO 'root'@'db2.example.com'  IDENTIFIED BY 'redhat' with grant option;  
Query OK, 0 rows affected (0.00 sec)  
  
mysql> GRANT ALL PRIVILEGES ON *.* TO 'root'@'db.example.com'  IDENTIFIED BY 'redhat' with grant option;  
Query OK, 0 rows affected (0.00 sec)  
  
mysql> GRANT ALL PRIVILEGES ON *.* TO 'root'@'www.example.com'  IDENTIFIED BY 'redhat' with grant option;  
Query OK, 0 rows affected (0.00 sec)  
  
mysql> GRANT ALL PRIVILEGES ON *.* TO 'root'@'webmail1.example.com'  IDENTIFIED BY 'redhat' with grant option;  
Query OK, 0 rows affected (0.00 sec)  
  
mysql> GRANT ALL PRIVILEGES ON *.* TO 'root'@'webmail2.example.com'  IDENTIFIED BY 'redhat' with grant option;  
Query OK, 0 rows affected (0.00 sec)  
  
  
mysql>  FLUSH PRIVILEGES;  
Query OK, 0 rows affected (0.00 sec)  
  
mysql>  

VSFTPD:

Install VSFTPD on both DB nodes.

yum install vsftpd

We already have setup an os user “webmaster” on both DB nodes. And they have their home directories setup as “/var/www/vhosts”. However, on the DB nodes , it is not “/var/www/vhosts” , rather, it is “/data/www/vhosts” , so update the os user on DB nodes as :

usermod -d /data/www/vhosts webmaster

Add vsftpd to HighAvailability config file haresources on both servers:

[root@db1 ~]# vi /etc/ha.d/haresources  
  
db1.example.com IPaddr::10.1.1.134/27/eth0 drbddisk::r0 Filesystem::/dev/drbd0::/data::ext3 nfs mysqld vsftpd  
    
[root@db2 ~]# vi /etc/ha.d/haresources  
  
db2.example.com IPaddr::10.1.1.134/27/eth0 drbddisk::r0 Filesystem::/dev/drbd0::/data::ext3 nfs mysqld vsftpd  

Apache:

It would be better to instal httpd and httpd-devel packages at this time on both DB servers:

yum install httpd httpd-devel

Setup Apache to be controlled through heartbeat:

[root@db1 ~]# vi /etc/ha.d/haresources  
  
db1.example.com IPaddr::10.1.1.134/27/eth0 drbddisk::r0 Filesystem::/dev/drbd0::/data::ext3 nfs mysqld vsftpd httpd  
  
  
[root@db2 ~]# vi /etc/ha.d/haresources  
  
db2.example.com IPaddr::10.1.1.134/27/eth0 drbddisk::r0 Filesystem::/dev/drbd0::/data::ext3 nfs mysqld vsftpd httpd  

And make sure you have php and related packages installed too on both DB servers:

yum install php php-mysql php-gd php-mbstring  
  
service httpd restart

LOAD BALANCER SETUP:

Load Balancer Setup on already available db1 and db2. I will install Linux LB packages on both db1 and db2 and use another cluster IP / Vritual IP as the target for www and @ for example.com.

yum install heartbeat-ldirectord perl-TimeDate perl-Net-SSLeay perl-IO-Socket-SSL pygtk2 libglade2

modprobe ip_vs_dh
modprobe ip_vs_ftp
modprobe ip_vs
modprobe ip_vs_lblc
modprobe ip_vs_lblcr
modprobe ip_vs_lc
modprobe ip_vs_nq
modprobe ip_vs_rr
modprobe ip_vs_sed
modprobe ip_vs_sh
modprobe ip_vs_wlc
modprobe ip_vs_wrr

Also put it in /etc/rc.local

vi /etc/rc.local
modprobe ip_vs_dh
modprobe ip_vs_ftp
modprobe ip_vs
modprobe ip_vs_lblc
modprobe ip_vs_lblcr
modprobe ip_vs_lc
modprobe ip_vs_nq
modprobe ip_vs_rr
modprobe ip_vs_sed
modprobe ip_vs_sh
modprobe ip_vs_wlc
modprobe ip_vs_wrr

Both LBs:

vi /etc/sysctl.conf

Enables packet forwarding

net.ipv4.ip_forward = 1

sysctl -p

Both LB nodes:

vi /etc/ha.d/ha.cf

logfacility local0
keepalive 2
#deadtime 30 # USE THIS!!!
deadtime 10
bcast eth1
#serial /dev/ttyS0
#baud 19200
auto_failback off
respawn hacluster /usr/lib/heartbeat/ipfail
node host3.example.com host4.example.com

Now on both LBs but with a bit different on each one:

LB Node1:

vi /etc/ha.d/haresources

db1.example.com ldirectord::ldirectord.cf LVSSyncDaemonSwap::master IPaddr2::10.1.1.135/27/eth0 IPaddr::10.1.1.134/27/eth0 drbddisk::r0 Filesystem::/dev/drbd0::/data::ext3 nfs mysqld vsftpd httpd

LB Node2:

vi /etc/ha.d/haresources
db2.example.com ldirectord::ldirectord.cf LVSSyncDaemonSwap::master IPaddr2::10.1.1.135/27/eth0 IPaddr::10.1.1.134/27/eth0 drbddisk::r0 Filesystem::/dev/drbd0::/data::ext3 nfs mysqld vsftpd httpd

both LBs

vi /etc/ha.d/ldirectord.cf

checktimeout=10
checkinterval=2
autoreload=no
logfile=”local0”
quiescent=yes

virtual=10.1.1.135:80
real=10.1.1.132:80 gate
real=10.1.1.133:80 gate
fallback=127.0.0.1:80 gate
service=http
request=”ldirector.html”
receive=”Test Page”
scheduler=rr
protocol=tcp
checktype=negotiate

Both LBs

chkconfig --level 35  ldirectord off  
chkconfig --level 35  heartbeat  on  
  
service ldirectord stop  

WWW1 and WWW2 (disabled these settings )

vi /etc/sysctl.conf
. . .
. . .

Setup for LB

  • When an arp request is received on eth0, only respond if that address is
  • configured on eth0. In particular, do not respond if the address is
  • configured on lo

net.ipv4.conf.eth0.arp_ignore = 1

Ditto for eth1, add for all ARPing interfaces

1net.ipv4.conf.eth1.arp_ignore = 1

Enable configuration of arp_announce option

net.ipv4.conf.all.arp_announce = 2

When making an ARP request sent through eth0 Always use an address that
is configured on eth0 as the source address of the ARP request. If this
is not set, and packets are being sent out eth0 for an address that is on
lo, and an arp request is required, then the address on lo will be used.
As the source IP address of arp requests is entered into the ARP cache on
the destination, it has the effect of announcing this address. This is
not desirable in this case as adresses on lo on the real-servers should
be announced only by the linux-director.

net.ipv4.conf.eth0.arp_announce = 2

Ditto for eth1, add for all ARPing interfaces

net.ipv4.conf.eth1.arp_announce = 2

Then:

sysctl -p # on BOTH WWWs

WWW1 and WWW2

REDHAT / CentOS / Fedora

cd /etc/sysconfig/network-scripts/

cp ifcfg-lo ifcfg-lo:0

vi ifcfg-lo:0

DEVICE=lo:0
IPADDR=10.1.1.135
NETMASK=255.255.255.255
ONBOOT=yes
NAME=loopback:0

Both WWWs

echo "Test Page" > /var/www/vhosts/example.com/ldirector.html