drbd+centos+nginx+php+mysql+memcache 低成本双机WEB高可用和负载均衡群集.

切记:生产环境使用时请用共享外部磁盘代替drbd,不要省略IPMI卡,否则折腾死人.
drbd模拟共享磁盘实现文件同步.redhat群集套件实现高可用,nginx实现web负载均衡.适用稳定性和性能要求比较高的网站项目.
本文使用两台虚拟机演示安装和维护操作,生产环境使用需要保护设备(低成本可以使用ipmi卡,有条件可以使用带snmp的交换机或snmp电源盒).

网络配置:
服务器:node1.cluster, IP:192.168.1.11
服务器:node2.cluster, IP:192.168.1.12
公共IP:192.168.1.200
生产环境使用最好用双网卡,把数据同步和对外服务用内外网卡分开传输.
演示用vm配置 20G硬盘, 其中10G安装操作系统 8G用于drbd模拟共享磁盘, 剩余作为swap

目录:
1. 安装操作系统和磁盘分区
2. 安装ntpd ntpdate服务
3. 安装drbd服务
4. 安装redhat群集套件
5. 配置gfs2文件系统
6. 安装配置mysql, memcache
7. 安装配置php,nginx
8. 管理服务(启动,停止,开关机)
9. 故障处理.

1. 安装操作系统和磁盘分区
操作系统安装过程比较简单,这里只介绍要点。

  1. 安装时注意两台服务器的主机名和Ip并不一样,虽然安装后可以改,但这里设置好更方便点.
    群集节点IP和主机名
  2. 特别注意磁盘分区,要给两台服务器分别分配一个drbd用分区,此分区要求大小完全相同. 原因会在“安装drbd服务”时解释. 分区时用什么分区格式不重要,在配置gfs2时会用新的分区格式覆盖它
    给drbd预留分区

注:在选择软件包时可以选最小化,服务器上用到的软件并不多,用最小化方便自定义.
最小化安装

安装完成重启并登陆终端,在两台服务器上分别执行:

1
2
#yum update -y
#reboot

目的是为了把刚安装好的操作系统软件保持当前最新,因为服务器软件安装配置好后更新系统容易破坏配置引起不必要的异常或兼容性问题.

2. 安装ntpd ntpdate服务
为什么要安装ntpd,ntpdate?
redhat群集套件,gfs2,drbd,php对时间精确性有要求,特别是gfs2要求群集节点时间误差在几分钟内。如果时间误差太大有可能引起重复的文件同步和错误的故障自动切换,当然节点时间误差太大还会引起php站点时间异常(要知道访问请求分布在两台节点处理).

1
2
3
4
5
#yum install ntp ntpdate -y
#chkconfig --level 2345 ntpdate on
#chkconfig --level 2345 ntpd on
#service ntpdate start
#service ntpd start

要注意 ntpdate需要比ntpd先启动, 如果顺序搞反了且时间误差太大时无法和远程时间服务器同步.

3. 安装配置drbd服务
同一个站点分别在两台服务器上分布运行,需要站点文件和数据库在两台服务器上保持同步,专业要求用共享磁盘阵列,这里为了降低成本用drbd软件模拟共享磁盘.模拟后从网络拓扑看就像两台服务器共享了同一个硬盘,数据库和网站文件存放在这个虚拟共享硬盘上. 其中一个节点写入,另一个节点就能实时读取更新.保证群集节点文件实时同步.
在两台节点上做如下操作:

1
2
3
4
5
6
7
8
9
10
#yum install wget -y
#wget http://oss.linbit.com/drbd/8.4/drbd-8.4.4.tar.gz
#tar -xzf drbd-8.4.4.tar.gz
#yum install perl make gcc flex kernel-devel -y
#cd drbd-8.4.4
#./configure --prefix=/usr --localstatedir=/var --sysconfdir=/etc --with-km --with-rgmanager
#make KDIR=/usr/src/kernels/2.6.32-431.5.1.el6.x86_64
#make install
#chkconfig --add drbd
#chkconfig --level 2345 drbd on

编译drbd时注意“KDIR”后的内核代码路径,在centos上是 /usr/src/kernels/版本号. 如果不清楚自己的操作系统是什么内核,最好用”uname -a” 命令确认。 如果系统内核是在2.6.33以后则可以取消configure参数的–with-km(编译内核模块)选项,因为33后的linux内核已经自带drbd模块,只需要编译安装用户工具.

1
#vi /etc/drbd.d/global_common.conf

编辑drbd配置文件如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
global {
        usage-count yes;
}
common {
        handlers {
                 fence-peer              "/usr/lib/drbd/crm-fence-peer.sh";
                 after-resync-target     "/usr/lib/drbd/crm-unfence-peer.sh";
        }
        startup {
                 become-primary-on both;
        }
           disk {
                fencing resource-and-stonith;
                }
        net {
                protocol C;
                allow-two-primaries;
                after-sb-0pri discard-zero-changes;
                after-sb-1pri discard-secondary;
                after-sb-2pri disconnect;
        }
}

这里配置使用 协议C, 必须两个硬盘都写入才返回成功,如有异常则停止服务等待管理员手工处理(这样可以保证万一出问题造成数据不同步时,故障范围不扩大), 使用双主节点配置,即在两个节点上可以同时读写.

定义资源 r0.res

1
#vi  /etc/drbd.d/r0.res
1
2
3
4
5
6
7
8
9
10
11
  resource r0 {
        device     /dev/drbd1;
        disk       /dev/vg_node/lv_drbd;
        meta-disk  internal;
        on node1.cluster {
                address         192.168.1.11:7788;
        }
        on node2.cluster {
                address         192.168.1.12:7788;
        }
  }

“/dev/vg_node/lv_drbd” 是安装系统时在分区界面指定的设备,“/dev/drbd1” 是模拟出来的共享磁盘(分区)设备.

卸载安装系统时的/drbd挂载点.

1
2
#umount /drbd
#vi /etc/fstab

编辑”/etc/fstab” 去掉 “/dev/mapper/vg_node-lv_drbd /drbd ext4 defaults 1 2” 映射,因为drbd的r0.res把/dev/vg_node/lv_drbd映射到/dev/drbd1

设置访问墙,开放tcp 7788端口

1
#vi /etc/sysconfig/iptables

增加下行(生产服务器这里最好用-s限制IP)

1
-A INPUT -m state --state NEW -m tcp -p tcp --dport 7788 -j ACCEPT
1
2
#service iptables restart
#service drbd start

使用新配置加载防火墙,启动drbd服务

在”node1.cluster”上执行初始化.

1
2
3
4
#dd if=/dev/zero of=/dev/vg_node/lv_drbd bs=1M count=1  //这行会擦除此设备分区的旧数据.谨慎操作.
#drbdadm create-md r0 //创建drbd磁盘metadata信息
#drbdadm up r0
#drbdadm primary --force r0

现在等待同步,使用”service drbd status”查看进度,直到状态为 UpToDate/UpToDate 为止, 同步比较慢,多等一会.
同步完成后在”node2.cluster”执行如下代码

1
#drbdadm primary r0

在看看状态(“service drbd status”),两个节点都显示primary.primary uptodate/uptodate状态
不要直接挂载/dev/drbd1使用,虽然这里挂载也能成功,但实际双机使用时,很可能存在两个节点因操作系统磁盘cache引起文件不同步(比如在其中一个节点修改内容,另一个节点却无法读取到改变,查drbd同步状态又正常.), 共享磁盘需要结合GFS2文件系统使用.

安装到这里 drbd 成功把 “lv_drbd“设备连接成同一个磁盘分区设备”/dev/drbd1″就如同两个节点的”lv_drdb”磁盘通过网络阵列为一个”/dev/drdb1″磁盘.

4. 安装redhat群集套件
更改访火墙”/etc/sysconfig/iptables”:

1
2
3
4
-A INPUT -p igmp -j ACCEPT
-A INPUT -s 192.168.1.0/24 -p udp -m state --state NEW -m multiport --dports 5404,5405 -j ACCEPT
-A INPUT -s 192.168.1.0/24 -p udp -m addrtype --dst-type MULTICAST -m state --state NEW -m multiport --dports 5404,5405 -j ACCEPT
-A INPUT -s 192.168.1.0/24 -p tcp -m state --state NEW -m multiport –dports 7788,11111,16851,21064 -j ACCEPT

允许igmp协议通过,允许udp5404,5405(群集心跳端口),tcp1111,16851,21064群集服务端口.
解释: 这里如果分内外网多网卡的话,可以通过网段限制Ip范围提高安全性
igmp这里是允许多播,给群集传播心跳信号用的,
udp 5404 5405就是用来传播心跳信号的端口
tcp 7788 drbd用数据传输端口
tcp 11111,16851,21064 是redhat群集套件用端口

编辑 “/etc/hosts” 增加

1
2
192.168.1.11 node1.cluster
192.168.1.12 node2.cluster

安装群集套件,设置群集配置

1
2
3
#yum install ccs ricci cman rgmanager gfs2-utils –y
#passwd ricci  //设置ricci服务密码
#service ricci start

ricci,ccs分别是群集管理软件的服务端和客户端
可以把各节点的ricci服务设置为自动启动,这样平时管理群集方便很多

在“node1.cluster”执行

1
2
3
4
5
6
7
8
9
10
11
#ccs -h node1.cluster --createcluster mycluster
#ccs -h node1.cluster --addnode node1.cluster
#ccs -h node1.cluster --addnode node2.cluster
#ccs -h node1.cluster --setcman expected_votes="1" two_node="1"
#ccs -h node1.cluster --addfailoverdomain mypri ordered
#ccs -h node1.cluster --addfailoverdomainnode mypri node1.cluster 1
#ccs -h node1.cluster --addfailoverdomainnode mypri node2.cluster 2
#ccs -h node1.cluster --addservice myservice domain=mypri recovery=relocate
#ccs -h node1.cluster --addsubservice myservice ip address="192.168.1.200/24" monitor_link="yes"
#ccs -h node1.cluster --sync –activate
#ccs -h node1.cluster --startall

如果是生产环境需要在以上命令中补充fence设备配置,
如果是多网卡需要给每对网卡增加一个虚拟IP配置.

查看”/etc/cluster/cluster.conf”如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?xml version="1.0"?>
<cluster config_version="33" name="mycluster">
        <fence_daemon/>
        <clusternodes>
                <clusternode name="node1.cluster" nodeid="1"/>
                <clusternode name="node2.cluster" nodeid="2"/>
        </clusternodes>
        <cman expected_votes="1" two_node="1"/>
        <fencedevices/>
        <rm>
                <failoverdomains>
                        <failoverdomain name="mypri" nofailback="0" ordered="1" restricted="0">
                                <failoverdomainnode name="node1.cluster" priority="1"/>
                                <failoverdomainnode name="node2.cluster" priority="2"/>
                        </failoverdomain>
                </failoverdomains>
                <resources/>
                <service domain="mypri" name="myservice" recovery="relocate">
                        <ip address="192.168.1.200/24" monitor_link="yes"/>
                </service>
        </rm>
</cluster>

注意:生产环境服务器还需要设置fence相关配置.

5. 配置gfs2文件系统
虽然安装了drdb服务,但是drbd只是提供了模拟的共享磁盘(磁盘镜像),操作系统磁盘各服务器独立缓存的引起文件读写不同步还是存在。表现为:
在node1.cluster /dev/drbd1写入文件。
node2.cluster /dev/drbd1无法看到更改,但重新启动或挂载后又能看到。
gfs2作为 “全局文件系统” 用于解决这个问题,此文件系统会给整个群集的所有节点共享网络文件锁,最终结果就如同所有节点网络共享磁盘缓存.

给/dev/drbd1 设置gfs2格式
“node1.cluster”执行

1
#mkfs.gfs2 -p lock_dlm -t mycluster:drbd1 -j 2 /dev/drbd1

使用gfs2格式化/dev/drbd1(这个是drbd服务模拟分区)分区, 并且使用”mycluster”群集管理锁 锁名“drbd1”,锁服务类型”lock_dlm”, 2个磁盘日志(2个节点,每个节点需要一个日志)

在两台服务器的”/etc/fstab”上分别增加

1
/dev/drbd1              /drbd                   gfs2    acl,noatime         0 0

注意 noatime参数,这里表示此设备文件挂载不记录文件访问时间(每次访问更新访问时间会降低文件访问速度,网站基本上用不着文件访问时间).

“node1.cluster”执行

1
2
#ccs -h node1.cluster --stopall
#ccs -h node1.cluster --startall

重启群集,现在可以查看 /drbd目录了,两个节点的/drbd目录应是同步的,分别读写试试.

6. 安装配置mysql, memcache
MySQL在这里只配置高可用,并不配置负载均衡。也就是说两个节点中同时只有一个节点在运行mysql,memcache服务。如果出现故障则自动转移到另一个正常节点运行。不能同时在两个节点运行mysql是因为两节点mysql程序是共享同一个数据库文件,如果两个mysql同时运行会造成两节点同时读写同一个mysql数据库文件而引起数据库文件损坏. memcache也是类似理由,节点内存并不同步,所以memcache同时只在一台节点运行. 这里先安装mysql并且配置cluster.conf管理mysql服务启动和停止.

node1.cluster执行

1
2
3
4
5
6
7
#yum install mysql-server -y
#service mysqld start
#/usr/bin/mysql_secure_installation
#service mysqld stop
#chkconfig --del mysqld
# mv /var/lib/mysql /drbd/MySQL
# ln -s /drbd/mysql /var/lib/mysql

移动mysql数据目录到/drbd, 然后再建立软链接回来,同时删除mysqld的chkconfig服务(确保mysqld由cluster控制启动和停止)
node2.cluster执行

1
2
3
4
5
6
7
8
#yum install mysql-server -y
#rm -fr /var/lib/MySQL
#ln -s /drbd/mysql /var/lib/mysql
#chkconfig --del mysqld
#ccs -h node1.cluster --addsubservice myservice script file="/etc/init.d/mysqld" name="mysqld"
#ccs -h node1.cluster --sync –activate
#ccs -h node1.cluster --stopall
#ccs -h node1.cluster --startall

删除mysql数据目录,使用drbd共享的mysql数据目录,这样两台服务器的mysqld服务读写同一个数据目录,保证了两个服务器的数据库完全同步.
现在连接数据库测试(注意要用虚拟IP:192.168.1.200连接)

Leave a Reply

Your email address will not be published.

Time limit is exhausted. Please reload the CAPTCHA.

Proudly powered by WordPress   Premium Style Theme by www.gopiplus.com