CentOS7 nginx keepalived主备实例配置

nginx1 ip:192.168.12.4 #MASTER
nginx2 ip:192.168.12.10 #BACKUP
nginx_vip :192.168.12.100

原理可参考:
http://www.keepalived.org/documentation.html
系统为CentOS7

1、配置一下yum源

curl -L http://mirrors.aliyun.com/repo/Centos-7.repo > /etc/yum.repos.d/CentOS-Base.repo
curl -L http://mirrors.aliyun.com/repo/epel-7.repo > /etc/yum.repos.d/epel.repo

yum -y install keepalived nginx

2、设置服务器基本环境

关闭防火墙:iptables -F;service iptables save
关闭seLinux:setenforce 0;sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/sysconfig/selinux

3、配置一下nginx,好区分测试环境

192.168.12.4:
echo 192.168.12.4 > /usr/share/nginx/html/index.html

192.168.12.10:
echo 192.168.12.10 > /usr/share/nginx/html/index.html

4、配置keepalived.conf

[[email protected]]# cat keepalived.conf 
! Configuration File for keepalived
global_defs {
notification_email {
[email protected]
}
notification_email_from [email protected]
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id LVS_DEVEL
}

vrrp_script check_nginx {
script "sh /etc/keepalived/check_nginx.sh" 
interval 2 
}

vrrp_instance VI_1 {
state MASTER
interface eth0
mcast_src_ip 192.168.12.4
virtual_router_id 51
priority 100
advert_int 2
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.12.100
}
track_script {
check_nginx
}
}

[[email protected]]# cat keepalived.conf 
! Configuration File for keepalived
global_defs {
notification_email {
[email protected]
}
notification_email_from [email protected]
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id LVS_DEVEL
}

vrrp_script check_nginx {
script "sh /etc/keepalived/check_nginx.sh" 
interval 2 
}

vrrp_instance VI_1 {
state BACKUP
interface eth0
mcast_src_ip 192.168.12.10
virtual_router_id 51
priority 99
advert_int 2
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.12.100
}
track_script {
check_nginx
}
}

脚本check_nginx.sh内容如下

#!/bin/bash

A=`pgrep nginx|wc -l` 
if [ $A -eq 0 ];then 
/bin/systemctl start nginx.service
if [ `pgrep nginx|wc -l` -eq 0 ];then
/bin/systemctl stop keepalived.service
fi
fi

5、启动

在两个服务器执行启动命令

service nginx start
service keepalived start

6、检查

[[email protected] keepalived]# ip addr
1: lo:  mtu 65536 qdisc noqueue state UNKNOWN qlen 1
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host 
valid_lft forever preferred_lft forever
2: eth0:  mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:0c:29:85:83:e8 brd ff:ff:ff:ff:ff:ff
inet 192.168.12.4/24 brd 192.168.12.255 scope global eth0
valid_lft forever preferred_lft forever
inet 192.168.12.100/32 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:fe85:83e8/64 scope link 
valid_lft forever preferred_lft forever
[[email protected] keepalived]# ip addr
1: lo:  mtu 65536 qdisc noqueue state UNKNOWN qlen 1
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host 
valid_lft forever preferred_lft forever
2: eth0:  mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:0c:29:62:6a:50 brd ff:ff:ff:ff:ff:ff
inet 192.168.12.10/24 brd 192.168.12.255 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:fe62:6a50/64 scope link 
valid_lft forever preferred_lft forever

仔细观察可以发现192.168.12.4的服务器多了一个IP,就是192.168.12.100,这个就是VIP
再看日志发现主服务器日志有这下面一条:

Jul 12 10:30:57 localhost Keepalived_vrrp[2510]: VRRP_Instance(VI_1) Entering MASTER STATE

备服务器日志

Jul 11 00:01:00 localhost Keepalived_vrrp[111937]: VRRP_Instance(VI_1) Entering BACKUP STATE

综上主备已搭建成功

7、模拟主nginx宕机

LVS负载均衡架构原理

高可用/集群

Linux Virtual Server
Ipvs : 嵌入到Linux的内核
IPVsadm:管理应用程序

负载均衡器

1、硬件:

 F5BIG-IP
 CitrixNetScaler
 A10

2、软件

 四层:tcp 之上的第四层协议
           LVS:只能操作IP,端口 ,在操作系统内核中。
 七层:http,ajp,https,(应用层)
           nginx
           haproxy
           httpd

调度方法(静态方法和动态方法)

四种静态:

     rr:轮循
     wrr:
     dh:
     sh:

动态调度方法:

     lc:最少连接
               active*256+inactive
               谁的小,挑谁
     wlc:加权最少连接
               (active*256+inactive)/weight
     sed:最短期望延迟
               (active+1)*256/weight
     nq:never queue
     LBLC:基于本地的最少连接
               DH:
     LBLCR:基于本地的带复制功能的最少连接
     默认方法:wlc

类型:

     NAT:地址转换
     DR:直接路由
     TUN:隧道

  NAT:
               集群节点跟director必须在同一个IP网络中;
               RIP通常是私有地址,仅用于各集群节点间的通信;
               director位于client和real server之间,并负责处理进出的所有通信;
               realserver必须将网关指向DIP;
               支持端口映射;
               realserver可以使用任意OS;
               较大规模应该场景中,director易成为系统瓶颈;
               VIP:虚拟服务器地址
               DIP:   转发的网络地址
                RIP:  后端真实主机(后端服务器)
               CIP:客户端IP地址
 DR:  
              集群节点跟director必须在同一个物理网络中;
              后端服务器(真实服务器)可以使用公网地址,实现便捷的远程管理和监控;
              director仅负责处理入站请求,响应报文则由realserver直接发往客户端;
              不支持端口映射;

高可用/集群

VIP(隐藏)的意思:

不对外广播

被叫不响应

Node1
VIP:192.168.1.251
DIP:192.168.239.3
集群服务器

Node2
RIP:192.168.1.248
VIP:192.168.239.10
RS,apache

Node3
RIP:192.168.1.249
VIP:192.168.239.10
RS,apache

TUN:

               集群节点可以跨越Internet;
               RIP必须是公网地址;
               director仅负责处理入站请求,响应报文则由realserver直接发往客户端;
               realserver网关不能指向director;
               只有支持隧道功能的OS才能用于realserver;
               不支持端口映射;

Ipvsadm命令:

  管理集群服务
               添加:-A -t|u|fservice-address [-s scheduler]
                        -t:TCP协议的集群
                        -u:UDP协议的集群
                                 service-address:     IP:PORT
                        -f:FWM: 防火墙标记
                                 service-address:Mark Number
               修改:-E
               删除:-D -t|u|fservice-address

               #ipvsadm -A -t 172.16.100.1:80 -s rr

  管理集群服务中的RS
               添加:-a -t|u|fservice-address -r server-address [-g|i|m] [-w weight]
                          -t|u|f service-address:事先定义好的某集群服务
                          -r server-address: 某RS的地址,在NAT模型中,可使用IP:PORT实现端口映射;
                          [-g|i|m]: LVS类型      
                                 -g:DR
                                 -i:TUN
                                 -m:NAT
                        [-wweight]: 定义服务器权重
               修改:-e
               删除:-d -t|u|fservice-address -r server-address

               #ipvsadm -a -t 172.16.100.1:80 -r 192.168.10.8 –g
               #ipvsadm -a -t 172.16.100.1:80 -r 192.168.10.9 -g
     查看
               -L|l
                        -n:数字格式显示主机地址和端口
                        --stats:统计数据
                        --rate:速率
                        --timeout:显示tcp、tcpfin和udp的会话超时时长
                        -c:显示当前的ipvs连接状况

     删除所有集群服务
               -C:清空ipvs规则
     保存规则
               -S
               #ipvsadm -S > /path/to/somefile
     载入此前的规则:
               -R
               # ipvsadm -R </path/form/somefile

DR模式

VIP: 虚拟主机IP
DIP:
kernelparameter:
arp_ignore:定义接收到ARP请求时的响应级别;
0:只要本地配置的有相应地址,就给予响应;
1:仅在请求的目标(MAC)地址配置请求到达的接口上的时候,才给予响应;

               arp_announce:定义将自己地址向外通告时的通告级别;
                        0:将本地任何接口上的任何地址向外通告;
                        1:试图仅向目标网络通告与其网络匹配的地址;
                        2:仅向与本地接口上(MAC)地址匹配的网络进行通告;

—————————————————————–DR模式示例————————————————————

Lvs DR模式集群步骤

1、 找一台主机作为DR(虚拟服务器),安装ipvsadm

   a) Yum install ipvsadm

2、 在DR设置两个IP地址:

       a) DIP: 192.168.1.134 ,设置静态ID
       b) VIP:192.168.1.200 , ifconfig eth0:1 192.168.1.200/24 (取消绑定ifconfig eth1 down)

3、 找多台机器作为RS(apeche或者tomcat )

   a) 两台:静态设置192.168.1.137
                               192.168.1.138
   b) 修改报文源IP的设置,需要设置内核参数
                    i.  echo 1 >/proc/sys/net/ipv4/conf/eth0/arp_ignore
                    ii. echo 1 >/proc/sys/net/ipv4/conf/all/arp_ignore
                    iii.echo 2 >/proc/sys/net/ipv4/conf/eth0/arp_announce
                    iv.echo 2 >/proc/sys/net/ipv4/conf/all/arp_announce
       c)  在两台机器(RS)上,设置网卡的别名IP:192.168.1.200
                     i. ifconfig lo:0 192.168.1.200 netmask 255.255.255.255 broadcast 192.168.1.200
       d)  在两台机器(RS)上,添加一个路由
                      i. route add -host 192.168.1.200 dev lo:0

4、 DR上需要加一个路由设置:route add -host 192.168.1.200 dev eth0:1

5、 在RS 检查web服务是否正常

6、 在DR上使用ipvsadm添加集群服务

       a)  Ipvsadm –C
       b)  ipvsadm -A -t 192.168.1.200:80-s wlc
       c)  ipvsadm -a -t 192.168.1.200:80-r 192.168.1.137 -g -w 1
       d)  ipvsadm -a -t 192.168.1.200:80-r 192.168.1.138 -g -w 1

脚本

#!/bin/bash
#description : start realserver
VIP=125.38.38.64
/etc/rc.d/init.d/functions
case "$1" in
start)
echo " start LVS of REALServer"
echo "1">/proc/sys/net/ipv4/conf/lo/arp_ignore
echo "2">/proc/sys/net/ipv4/conf/lo/arp_announce
echo "1">/proc/sys/net/ipv4/conf/all/arp_ignore
echo "2" >/proc/sys/net/ipv4/conf/all/arp_announce
/sbin/ifconfig lo:0 $VIP broadcast $VIPnetmask 255.255.255.255 up

;;
stop)
/sbin/ifconfig lo:0 down
echo "close LVS Directorserver"
echo "0">/proc/sys/net/ipv4/conf/lo/arp_ignore
echo "0">/proc/sys/net/ipv4/conf/lo/arp_announce
echo "0">/proc/sys/net/ipv4/conf/all/arp_ignore
echo "0">/proc/sys/net/ipv4/conf/all/arp_announce
;;
*)
echo "Usage: $0 {start|stop}"
exit 1
esac

双机高可用、负载均衡、MySQL(读写分离、主从自动切换)架构设计

架构简介

 

前几天网友来信说帮忙实现这样一个架构:只有两台机器,需要实现其中一台死机之后另一台能接管这台机器的服务,并且在两台机器正常服务时,两台机器都能用上。于是设计了如下的架构。
高可用/集群
此架构主要是由keepalived实现双机高可用,维护了一个外网VIP,一个内网VIP。正常情况时,外网VIP和内网VIP都绑定在server1服务器,web请求发送到server1的nginx,nginx对于静态资源请求就直接在本机检索并返回,对于php的动态请求,则负载均衡到server1和server2。对于SQL请求,会将此类请求发送到Atlas MySQL中间件,Atlas接收到请求之后,把涉及写操作的请求发送到内网VIP,读请求操作发送到mysql从,这样就实现了读写分离。

 

当主服务器server1宕机时,keepalived检测到后,立即把外网VIP和内网VIP绑定到server2,并把server2的mysql切换成主库。此时由于外网VIP已经转移到了server2,web请求将发送给server2的nginx。nginx检测到server1宕机,不再把请求转发到server1的php-fpm。之后的sql请求照常发送给本地的atlas,atlas把写操作发送给内网VIP,读操作发送给mysql从,由于内网VIP已经绑定到server2了,server2的mysql同时接受写操作和读操作。

 

当主服务器server1恢复后,server1的mysql自动设置为从,与server2的mysql主同步。keepalived不抢占server2的VIP,继续正常服务。

 

架构要求

 

要实现此架构,需要三个条件:

  • 1、服务器可以设置内网IP,并且设置的内网IP互通;
  • 2、服务器可以随意绑定IDC分配给我们使用的外网IP,即外网IP没有绑定MAC地址;
  • 3、MySQL服务器支持GTID,即MySQL-5.6.5以上版本。

 

环境说明

 

server1

  • eth0: 10.96.153.110(对外IP)
  • eth1: 192.168.1.100(对内IP)

server2

  • eth0: 10.96.153.114(对外IP)
  • eth1: 192.168.1.101(对内IP)

系统都是CentOS-6。

 

对外VIP: 10.96.153.239
对内VIP: 192.168.1.150

 

hosts设置

 

/etc/hosts:
192.168.1.100 server1
192.168.1.101 server2

 

Nginx PHP MySQL Memcached安装

 

这几个软件的安装推荐使用EZHTTP来完成。

 

解决session共享问题

 

php默认的session存储是在/tmp目录下,现在我们是用两台服务器作php请求的负载,这样会造成session分布在两台服务器的/tmp目录下,导致依赖于session的功能不正常。我们可以使用memcached来解决此问题。
上一步我们已经安装好了memcached,现在只需要配置php.ini来使用memcached,配置如下,打开php.ini配置文件,修改为如下两行的值:

  1. session.save_handler = memcache
  2. session.save_path = "tcp://192.168.1.100:11211,tcp://192.168.1.101:11211"

之后重启php-fpm生效。

 

Nginx配置

 

Server1配置

  1. http {
  2. […]
  3.     upstream php-server {
  4.            server 192.168.1.101:9000;
  5.            server 127.0.0.1:9000;
  6.            keepalive 100;
  7.     }
  8. […]
  9.  server {
  10.     […]
  11.         location ~ .php$ {
  12.                         fastcgi_pass   php-server;
  13.                         fastcgi_index  index.php;
  14.                         fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
  15.                         include        fastcgi_params;
  16.         }
  17.     […]
  18.  }
  19. […]
  20. }

 

Server2配置

  1. http {
  2. […]
  3.     upstream php-server {
  4.            server 192.168.1.100:9000;
  5.            server 127.0.0.1:9000;
  6.            keepalive 100;
  7.     }
  8. […]
  9.  server {
  10.     […]
  11.         location ~ .php$ {
  12.                         fastcgi_pass   php-server;
  13.                         fastcgi_index  index.php;
  14.                         fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
  15.                         include        fastcgi_params;
  16.         }
  17.     […]
  18.  }
  19. […]
  20. }

这两个配置主要的作用是设置php请求的负载均衡。

 

MySQL配置

 

mysql util安装

我们需要安装mysql util里的主从配置工具来实现主从切换。

  1. cd /tmp
  2. wget http://dev.mysql.com/get/Downloads/MySQLGUITools/mysql-utilities-1.5.3.tar.gz
  3. tar xzf mysql-utilities-1.5.3.tar.gz
  4. cd mysql-utilities-1.5.3
  5. python setup.py build
  6. python setup.py install

 

mysql my.cnf配置

server1:

  1. [mysql]
  2. […]
  3. protocol=tcp
  4. […]
  5. […]
  6. [mysqld]
  7. […]
  8. # BINARY LOGGING #
  9. log-bin = /usr/local/mysql/data/mysql-bin
  10. expire-logs-days = 14
  11. binlog-format= row
  12. log-slave-updates=true
  13. gtid-mode=on
  14. enforce-gtid-consistency =true
  15. master-info-repository=TABLE
  16. relay-log-info-repository=TABLE
  17. server-id=1
  18. report-host=server1
  19. report-port=3306
  20. […]

server2:

  1. [mysql]
  2. […]
  3. protocol=tcp
  4. […]
  5. [mysqld]
  6. […]
  7. # BINARY LOGGING #
  8. log-bin = /usr/local/mysql/data/mysql-bin
  9. expire-logs-days = 14
  10. binlog-format= row
  11. log-slave-updates=true
  12. gtid-mode=on
  13. enforce-gtid-consistency =true
  14. master-info-repository=TABLE
  15. relay-log-info-repository=TABLE
  16. server-id=2
  17. report-host=server2
  18. report-port=3306
  19. […]

这两个配置主要是设置了binlog和启用gtid-mode,并且需要设置不同的server-id和report-host。

 

开放root帐号远程权限

我们需要在两台mysql服务器设置root帐号远程访问权限。

  1. mysql> grant all on *.* to ‘root’@’192.168.1.%’ identified by ‘Xp29at5F37’ with grant option;
  2. mysql> grant all on *.* to ‘root’@’server1’ identified by ‘Xp29at5F37’ with grant option;
  3. mysql> grant all on *.* to ‘root’@’server2’ identified by ‘Xp29at5F37’ with grant option;
  4. mysql> flush privileges;

 

设置mysql主从

在任意一台执行如下命令:

  1. mysqlreplicate –master=root:Xp29at5F37@server1:3306 –slave=root:Xp29at5F37@server2:3306 –rpl-user=rpl:o67DhtaW

# master on server1: … connected.
# slave on server2: … connected.
# Checking for binary logging on master…
# Setting up replication…
# …done.

 

显示主从关系

  1. mysqlrplshow –master=root:Xp29at5F37@server1 –discover-slaves-login=root:Xp29at5F37

# master on server1: … connected.
# Finding slaves for master: server1:3306

# Replication Topology Graph
server1:3306 (MASTER)
|
+— server2:3306 – (SLAVE)

 

检查主从状态

  1. mysqlrplcheck –master=root:Xp29at5F37@server1 –slave=root:Xp29at5F37@server2

# master on server1: … connected.
# slave on server2: … connected.
Test Description Status
—————————————————————————
Checking for binary logging on master [pass]
Are there binlog exceptions? [pass]
Replication user exists? [pass]
Checking server_id values [pass]
Checking server_uuid values [pass]
Is slave connected to master? [pass]
Check master information file [pass]
Checking InnoDB compatibility [pass]
Checking storage engines compatibility [pass]
Checking lower_case_table_names settings [pass]
Checking slave delay (seconds behind master) [pass]
# …done.

 

Keepalived配置

 

keepalived安装(两台都装)

  1. yum -y install keepalived
  2. chkconfig keepalived on

 

keepalived配置(server1)

  1. vi /etc/keepalived/keepalived.conf
  1. vrrp_sync_group VG_1 {
  2. group {
  3. inside_network
  4. outside_network
  5. }
  6. }
  7.  
  8. vrrp_instance inside_network {
  9. state BACKUP
  10. interface eth1
  11. virtual_router_id 51
  12. priority 101
  13. advert_int 1
  14. authentication {
  15. auth_type PASS
  16. auth_pass 3489
  17. }
  18. virtual_ipaddress {
  19. 192.168.1.150/24
  20. }
  21. nopreempt
  22. notify /data/sh/mysqlfailover-server1.sh
  23. }
  24.  
  25. vrrp_instance outside_network {
  26. state BACKUP
  27. interface eth0
  28. virtual_router_id 50
  29. priority 101
  30. advert_int 1
  31. authentication {
  32. auth_type PASS
  33. auth_pass 3489
  34. }
  35. virtual_ipaddress {
  36. 10.96.153.239/24
  37. }
  38. nopreempt
  39. }

 

keepalived配置(server2)

  1. vrrp_sync_group VG_1 {
  2. group {
  3. inside_network
  4. outside_network
  5. }
  6. }
  7.  
  8. vrrp_instance inside_network {
  9. state BACKUP
  10. interface eth1
  11. virtual_router_id 51
  12. priority 100
  13. advert_int 1
  14. authentication {
  15. auth_type PASS
  16. auth_pass 3489
  17. }
  18. virtual_ipaddress {
  19. 192.168.1.150
  20. }
  21. notify /data/sh/mysqlfailover-server2.sh
  22. }
  23.  
  24. vrrp_instance outside_network {
  25. state BACKUP
  26. interface eth0
  27. virtual_router_id 50
  28. priority 100
  29. advert_int 1
  30. authentication {
  31. auth_type PASS
  32. auth_pass 3489
  33. }
  34. virtual_ipaddress {
  35. 10.96.153.239/24
  36. }
  37. }

此keepalived配置需要注意的是:

  • 1、两台server的state都设置为backup,server1增加nopreempt配置,并且server1 priority比server2高,这样用来实现当server1从宕机恢复时,不抢占VIP;
  • 2、server1设置notify /data/sh/mysqlfailover-server1.sh,server2设置notify /data/sh/mysqlfailover-server2.sh,作用是自动切换主从

/data/sh/mysqlfailover-server1.sh脚本内容:

  1. #!/bin/bash
  2.  
  3. sleep 10
  4. state=$3
  5. result=`mysql -h127.0.0.1 -P3306 -uroot -pXp29at5F37 -e ‘show slave status;’`
  6. [[ "$result" == "" ]] && mysqlState="master" || mysqlState="slave"
  7.  
  8. if [[ "$state" == "MASTER" ]];then
  9.   if [[ "$mysqlState" == "slave" ]];then
  10.     mysqlrpladmin –slave=root:Xp29at5F37@server1:3306 failover
  11.   fi
  12.  
  13. elif [[ "$state" == "BACKUP" ]];then
  14.   if [[ "$mysqlState" == "master" ]];then
  15.     mysqlreplicate –master=root:Xp29at5F37@server2:3306 –slave=root:Xp29at5F37@server1:3306 –rpl-user=rpl:o67DhtaW
  16.   fi
  17. fi
  18.  
  19. sed -i ‘s/proxy-read-only-backend-addresses.*/proxy-read-only-backend-addresses = 192.168.1.150:3306/’ /usr/local/mysql-proxy/conf/my.cnf
  20. mysql -h127.0.0.1 -P2345 -uuser -ppwd -e "REMOVE BACKEND 2;"

/data/sh/mysqlfailover-server2.sh脚本内容:

  1. #!/bin/bash
  2.  
  3. sleep 10
  4. state=$3
  5. result=`mysql -h127.0.0.1 -P3306 -uroot -pXp29at5F37 -e ‘show slave status;’`
  6. [[ "$result" == "" ]] && mysqlState="master" || mysqlState="slave"
  7.  
  8. if [[ "$state" == "MASTER" ]];then
  9.   if [[ "$mysqlState" == "slave" ]];then
  10.     mysqlrpladmin –slave=root:Xp29at5F37@server2:3306 failover
  11.   fi
  12.  
  13. elif [[ "$state" == "BACKUP" ]];then
  14.   if [[ "$mysqlState" == "master" ]];then
  15.     mysqlreplicate –master=root:Xp29at5F37@server1:3306 –slave=root:Xp29at5F37@server2:3306 –rpl-user=rpl:o67DhtaW
  16.   fi
  17. fi
  18.  
  19. sed -i ‘s/proxy-read-only-backend-addresses.*/proxy-read-only-backend-addresses = 192.168.1.150:3306/’ /usr/local/mysql-proxy/conf/my.cnf
  20. mysql -h127.0.0.1 -P2345 -uuser -ppwd -e "REMOVE BACKEND 2;"

 

Atlas设置

 

atlas安装

到这里下载最新版本,https://github.com/Qihoo360/Atlas/releases

  1. cd /tmp
  2. wget https://github.com/Qihoo360/Atlas/releases/download/2.2.1/Atlas-2.2.1.el6.x86_64.rpm
  3. rpm -i Atlas-2.2.1.el6.x86_64.rpm

 

atlas配置

  1. cd /usr/local/mysql-proxy/conf
  2. cp test.cnf my.cnf
  3. vi my.cnf

调整如下参数,

  1. proxy-backend-addresses = 192.168.1.150:3306
  2. proxy-read-only-backend-addresses = 192.168.1.101:3306
  3. pwds = root:qtyU1btXOo074Itvx0UR9Q==
  4. event-threads = 8

注意:
proxy-backend-addresse设置为内网VIP
proxy-read-only-backend-addresses设置为server2的IP
root:qtyU1btXOo074Itvx0UR9Q==设置数据库的用户和密码,密码是通过/usr/local/mysql-proxy/bin/encrypt Xp29at5F37生成。
更详细参数解释请查看,Atlas配置详解

 

启动atlas

  1. /usr/local/mysql-proxy/bin/mysql-proxy –defaults-file=/usr/local/mysql-proxy/conf/my.cnf

之后程序里配置mysql就配置127.0.0.1:1234就好。

 

部署atlas自动维护脚本

在两台机器都部署此脚本,并添加定时任务(如每2分钟运行一次)我们把脚本放在/data/sh/auto_maintain_atlas.sh,脚本内容为:

  1. #!/bin/bash
  2.  
  3. count=`mysql -N -h127.0.0.1 -P2345 -uuser -ppwd -e "select * from backends;" | wc -l`
  4.  
  5. if [[ "$count" == "1" ]];then
  6.   result=`mysql -hserver1 -P3306 -uroot -pXp29at5F37 -e ‘show slave statusG’`
  7.   if echo "$result" | grep Slave_IO_State;then
  8.     slaveIP=192.168.1.100
  9.   else
  10.     result=`mysql -hserver2 -P3306 -uroot -pXp29at5F37 -e ‘show slave statusG’`
  11.     slaveIP=192.168.1.101
  12.   fi
  13.  
  14.         slaveIORunning=`echo "$result" | awk -F’:’ ‘/Slave_IO_Running:/{print $2}’`
  15.         slaveSQLRunning=`echo "$result" | awk -F’:’ ‘/Slave_SQL_Running:/{print $2}’`
  16.         SlaveSQLRunning_State=`echo "$result" | awk -F’:’ ‘/Slave_SQL_Running_State:/{print $2}’`
  17.     
  18.   if [[ "$slaveIORunning" =~ "Yes" && "$slaveSQLRunning" =~ "Yes" && "$SlaveSQLRunning_State" =~ "Slave has read all relay log" ]];then
  19.     mysql -h127.0.0.1 -P2345 -uuser -ppwd -e "add slave ${slaveIP}:3306;"
  20.   fi
  21. fi

为什么需要这个脚本呢?假设目前mysql主服务器在s1,s1宕机后,s2接管VIP,接着删除atlas中设置的slave backend,其mysql提升为主。过一段时间后,s1从宕机中恢复,这时候s1的mysql自动切换为从,接着删除atlas中设置的slave backend,开始连接s2的mysql主同步数据。到这个时候我们发现,已经不存在读写分离了,所有的sql都发送给了s2的mysql。auto_maintain_atlas.sh脚本就派上用场了,此脚本会定时的检查主从是否已经同步完成,如果完成就自动增加slave backend,这样读写分离又恢复了,完全不需要人工干预。

 

server1主宕机测试

 

测试keepalived是否工作正常

我们来模拟server1宕机。
在server1上执行shutdown关机命令。
此时我们登录server2,执行ip addr命令,输出如下:
1: lo: mtu 16436 qdisc noqueue state UNKNOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:0c:29:81:9d:42 brd ff:ff:ff:ff:ff:ff
inet 10.96.153.114/24 brd 10.96.153.255 scope global eth0
inet 10.96.153.239/24 scope global secondary eth0
inet6 fe80::20c:29ff:fe81:9d42/64 scope link
valid_lft forever preferred_lft forever
3: eth1: mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:0c:29:81:9d:4c brd ff:ff:ff:ff:ff:ff
inet 192.168.1.101/24 brd 192.168.1.255 scope global eth1
inet 192.168.1.150/32 scope global eth1
inet6 fe80::20c:29ff:fe81:9d4c/64 scope link
valid_lft forever preferred_lft forever

我们看到对外VIP 10.96.153.239和对内IP 192.168.1.150已经转移到server2了,证明keepalived运行正常。

 

测试是否自动切换了主从

登录server2的mysql服务器,执行show slave status;命令,如下:
mysql> show slave statusG
Empty set (0.00 sec)

我们发现从状态已经为空,证明已经切换为主了。

 

测试server1是否抢占VIP

为什么要测试这个呢?如果server1恢复之后抢占了VIP,而我们的Atlas里后端设置的是VIP,这样server1启动之后,sql的写操作就会向server1的mysql发送,而server1的mysql数据是旧于server2的,所以这样会造成数据不一致,这个是非常重要的测试。
我们先来启动server1,之后执行ip addr,输出如下:
1: lo: mtu 16436 qdisc noqueue state UNKNOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:0c:29:f1:4f:4e brd ff:ff:ff:ff:ff:ff
inet 10.96.153.110/24 brd 10.96.153.255 scope global eth0
inet6 fe80::20c:29ff:fef1:4f4e/64 scope link
valid_lft forever preferred_lft forever
3: eth1: mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:0c:29:f1:4f:58 brd ff:ff:ff:ff:ff:ff
inet 192.168.1.100/24 brd 192.168.1.255 scope global eth1
inet6 fe80::20c:29ff:fef1:4f58/64 scope link
valid_lft forever preferred_lft forever

我们看到,server1并没有抢占VIP,测试正常。不过另人郁闷的是,在虚拟机的环境并没有测试成功,不知道为什么。

 

测试server2的atlas是否已经删除slave backend

我们测试这个是为了保证atlas已经没有slave backend,也就是没有从库的设置了,否则当server1恢复时,有可能会把读请求发送给server1的mysql,造成读取了旧数据的问题。

[root@server1 ~]# mysql -h127.0.0.1 -P2345 -uuser -ppwd
mysql> select * from backends;
+————-+——————–+——-+——+
| backend_ndx | address | state | type |
+————-+——————–+——-+——+
| 1 | 192.168.1.150:3306 | up | rw |
+————-+——————–+——-+——+
1 rows in set (0.00 sec)
如果看到只有一个后端,证明运作正常。

 

测试server1 mysql是否设置为从

serve1恢复后,登录server1的mysql服务器,执行show slave status;命令,如下:

mysql> show slave statusG
*************************** 1. row ***************************
Slave_IO_State: Opening tables
Master_Host: server1
Master_User: rpl
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000015
Read_Master_Log_Pos: 48405991
Relay_Log_File: mysql-relay-bin.000002
Relay_Log_Pos: 361
Relay_Master_Log_File: mysql-bin.000015
Slave_IO_Running: Yes
Slave_SQL_Running: yes

 

测试是否自动恢复读写分离

server1恢复后一段时间,我们可以看是读写分离是否已经恢复。

[root@server1 ~]# mysql -h127.0.0.1 -P2345 -uuser -ppwd
Warning: Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or g.
Your MySQL connection id is 1
Server version: 5.0.99-agent-admin

Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type ‘help;’ or ‘h’ for help. Type ‘c’ to clear the current input statement.

mysql> select * from backends;
+————-+——————–+——-+——+
| backend_ndx | address | state | type |
+————-+——————–+——-+——+
| 1 | 192.168.1.150:3306 | up | rw |
| 2 | 192.168.1.100:3306 | up | ro |
+————-+——————–+——-+——+
2 rows in set (0.00 sec)

我们看到server1已经被添加为slave backend了。这表示已经成功恢复读写分离。

MySQL集群安装与配置

MySQL Cluster 是 MySQL 适合于分布式计算环境的高实用、高冗余版本。它采用了NDB Cluster 存储引擎,允许在1个 Cluster 中运行多个MySQL服务器。MySQL Cluster 能够使用多种故障切换和负载平衡选项配置NDB存储引擎,但在 Cluster 级别上的存储引擎上做这个最简单。下面我们简单介绍MySQL Cluster如何安装与配置。
基本设定
管理(MGM)节点:192.168.0.111
MySQL服务器(SQL)节点:192.168.0.110
数据(NDBD)节点”A”:192.168.0.112
数据(NDBD)节点”B”:192.168.0.113

一、mysql集群安装

mysql的集群安装可以有三种方式,一是直接下载二进制使用,二是使用rpm安装,三是源码编译。我们这里使用第一种安装。
1、每个节点做相同的操作

  1. cd /tmp
  2. wget http://cdn.mysql.com/Downloads/MySQL-Cluster-7.2/mysql-cluster-gpl-7.2.8-linux2.6-i686.tar.gz
  3. tar xzf mysql-cluster-gpl-7.2.8-linux2.6-i686.tar.gz
  4. mv mysql-cluster-gpl-7.2.8-linux2.6-i686 /usr/local/mysql

注意:这里下载的是32位的二进制包,如果你的系统是64位,需要下载64位的包。
2、存储节点和SQL节点安装

  1. groupadd mysql
  2. useradd -g mysql mysql
  3. /usr/local/mysql/scripts/mysql_install_db –basedir=/usr/local/mysql –datadir=/usr/local/mysql/data –user=mysql
  4. chown -R root /usr/local/mysql
  5. chown -R mysql /usr/local/mysql/data
  6. chgrp -R mysql /usr/local/mysql
  7. cp /usr/local/mysql/support-files/my-medium.cnf /etc/my.cnf

二、节点配置

1、配置存储节点和SQL节点

  1. vi /etc/my.cnf
  2. 类似于:
  3. # Options for mysqld process:
  4. [MYSQLD]                       
  5. ndbcluster                      # run NDB engine
  6. ndb-connectstring=198.168.0.111  # location of MGM node
  7.  
  8. # Options for ndbd process:
  9. [MYSQL_CLUSTER]                 
  10. ndb-connectstring=198.168.0.111  # location of MGM node

2、配置管理节点

  1. mkdir /var/lib/mysql-cluster
  2. cd /var/lib/mysql-cluster
  3. vi config.ini
  4.  
  5. config.ini文件应类似于:
  6.  
  7. # Options affecting ndbd processes on all data nodes:
  8. [NDBD DEFAULT]   
  9. NoOfReplicas=2    # Number of replicas
  10. DataMemory=80M    # How much memory to allocate for data storage
  11. IndexMemory=18M   # How much memory to allocate for index storage
  12.                   # For DataMemory and IndexMemory, we have used the
  13.                   # default values. Since the "world" database takes up
  14.                   # only about 500KB, this should be more than enough for
  15.                   # this example Cluster setup.
  16.  
  17. # TCP/IP options:
  18. [TCP DEFAULT]     
  19. portnumber=2202   # This the default; however, you can use any
  20.                   # port that is free for all the hosts in cluster
  21.                   # Note: It is recommended beginning with MySQL 5.0 that
  22.                   # you do not specify the portnumber at all and simply allow
  23.                   # the default value to be used instead
  24.  
  25. # Management process options:
  26. [NDB_MGMD]                     
  27. hostname=198.168.0.111           # Hostname or IP address of MGM node
  28. datadir=/var/lib/mysql-cluster  # Directory for MGM node logfiles
  29.  
  30. # Options for data node "A":
  31. [NDBD]                         
  32.                                 # (one [NDBD] section per data node)
  33. hostname=198.168.0.112         # Hostname or IP address
  34. datadir=/usr/local/mysql/data   # Directory for this data node’s datafiles
  35.  
  36. # Options for data node "B":
  37. [NDBD]                         
  38. hostname=198.168.0.113       # Hostname or IP address
  39. datadir=/usr/local/mysql/data   # Directory for this data node’s datafiles
  40.  
  41. # SQL node options:
  42. [MYSQLD]                       
  43. hostname=198.168.0.110           # Hostname or IP address
  44.                                 # (additional mysqld connections can be
  45.                                 # specified for this node for various
  46.                                 # purposes such as running ndb_restore)

三、首次启动节点

1、启动管理节点

  1. /usr/local/mysql/bin/ndb_mgmd –configdir=/var/lib/mysql-cluster -f /var/lib/mysql-cluster/config.ini

2、启动数据节点
首次启动需要–initial参数初始化,下一次启动就不需要了。

  1. /usr/local/mysql/bin/ndbd –initial

3、启动SQL节点

  1. /usr/local/mysql/bin/mysqld_safe  &

4、检查状态
如果一切正常,执行命令 /usr/local/mysql/bin/ndb_mgm -e show应该会输出类似信息:

[root@localhost mysql-cluster]# /usr/local/mysql/bin/ndb_mgm -e show
Connected to Management Server at: localhost:1186
Cluster Configuration
———————
[ndbd(NDB)] 2 node(s)
id=2 @192.168.0.112 (mysql-5.5.27 ndb-7.2.8, Nodegroup: 0, Master)
id=3 @192.168.0.113 (mysql-5.5.27 ndb-7.2.8, Nodegroup: 0)

[ndb_mgmd(MGM)] 1 node(s)
id=1 @192.168.0.111 (mysql-5.5.27 ndb-7.2.8)

[mysqld(API)] 1 node(s)
id=4 @192.168.0.110 (mysql-5.5.27 ndb-7.2.8)

四、测试服务是否正常

在SQL节点上执行如下数据库操作:

  1. /usr/local/mysql/bin/mysql -uroot -p
  2. mysql> create database clusterdb;use clusterdb;
  3. mysql> create table simples (id int not null primary key) engine=ndb;
  4. mysql> insert into simples values (1),(2),(3),(4);
  5. mysql> select * from simples;

如果出现:
+—-+
| id |
+—-+
| 1 |
| 2 |
| 4 |
| 3 |
+—-+
则表示工作正常。

五、安全关闭和重启

1、关闭mysql集群,可在管理节点在执行如下命令:

  1. /usr/local/mysql/bin/ndb_mgm -e shutdown

2、重启管理节点

  1. /usr/local/mysql/bin/ndb_mgmd –configdir=/var/lib/mysql-cluster -f /var/lib/mysql-cluster/config.ini

3、重启数据节点

  1. /usr/local/mysql/bin/ndbd

参考:http://dev.mysql.com/doc/refman/5.1/zh/ndbcluster.html

双机热备+负载均衡线上方案(Heartbeat+DRBD+NFS+Keepalived+Lnmp)

我们下面来实现一个架构,heartbeat+drbd+nfs实现mysql和网站数据的同步,keepalived实现nginx的高可用,而用nginx和dns轮询实现负载均衡。

架构说明

目录规划

/usr/local/src/lnmp:用来存放源码工具等等
/data:用来存放所有数据和NFS以及DRBD的挂载
/data/shell:用来存放所有管理脚本
/data/mysql:用来挂载DRBD的mysql资源,以供mysql存放数据库
/data/wwwnfs:用来挂载DRBD生成的www资源,以供两个节点挂载到各个节点的/data/www目录,以供论坛等程序数据使用
/data/www:用来挂载NFS资源,用来存放论坛(网站)等程序数据

拓扑工作原理

内网:
1,DRBD网络存储创建出两个资源,一个mysql给mysql数据库同步用,一个www给web(论坛)数据NFS共享挂载用,虚拟出两个虚拟IP,一个是 192.168.1.100,用来连接数据库,一个是192.168.1.200,用来给节点挂载NFS
注意:NFS底下挂载了三次:DRBD挂载一次,文件系统挂载一次,客户端挂载一次
2,Heartbeat来实现DRBD的HA,同时虚拟出两个内网IP,并管理NFS,MySQL的启动和关闭

外网:
1,两个节点都用Nginx做均衡器,通过内网调度负载两个节点,实现内部均衡
2,DNS配置双IP对应一个域名的方式来实现DNS轮询,实现外网均衡
3,Keepalived使用双主(master)配置虚拟出两个虚拟IP:节点一 12.12.12.100和节点二 12.12.12.200,同时共外网访问,两个节点互为主从关系,当某个节点挂掉的时候,另外一个节点将同时是两个资源的master,同时拥有两个虚拟IP,实现资源转移。

我们知道DNS的缺点就是生效慢,分配资源不合理,理论上有可能把所有的请求都发送给同一节点,导致均衡不合理导致所有资源不可用,这里我们由于有了NGINX内部负载,就不怕DNS轮询不均衡了,因为NGINX内部有严谨的调度方式,不管那台请求有多少,在内部都能实现理想的调度,这样就能把DNS负载均衡和NGINX完美结合,是硬件资源得到合理的利用,然后利用keepalive保证了每个节点的可靠性,几乎完美!
拓扑图如下:
高可用/集群

架构实现

LNMP架构配置

配置LNMp架构需要注意两点:
注意一:这里MYSQL都不要初始化,不要启动!后面有专门的配置的
注意二:nginx所有端口都改成 8080,因为一会还要安装nginx来做均衡器并对外提供服务,所以不要用默认的80
注意三、nginx和php-fpm运行的用户都是www。

安装配置NFS

1、安装NFS

  1. yum install nfs-utils nfs4-acl-tools portmap

2、配置/etc/exports

  1. /data/wwwnfs 192.168.1.0/24(rw,,no_root_squash,sync,anonuid=502,anongid=502)

注意:
/data/wwwnfs:就是给两个节点挂载的目录,所有网站程序都放在这里,实现论坛程序等数据的共享(同步)
anonuid=502,anongid=502:这个表示客户端上任何用户进入到挂载目录都以uid=502和gid=502身份,我这里这个代表的是www用户
3、启动

  1. service portmap start
  2. service nfs start

切忌,必须先启动portmap

  1. chkconfig  nfs off
  2. chkconfig  portmap on

注意:portmap服务器必须常驻,且不收heartbeat管理;而nfs这必须要用heartbeat来管理他的启动和关闭,所以这里要关闭nfs开机自动启动

同时要启动锁机制,因为同时有两个节点要使用同一份数据,所以需要有总裁,这个尤其是在NFS给mysql用的时候是必须要用的,对于论坛或网站,要看情况,如果存在对同一文件同时修改的时候必须要启动NFS锁机制,如果没有这种情况,那么建议不要启动,启动了会降低NFS的性能:

  1. /sbin/rpc.lockd
  2. echo "/sbin/rpc.lockd" >>/etc/rc.local

4、开机自动挂载

  1. echo "sleep 20" >>/etc/rc.local
  2. echo "/bin/mount -t nfs 192.168.1.200:/data/wwwnfs /data/www" >>/etc/rc.local

为什么为延迟20秒再挂载nfs?因为如果不等待立即挂载,会发现挂载不上,这是由于heartbeat启动用的vip还没设置好的原因。
立即挂载:

  1. mount -a

安装配置DRBD

安装方法见:http://devops.webres.wang/2012/02/drbd-compile-install-deploy/

配置文件

DRBD有三种配置文件:
/usr/local/drbd/etc/drbd.conf
/usr/local/drbd/etc/drbd.d/global_common.conf
/usr/local/drbd/etc/drbd.d/*.res
1、drbd.conf

  1. include "drbd.d/global_common.conf";
  2. include "drbd.d/*.res";

2、global_common.conf

  1. global {
  2.   usage-count yes;
  3. }
  4. common {
  5.   net {
  6.     protocol C;
  7.   }
  8. }

3、mysql.res和www.res
mysql.res:

  1. vi /usr/local/drbd/etc/drbd.d/mysql.res
  1. #资源组的名称
  2. resource mysql{
  3.  
  4. #定义主服务器资源
  5.         on node1{
  6. #建立块设备文件
  7.         device /dev/drbd1;
  8. #要用于复制的分区
  9.         disk /dev/sdb1;
  10. #定义侦听IP和端口
  11.         address 192.168.1.10:7788;
  12. #meta data信息存放的方式,这里为内部存储,即和真实数据放在一起存储
  13.         meta-disk internal;
  14.                    }
  15.  
  16. #定义备服务器资源
  17.         on node2{
  18.         device /dev/drbd1;
  19.         disk /dev/sdb1;
  20.         address 192.168.1.20:7788;
  21.         meta-disk internal;
  22.                    }
  23.  
  24.                 }

www.res:

  1. vi /usr/local/drbd/etc/drbd.d/www.res
  1. #资源组的名称
  2. resource www{
  3.  
  4. #定义主服务器资源
  5.         on node2{
  6. #建立块设备文件
  7.         device /dev/drbd2;
  8. #要用于复制的分区
  9.         disk /dev/sdb2;
  10. #定义侦听IP和端口
  11.         address 192.168.1.20:7789;
  12. #meta data信息存放的方式,这里为内部存储,即和真实数据放在一起存储
  13.         meta-disk internal;
  14.                    }
  15.  
  16. #定义备服务器资源
  17.         on node1{
  18.         device /dev/drbd2;
  19.         disk /dev/sdb2;
  20.         address 192.168.1.10:7789;
  21.         meta-disk internal;
  22.                    }
  23.  
  24.                 }

最后复制这些文件到node2。

初始化DRBD资源

1)在各个节点启用资源mysql和www

  1. modprobe drbd
  2. dd if=/dev/zero of=/dev/sdb1 bs=1M count=10
  3. dd if=/dev/zero of=/dev/sdb2 bs=1M count=10
  4. drbdadm create-md mysql
  5. drbdadm create-md www
  6. drbdadm up mysql
  7. drbdadm up www

2),提升各个节点上的主
在node1上:

  1. drbdadm primary –force mysql

在node2上:

  1. drbdadm primary –force www

3)格式化drbd块设备
在node1上

  1. mkfs.ext3 /dev/drbd1

在node2上

  1. mkfs.ext3 /dev/drbd2

4)挂载分区
在node1上

  1. mount /dev/drbd1 /data/mysql

在node2上

  1. mount /dev/drbd2 /data/wwwnfs

安装配置heartbeat

1、安装heartbeat

  1. yum install heartbeat

安装完后会自动建立用户hacluster和组haclient
确保两个节点上hacluster用户的的UID和GID相同
2、同步两台节点的时间

  1. rm -rf /etc/localtime
  2. cp -f /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
  3. yum install -y ntp
  4. ntpdate -d cn.pool.ntp.org

3、配置/etc/ha.d/ha.cf

  1. debugfile /var/log/ha-debug                             #打开错误日志报告
  2. keepalive 2                                             #两秒检测一次心跳线连接
  3. deadtime 10                                             #10 秒测试不到主服务器心跳线为有问题出现
  4. warntime 6                                              #警告时间(最好在 2 ~ 10 之间)
  5. initdead 120                                            #初始化启动时 120 秒无连接视为正常,或指定heartbeat
  6.                                                         #在启动时,需要等待120秒才去启动任何资源。
  7.  
  8. udpport 694                                             #用 udp 的 694 端口连接
  9. ucast eth0 192.168.1.20                                #单播方式连接(主从都写对方的 ip 进行连接)
  10. node   node1                                           #声明主服(注意是主机名uname -n不是域名)
  11. node   node2                                           #声明备服(注意是主机名uname -n不是域名)
  12. auto_failback on                                        #自动切换(主服恢复后可自动切换回来)这个不要开启
  13. respawn hacluster /usr/lib/heartbeat/ipfail           #监控ipfail进程是否挂掉,如果挂掉就重启它

4、/etc/ha.d/authkeys

  1. auth 1
  2. 1 crc

5、/etc/ha.d/haresources

  1. node1 IPaddr::192.168.1.100/24/eth0 drbddisk::mysql Filesystem::/dev/drbd1::/data/mysql::ext3 mysqld portmap
  2. node2 IPaddr::192.168.1.200/24/eth0 drbddisk::www Filesystem::/dev/drbd2::/data/wwwnfs::ext3 portmap nfs

6、创建nfs管理脚本

  1. vi /etc/ha.d/resource.d/nfs

写入:

  1. #!/bin/bash
  2.  
  3. NFSD=/etc/rc.d/init.d/nfs
  4. NFSDPID=`/sbin/pidof nfsd`
  5. case $1 in
  6. start)
  7. $NFSD start;
  8. ;;
  9. stop)
  10. $NFSD stop;
  11.         if [ "$NFSDPID" != " " ];then
  12.                 for NFSPID in $NFSDPID
  13.                 do /bin/kill -9 $NFSPID;
  14.                 done
  15.         fi
  16. ;;
  17. *)
  18. echo "Syntax incorrect. You need one of {start|stop }"
  19. ;;
  20. esac

先启动node1的heartbeat,再启动node2的heartbeat
启动成功后,这里有几项需要检查
node1:
1、执行ip a,检查是否已经设置有虚拟ip 192.168.1.100
2、执行cat /proc/drbd检查状态是否正常
3、执行df -h查看/dev/drbd1是否已经挂载到/data/mysql
4、执行service mysqld status查看mysql是否已经启动
node2:
1、执行ip a查看是否已经设置虚拟ip 192.168.1.200
2、执行cat /proc/drbd检查状态是否正常
3、执行df -h查看/dev/drbd2是否已经挂载到/data/wwwnfs和192.168.1.200:/data/wwwnfs是否已经挂载到/data/www

nginx均衡器配置

  1. user  www;
  2. worker_processes  1;
  3.  
  4. error_log  /var/log/nginx/error.log warn;
  5. pid        /var/run/nginx.pid;
  6.  
  7.  
  8. events {
  9.     worker_connections  1024;
  10. }
  11.  
  12.  
  13. http {
  14.     include       /etc/nginx/mime.types;
  15.     default_type  application/octet-stream;
  16.  
  17.     log_format  main  ‘$remote_addr – $remote_user [$time_local] "$request" ‘
  18.                       ‘$status $body_bytes_sent "$http_referer" ‘
  19.                       ‘"$http_user_agent" "$http_x_forwarded_for"’;
  20.  
  21.     access_log  /var/log/nginx/access.log  main;
  22.  
  23.     sendfile        on;
  24.     #tcp_nopush     on;
  25.  
  26.     keepalive_timeout  65;
  27.  
  28.     #gzip  on;
  29.  upstream devops.webres.wang_server
  30.   {
  31.   server 192.168.1.10:8080 weight=3 max_fails=2 fail_timeout=30s;
  32.   server 192.168.1.20:8080 weight=9 max_fails=2 fail_timeout=30s;
  33.   }
  34.   server
  35.   {
  36.     listen       80;
  37.     server_name  devops.webres.wang;
  38.     location / {
  39.     root /data/www/devops.webres.wang;
  40.     index index.php index.htm index.html;
  41.     proxy_redirect off;
  42.     proxy_set_header Host $host;
  43.     proxy_set_header X-Real-IP $remote_addr;
  44.     proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  45.     proxy_pass http://devops.webres.wang_server;
  46.     }
  47.     access_log  off;
  48.   }
  49. server
  50.   {
  51.     listen       8080;
  52.     server_name  devops.webres.wang;
  53.     index index.html index.htm index.php;
  54.     root  /data/www/devops.webres.wang;
  55.     #limit_conn   crawler  20;
  56.  location ~ .php$ {
  57.         root           /data/www/devops.webres.wang;
  58.         fastcgi_pass   127.0.0.1:9000;
  59.         fastcgi_index  index.php;
  60.         fastcgi_param  SCRIPT_FILENAME  /data/www/devops.webres.wang/$fastcgi_script_name;
  61.         include        fastcgi_params;
  62.     }
  63.     location ~ .*.(gif|jpg|jpeg|png|bmp|swf)$
  64.     {
  65.       expires      30d;
  66.     }
  67.     location ~ .*.(js|css)?$
  68.     {
  69.       expires      1h;
  70.     }
  71.     access_log  off;
  72.       }
  73. }

这里定义了两台用于负载均衡的机子,分别是192.168.1.10:8080和192.168.1.20:8080,通过proxy_pass http://devops.webres.wang_server代理循询转发到这两台机,达到负载均衡的作用。
你可以建立index.php,里面写入:

  1. <?php
  2. echo $_SERVER[‘SERVER_ADDR’];
  3. ?>

如果连续刷新几次,得到不同的IP,证明已经均衡负载到不同的服务器。

Keepalived实现nginx和php的HA

1、keepalived安装
安装方法见:http://devops.webres.wang/2012/02/nginx-keepalived-high-availability/
2、配置
节点一node1配置如下:

  1. global_defs {
  2.    notification_email {
  3.      [email protected]
  4.    }
  5.    notification_email_from [email protected]
  6.    smtp_server 127.0.0.1
  7.    smtp_connect_timeout 30
  8.    router_id LVS_DEVEL
  9. }
  10. vrrp_instance VI_1 {
  11.     state MASTER        ############ 辅机为 BACKUP
  12.     interface eth0
  13.     virtual_router_id 100
  14.     mcast_src_ip 192.168.1.10  ########### 本机IP
  15.     priority 102                  ########### 权值要比 back 高
  16.     advert_int 1
  17.     authentication {
  18.         auth_type PASS
  19.         auth_pass 1111
  20.     }
  21.     virtual_ipaddress {
  22.        12.12.12.100
  23.     }
  24. }
  25.  
  26. vrrp_instance VI_1 {
  27.     state BACKUP
  28.     interface eth0
  29.     virtual_router_id 200
  30.     mcast_src_ip 192.168.1.101 ########### 本机IP
  31.     priority 101              ##########权值 要比 master 低。。
  32.     advert_int 1
  33.     authentication {
  34.         auth_type PASS
  35.         auth_pass 1111
  36.     }
  37.     virtual_ipaddress {
  38.        12.12.12.200
  39.     }
  40. }

节点二配置:

  1. global_defs {
  2.    notification_email {
  3.      [email protected]
  4.    }
  5.    notification_email_from [email protected]
  6.    smtp_server 127.0.0.1
  7.    smtp_connect_timeout 30
  8.    router_id LVS_DEVEL
  9. }
  10. vrrp_instance VI_1 {
  11.     state BACKUP
  12.     interface eth0
  13.     virtual_router_id 100
  14.     mcast_src_ip 192.168.1.20 ########### 本机IP
  15.     priority 101              ##########权值 要比 master 低。。
  16.     advert_int 1
  17.     authentication {
  18.         auth_type PASS
  19.         auth_pass 1111
  20.     }
  21.     virtual_ipaddress {
  22.        12.12.12.100
  23.     }
  24. }
  25.  
  26. vrrp_instance VI_1 {
  27.     state MASTER        ############ 辅机为 BACKUP
  28.     interface eth0
  29.     virtual_router_id 200
  30.     mcast_src_ip 192.168.1.103  ########### 本机IP
  31.     priority 102                  ########### 权值要比 back 高
  32.     advert_int 1
  33.     authentication {
  34.         auth_type PASS
  35.         auth_pass 1111
  36.     }
  37.     virtual_ipaddress {
  38.        12.12.12.200
  39.     }
  40. }

3、创建监控脚本
node1监控脚本:

  1. vi /opt/check.sh
  1. #!/bin/bash
  2. while  :
  3. do
  4. mysqlcheck=`/usr/bin/mysqladmin -uroot ping 2>&1`
  5. mysqlcode=`echo $?`
  6. heartbeat=`ps -C heartbeat –no-header | wc -l`
  7. if [ $mysqlcode -ne 0 ] ;then
  8.  if [ $heartbeat-ne 0 ];then
  9. service heartbeat stop
  10. fi
  11. fi
  12. phpcheck=`ps -C php-fpm –no-header | wc -l`
  13. nginxcheck=`ps -C nginx –no-header | wc -l`
  14. keepalivedcheck=`ps -C keepalived –no-header | wc -l`
  15. if [ $nginxcheck -eq 0 ]|| [ $phpcheck -eq 0 ];then
  16.                 if [ $keepalivedcheck -ne 0 ];then
  17.                    killall -TERM keepalived
  18.                 else
  19.                    echo "keepalived is stoped"
  20.                 fi
  21.         else
  22.                 if [ $keepalivedcheck -eq 0 ];then
  23.                    /etc/init.d/keepalived start
  24.                 else
  25.                    echo "keepalived is running"
  26.                 fi
  27. fi
  28. sleep 5
  29. done

node2监控脚本:

  1. #!/bin/bash
  2. while  :
  3. do
  4. phpcheck=`ps -C php-cgi –no-header | wc -l`
  5. nginxcheck=`ps -C nginx –no-header | wc -l`
  6. keepalivedcheck=`ps -C keepalived –no-header | wc -l`
  7. if [ $nginxcheck -eq 0 ]|| [ $phpcheck -eq 0 ];then
  8.                 if [ $keepalivedcheck -ne 0 ];then
  9.                    killall -TERM keepalived
  10.                 else
  11.                    echo "keepalived is stoped"
  12.                 fi
  13.         else
  14.                 if [ $keepalivedcheck -eq 0 ];then
  15.                    /etc/init.d/keepalived start
  16.                 else
  17.                    echo "keepalived is running"
  18.                 fi
  19. fi
  20. sleep 5
  21. done

这个监控代码实现了mysql,nginx,php-fpm的HA。
加上权限,并执行

  1. chmod +x /opt/check.sh
  2. nohup sh /opt/check.sh &

设置开机启动:
echo “nohup sh /opt/check.sh &” >> /etc/rc.local

4、测试keepalived
分别启动keepalived

  1. service keepalived start

1)执行ip a检查node1和node2是否已经存在vip:12.12.12.100和12.12.12.200
2)测试nginx和php-fpm的HA。在node1执行service nginx stop或者service php-fpm stop停止nginx或php-fpm,过几秒钟后你会发现node2已经接管了vip 12.12.12.100,并且使用vip 12.12.12.100或12.12.12.200浏览nginx网页你会发现网页显示的IP一直是192.168.1.20,表明keepalived已经成功接管node1的vip和nginx或php-fpm服务。
3)测试mysql HA。在node1执行service mysqld stop停止mysql服务,几秒后在node2查看,发现node2已经接管vip 192.168.1.100,并且已经启动mysql服务。
注意:在恢复mysql或nginx,php-fpm时,先停止监控脚本,要不heartbeat或keepalived还没实现接管又被停止。
参考:http://bbs.ywlm.net/thread-965-1-1.html

lvs负载均衡及高可用(heartbeat+ldirectord)集群配置

lvs是一个开源免费的负载均衡软件,能实现多台服务器之间的负载均衡,搭配heartbeat和ldirectord的使用,就能配置成高可用的集群。

服务器环境说明

下面说明本次测试配置的服务器环境。
系统:CentOS-5 32 内核2.6.18-238.el5
因为机器只有两台,所以lvs负载器和后端服务器在同一机器。
node1 192.168.79.130
node2 192.168.79.131
VIP 192.168.79.135
当node1出现故障时,lvs负载器和web服务器转移到node2。
如果机器充足,还是建议lvs负载器和web服务器分开。

软件安装

  1. yum -y install heartbeat heartbeat-ldirectord ipvsadm

配置

主要的配置文件有以下几个:
Authkeys
ha.cf
ldirectord.cf
haresources

authkeys

  1. vi /etc/ha.d/authkeys

代码:

  1. auth 1
  2. 1 crc

ha.cf

  1. vi /etc/ha.d/ha.cf
  1. debugfile /var/log/ha-debug
  2. logfile /var/log/ha-log
  3. logfacility local0
  4. keepalive 8
  5. deadtime 60
  6. warntime 60
  7. initdead 120
  8. udpport 694
  9. ucast eth0 192.168.79.131
  10. auto_failback on
  11. node node1
  12. node node2
  13. respawn hacluster /usr/lib/heartbeat/ipfail
  14. apiauth ipfail gid=haclient uid=hacluster

node2唯一不同是ucast eth0 192.168.79.131,把IP改成node1的IP。

haresources

  1. vi /etc/ha.d/haresources

填入:

  1. node1 lvs IPaddr::192.168.79.135/24/eth0:0 ldirectord

这段代码的意思是双机启动heartbeat时,启动node1的lvs脚本,接着配置vip 192.168.79.135/24/eth0:0,然后启动ldirectord来设置node1成lvs负载器并监控80端口。如果node1出故障,node1的heartbeat将从右到左停止服务,如先停止ldirectord,取消vip等。接着node2将接管node1的所有服务,如vip,web服务等。

ldirectord.cf

  1. vi /etc/ha.d/ldirectord.cf
  1. checktimeout=10
  2. checkinterval=8
  3. autoreload=yes
  4. logfile="/var/log/ldirectord.log"
  5. logfile="local0"
  6. quiescent=no
  7.  
  8. virtual=192.168.79.135:80
  9. real=192.168.79.130:80 gate
  10. real=192.168.79.131:80 gate
  11. service=http
  12. request="test.html"
  13. receive="Test Page"
  14. scheduler=wrr
  15. persistent=30
  16. protocol=tcp
  17. checktype=negotiate
  18. checkport=80

node2配置这文件时,需要把real=192.168.79.130:80 gate删除,因为当lvs负载器转移到node2时,不能把故障机node1添加到虚拟机。

test.html

在网站根目录建立test.html,并写入Test Page字段,这个用来监控web服务器的健康情况。假设根目录为/var/www/html:

  1. echo "Test Page" > /var/www/html/test.html

lvs启动脚本

  1. vi /etc/init.d/lvs

node1上的lvs启动脚本:

  1. #!/bin/bash
  2. /sbin/ipvsadm –set 10 10 10

node1上的lvs启动脚本:

  1. #!/bin/bash
  2. VIP=192.168.79.135
  3. /etc/rc.d/init.d/functions
  4. /sbin/ipvsadm –set 10 10 10
  5. case "$1" in
  6. start)
  7. /sbin/ifconfig lo:0 down
  8. /sbin/ifconfig eth0:0 $VIP broadcast $VIP netmask 255.255.255.255 up
  9. /sbin/route add -host $VIP dev eth0:0
  10. ;;
  11. stop)
  12. /sbin/ifconfig eth0:0 down
  13. /sbin/ifconfig lo:0 $VIP broadcast $VIP netmask 255.255.255.255 up
  14. /sbin/route add -host $VIP dev lo:0
  15. ;;
  16. *)
  17. echo "Usage: $0 {start|stop}"
  18. exit 1
  19. esac

最后加上执行权限:

  1. chmod +x /etc/init.d/lvs

主机名及hosts配置

1、对两台机分别设置对应的主机名
192.168.79.130 为 node1
192.168.79.131 为 node2
2、添加主机名解析

  1. vi /etc/hosts
  1. 192.168.79.130 node1
  2. 192.168.79.131 node2

解决arp问题

  1. vi /etc/sysctl.conf
  1. net.ipv4.ip_forward = 1
  2. net.ipv4.conf.lo.arp_ignore = 1
  3. net.ipv4.conf.lo.arp_announce = 2
  4. net.ipv4.conf.all.arp_ignore = 1
  5. net.ipv4.conf.all.arp_announce = 2

立即使内核参数生效:

  1. sysctl -p

lvs测试

测试负载均衡:可以在两台机放入不同的首页内容,在不同的客户端测试是否显示不一样的内容
测试高可用:关掉node1 heartbeat,在node2执行ip a查看是否已经接管vip。
测试ldirectord:ldirectord可以实时监控指定的服务是否可用,如果发现不可用,就会使用ipvsadm把这台故障的机从虚拟机中删除。

使用heartbeat实现DRBD主从自动切换

这里简单介绍一下heartbeat和drbd。
如果主服务器宕机,造成的损失是不可估量的。要保证主服务器不间断服务,就需要对服务器实现冗余。在众多的实现服务器冗余的解决方案中,heartbeat为我们提供了廉价的、可伸缩的高可用集群方案。我们通过heartbeat+drbd在Linux下创建一个高可用(HA)的集群服务器。

DRBD是一种块设备,可以被用于高可用(HA)之中。它类似于一个网络RAID-1功能。当你将数据写入本地文件系统时,数据还将会被发送到网络中另一台主机上。以相同的形式记录在一个文件系统中。本地(主节点)与远程主机(备节点)的数据可以保证实时同步。当本地系统出现故障时,远程主机上还会保留有一份相同的数据,可以继续使用。在高可用(HA)中使用DRBD功能,可以代替使用一个共享盘阵。因为数据同时存在于本地主机和远程主机上。切换时,远程主机只要使用它上面的那份备份数据,就可以继续进行服务了。

下面我们部署这一高可用。首先安装heartbeat,执行yum install heartbeat即可,不建议编译安装heartbeat,因为安装时间特长,容易出问题;接着安装drbd,安装方法见:http://devops.webres.wang/2012/02/drbd-compile-install-deploy/,唯一不同的是在./configure命令中添加–with-heartbeat,安装完成后会在/usr/local/drbd/etc/ha.d/resource.d生成drbddisk和drbdupper文件,把这两个文件复制到/usr/local/heartbeat/etc/ha.d/resource.d目录,命令cp -R /usr/local/drbd/etc/ha.d/resource.d/* /etc/ha.d/resource.d。
我们的主机ip是192.168.79.130,备机ip:192.168.79.131,虚拟ip:192.168.79.135,drbd同步的分区/dev/sdb1,挂载的目录/data。

drbd配置

1、首先对/dev/sdb分区出/dev/sdb1,建立目录/data。
2、配置global和resource。
配置drbd.conf:

  1. vi /usr/local/drbd/etc/drbd.conf

写入:

  1. include "drbd.d/global_common.conf";
  2. include "drbd.d/*.res";

配置global_common.conf

  1. vi /usr/local/drbd/etc/drbd.d/global_common.conf

写入:

  1. global {
  2.   usage-count yes;
  3. }
  4. common {
  5.   net {
  6.     protocol C;
  7.   }
  8. }

配置r0资源:

  1. vi /usr/local/drbd/etc/drbd.d/r0.res

写入:

  1. resource r0 {
  2.   on node1 {
  3.     device    /dev/drbd1;
  4.     disk      /dev/sdb1;
  5.     address   192.168.79.130:7789;
  6.     meta-disk internal;
  7.   }
  8.   on node2 {
  9.     device    /dev/drbd1;
  10.     disk      /dev/sdb1;
  11.     address   192.168.79.131:7789;
  12.     meta-disk internal;
  13.   }
  14. }

3、设置hostname。

  1. vi /etc/sysconfig/network

修改HOSTNAME为node1
编辑hosts

  1. vi /etc/hosts

添加:

  1. 192.168.79.130 node1
  2. 192.168.79.131 node2

使node1 hostnmae临时生效

  1. hostname node1

node2设置类似。
4、设置resource
以下操作需要在node1和node2操作。

  1. modprobe drbd //载入 drbd 模块
  2. dd if=/dev/zero of=/dev/sdb1 bs=1M count=100 /把一些资料塞到 sdb 內 (否则 create-md 时有可能会出现错误)
  3. drbdadm create-md r0                             //建立 drbd resource
  4. drbdadm up r0                                  //启动 resource r0

5、设置Primary Node
以下操作仅在node1执行。
设置node1为primary node:

  1. drbdadm primary –force r0

6、创建DRBD文件系统
以下操作仅在node1执行。
上面已经完成了/dev/drbd1的初始化,现在来把/dev/drbd1格式化成ext3格式的文件系统。

  1. mkfs.ext3 /dev/drbd1

然后将/dev/drbd1挂载到之前创建的/data目录。

  1. mount /dev/drbd1 /data

heartbeat配置

总共有三个文件需要配置:
ha.cf 监控配置文件
haresources 资源管理文件
authkeys 心跳线连接加密文件
1、同步两台节点的时间

  1. rm -rf /etc/localtime
  2. cp -f /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
  3. yum install -y ntp
  4. ntpdate -d cn.pool.ntp.org

2、配置ha.cf

  1. vi /etc/ha.d/ha.cf
  1. debugfile /var/log/ha-debug                             #打开错误日志报告
  2. keepalive 2                                             #两秒检测一次心跳线连接
  3. deadtime 10                                             #10 秒测试不到主服务器心跳线为有问题出现
  4. warntime 6                                              #警告时间(最好在 2 ~ 10 之间)
  5. initdead 120                                            #初始化启动时 120 秒无连接视为正常,或指定heartbeat
  6.                                                         #在启动时,需要等待120秒才去启动任何资源。
  7.  
  8. udpport 694                                             #用 udp 的 694 端口连接
  9. ucast eth0 192.168.79.131                                #单播方式连接(主从都写对方的 ip 进行连接)
  10. node   node1                                           #声明主服(注意是主机名uname -n不是域名)
  11. node   node2                                           #声明备服(注意是主机名uname -n不是域名)
  12. auto_failback on                                        #自动切换(主服恢复后可自动切换回来)这个不要开启
  13. respawn hacluster /usr/lib/heartbeat/ipfail           #监控ipfail进程是否挂掉,如果挂掉就重启它

3、配置authkeys

  1. vi /etc/ha.d/authkeys

写入:

  1. auth 1
  2. 1 crc

4、配置haresources

  1. vi /etc/ha.d/haresources

写入:

  1. node1 IPaddr::192.168.79.135/24/eth0 drbddisk::r0 Filesystem::/dev/drbd1::/data::ext3

node1:master主机名
IPaddr::192.168.79.135/24/eth0:设置虚拟IP
drbddisk::r0:管理资源r0
Filesystem::/dev/drbd1::/data::ext3:执行mount与unmout操作
node2配置基本相同,不同的是ha.cf中的192.168.79.131改为192.168.79.130。

DRBD主从自动切换测试

首先先在node1启动heartbeat,接着在node2启动,这时,node1等node2完全启动后,相继执行设置虚拟IP,启动drbd并设置primary,并挂载/dev/drbd1到/data目录,启动命令为:

  1. service heartbeat start

这时,我们执行ip a命令,发现多了一个IP 192.168.79.135,这个就是虚拟IP,cat /proc/drbd查看drbd状态,显示primary/secondary状态,df -h显示/dev/drbd1已经挂载到/data目录。
然后我们来测试故障自动切换,停止node1的heartbeat服务或者断开网络连接,几秒后到node2查看状态。
接着恢复node1的heartbeat服务或者网络连接,查看其状态。

heartbeat配置文件ha.cf haresources authkeys详解

在启用Heartbeat之前,安装后要配置三个文件(如没有可手动建立):ha.cf、haresources、authkeys。这三个配置文件需要在/etc/ha.d目录下面,但是默认是没有这三个文件的,可以到官网上下这三个文件,也可以在源码包里找这三个文件,在源码目录下的DOC子目录里。

1 配置ha.cf

第一个是ha.cf该文件位于在安装后创建的/etc/ha.d目录中。该文件中包括为Heartbeat使用何种介质通路和如何配置他们的信息。在源代码目录中的ha.cf文件包含了您可以使用的全部选项,详述如下:
serial /dev/ttyS0
使用串口heartbeat-如果不使用串口heartbeat,则必须使用其他的介质,如bcast(以太网)heartbeat。用适当的设备文件代替/dev/ttyS0。
watchdog /dev/watchdog

该选项是可选配置。通过Watchdog 功能可以获得提供最少功能的系统,该系统不提供heartbeat,可以在持续一份钟的不正常状态后重新启动。该功能有助于避免一台机器在被认定已经死亡之后恢复heartbeat的情况。如果这种情况发生并且磁盘挂载因故障而迁移(fail over),便有可能有两个节点同时挂载一块磁盘。如果要使用这项功能,则除了这行之外,也需要加载“softdog”内核模块,并创建相应的设备文件。方法是使用命令“insmod softdog”加载模块。然后输入“grep misc /proc/devices”并记住得到的数字(应该是10)。然后输入”cat /proc/misc | grep watchdog”并记住输出的数字(应该是130)。根据以上得到的信息可以创建设备文件,“mknod /dev/watchdog c 10 130”。
bcast eth1
表示在eth1接口上使用广播heartbeat(将eth1替换为eth0,eth2,或者您使用的任何接口)。
keepalive 2
设定heartbeat之间的时间间隔为2秒。
warntime 10
在日志中发出“late heartbeat“警告之前等待的时间,单位为秒。
deadtime 30
在30秒后宣布节点死亡。
initdead 120
在某些配置下,重启后网络需要一些时间才能正常工作。这个单独的”deadtime”选项可以处理这种情况。它的取值至少应该为通常deadtime的两倍。
baud 19200
波特率,串口通信的速度。
udpport 694
使用端口694进行bcast和ucast通信。这是默认的,并且在IANA官方注册的端口号。
auto_failback on
该选项是必须配置的。对于那些熟悉Tru64 Unix的人来说,heartbeat的工作方式类似于“favored member“模式。在failover之前,haresources文件中列出的主节点掌握所有的资源,之后从节点接管这些资源。当auto_failback设置为on时,一旦主节点重新恢复联机,将从从节点取回所有资源。若该选项设置为off,主节点便不能重新获得资源。该选项与废弃的nice_failback选项类似。如果要从一个nice_failback设置为off的集群升级到这个或更新的版本,需要特别注意一些事项以防止flash cut。请参阅FAQ中关于如何处理这类情况的章节。
node primary.mydomain.com
该选项是必须配置的。集群中机器的主机名,与“uname –n”的输出相同。
node backup.mydomain.com
该选项是必须配置的。同上。
respawn
该选项是可选配置的:列出将要执行和监控的命令。例如:要执行ccm守护进程,则要添加如下的内容:
respawn hacluster /usr/lib/heartbeat/ccm
使得Heartbeat以userid(在本例中为hacluster)的身份来执行该进程并监视该进程的执行情况,如果其死亡便重启之。对于ipfail,则应该是:
respawn hacluster /usr/lib/heartbeat/ipfail
注意:如果结束进程的退出代码为100,则不会重启该进程。

2 配置haresources

配置好ha.cf文件之后,便是haresources文件。该文件列出集群所提供的服务以及服务的默认所有者。 注意:两个集群节点上的该文件必须相同。集群的IP地址是该选项是必须配置的,不能在haresources文件以外配置该地址, haresources文件用于指定双机系统的主节点、集群IP、子网掩码、广播地址以及启动的服务等。其配置语句格式如下:
node-name network-config
其中node-name指定双机系统的主节点,取值必须匹配ha.cf文件中node选项设置的主机名中的一个,node选项设置的另一个主机名成为从节点。network-config用于网络设置,包括指定集群IP、子网掩码、广播地址等。resource-group用于设置heartbeat启动的服务,该服务最终由双机系统通过集群IP对外提供。在本文中我们假设要配置的HA服务为Apache和Samba。

在haresources文件中需要如下内容:

primary.mydomain.com 192.168.85.3 httpd smb

该行指定在启动时,节点linuxha1得到IP地址192.168.85.3,并启动Apache和Samba。在停止时,Heartbeat将首先停止smb,然后停止Apache,最后释放IP地址192.168.85.3。这里假设命令“uname –n”的输出为“primary.mydomain.com”-如果输出为“primary”,便应使用“primary”。

正确配置好haresources文件之后,将ha.cf和haresource拷贝到/etc/ha.d目录。
注意:资源文件中能执行的命令必须在/etc/ha.d/resource.d/ 中可见

3 配置Authkeys

需要配置的第三个文件authkeys决定了您的认证密钥。共有三种认证方式:crc,md5,和sha1。您可能会问:“我应该用哪个方法呢?”简而言之: 如果您的Heartbeat运行于安全网络之上,如本例中的交叉线,可以使用crc,从资源的角度来看,这是代价最低的方法。如果网络并不安全,但您也希望降低CPU使用,则使用md5。最后,如果您想得到最好的认证,而不考虑CPU使用情况,则使用sha1,它在三者之中最难破解。

文件格式如下:

auth
[]

因此,对于sha1,示例的/etc/ha.d/authkeys可能是

auth 1
1 sha1 key-for-sha1-any-text-you-want

对于md5,只要将上面内容中的sha1换成md5就可以了。 对于crc,可作如下配置:

auth 2
2 crc

不论您在关键字auth后面指定的是什么索引值,在后面必须要作为键值再次出现。如果您指定“auth 4”,则在后面一定要有一行的内容为“4 ”。

确保该文件的访问权限是安全的,如600。
转自:http://blog.csdn.net/ndcs_dhf2008/article/details/5570219

DRBD编译安装与配置

DRBD介绍

DRBD是一个用软件实现的、无共享的、服务器之间镜像块设备内容的存储复制解决方案。 DRBD Logo数据镜像:实时、透明、同步(所有服务器都成功后返回)、异步(本地服务器成功后返回)。DBRD的核心功能通过Linux的内核实现,最接近系统的IO栈,但它不能神奇地添加上层的功能比如检测到EXT3文件系统的崩溃。DBRD的位置处于文件系统以下,比文件系统更加靠近操作系统内核及IO栈。

DRBD编译安装

安装所需依赖:

  1. yum -y install gcc kernel-devel kernel-headers flex

开始安装drbd,下载地址:http://oss.linbit.com/drbd/
安装用户空间工具:

  1. cd /tmp
  2. wget http://oss.linbit.com/drbd/8.4/drbd-8.4.1.tar.gz
  3. tar xzf drbd-8.4.1.tar.gz
  4. cd drbd-8.4.1
  5. ./configure –prefix=/usr/local/drbd –with-km
  6. make KDIR=/usr/src/kernels/2.6.18-274.18.1.el5-i686/
  7. make install
  8. mkdir -p /usr/local/drbd/var/run/drbd
  9. cp /usr/local/drbd/etc/rc.d/init.d/drbd /etc/rc.d/init.d
  10. chkconfig –add drbd
  11. chkconfig drbd on

安装drbd模块:

  1. cd drbd
  2. make clean
  3. make KDIR=/usr/src/kernels/2.6.18-274.18.1.el5-i686/
  4. cp drbd.ko /lib/modules/`uname -r`/kernel/lib/
  5. depmod

注:usr/src/kernels/2.6.18-274.18.1.el5-i686/这个内核源码树路径需要根据自己的系统修改。

DRBD配置

建立分区

假如现在有第二块硬盘hdb,两个node都要分区。

  1. #fdisk /dev/hdb                                                      //准备为 hdb 建立分区
  2.  The number of cylinders for this disk is set to 20805.
  3.  There is nothing wrong with that, but this is larger than 1024,
  4.  and could in certain setups cause problems with:
  5.  1) software that runs at boot time (e.g., old versions of LILO)
  6.  2) booting and partitioning software from other OSs
  7.    (e.g., DOS FDISK, OS/2 FDISK)
  8.  Command (m for help): n                                              //键入 n 表示要建立分区
  9.  Command action
  10.     e   extended
  11.     p   primary partition (1-4)
  12.  p                                                                    //键入 p 表示建立主要分区
  13.  Partition number (1-4): 1                                            //键入 1 为此主要分区代号
  14.  First cylinder (1-20805, default 1):                                 //开始磁柱值,按下 enter 即可
  15.  Using default value 1
  16.  Last cylinder or +size or +sizeM or +sizeK (1-20805, default 20805): //结束磁柱值,按下 enter 即可
  17.  Using default value 20805
  18.  Command (m for help): w                                              //键入 w 表示确定执行刚才设定
  19.  The partition table has been altered!
  20.  Calling ioctl() to re-read partition table.
  21.  Syncing disks.
  22.  [root@node1 yum.repos.d]# partprobe                                  //使刚才的 partition table 变更生效

建立分区完成后使用指令 fdisk -l 确定 partition talbe 状态

  1. #fdisk -l
  2.  Disk /dev/hda: 21.4 GB, 21474754560 bytes
  3.  255 heads, 63 sectors/track, 2610 cylinders
  4.  Units = cylinders of 16065 * 512 = 8225280 bytes
  5.     Device Boot      Start         End      Blocks   Id  System
  6.  /dev/hda1   *           1          13      104391   83  Linux
  7.  /dev/hda2              14        2610    20860402+  8e  Linux LVM
  8.  Disk /dev/hdb: 10.7 GB, 10737377280 bytes
  9.  16 heads, 63 sectors/track, 20805 cylinders
  10.  Units = cylinders of 1008 * 512 = 516096 bytes
  11.     Device Boot      Start         End      Blocks   Id  System
  12.  /dev/hdb1               1       20805    10485688+  83  Linux

建立分区完成后请建立 /db 目录。 (Node1 及 Node2 都必须建立)

  1. #mkdir /db

建立drbd配置文件

主要定义两块global和resource。

  1. vi /usr/local/drbd/etc/drbd.conf

写入:

  1. include "drbd.d/global_common.conf";
  2. include "drbd.d/*.res";
  1. vi /usr/local/drbd/etc/drbd.d/global_common.conf

写入:

  1. global {
  2.   usage-count yes;
  3. }
  4. common {
  5.   net {
  6.     protocol C;
  7.   }
  8. }
  1. vi /usr/local/drbd/etc/drbd.d/r0.res

写入:

  1. resource r0 {
  2.   on node1 {
  3.     device    /dev/drbd1;
  4.     disk      /dev/hdb1;
  5.     address   192.168.1.101:7789;
  6.     meta-disk internal;
  7.   }
  8.   on node2 {
  9.     device    /dev/drbd1;
  10.     disk      /dev/hdb1;
  11.     address   192.168.1.103:7789;
  12.     meta-disk internal;
  13.   }
  14. }

设置hostname

根据上面的resource配置文件,需要对192.168.1.101和192.168.1.103分别设置hostname为node1和node2,设置方法如下:

  1. vi /etc/sysconfig/network

修改HOSTNAME为node1

  1. vi /etc/hosts

填入:

  1. 192.168.1.101 node1
  2. 192.168.1.103 node2

使node1 hostnmae临时生效

  1. hostname node1

node2机器设置类似。

设置resource

以下操作需要在node1和node2操作。

  1. #modprobe drbd                                    //载入 drbd 模块
  2. #lsmod|grep drbd                                  //确认 drbd 模块是否载入
  3.  drbd                  228528  0
  4.  #dd if=/dev/zero of=/dev/hdb1 bs=1M count=100     //把一些资料塞到 hdb 內 (否则 create-md 时有可能会出现错误)
  5.  #drbdadm create-md r0                             //建立 drbd resource
  6.  #drbdadm up r0                                  //启动 resource r0

查看node1和node2的状态应该类似下面的:

  1. cat /proc/drbd
  1. version: 8.4.1 (api:1/proto:86-100)
  2. GIT-hash: 91b4c048c1a0e06777b5f65d312b38d47abaea80 build by [email protected], 2012-02-12 06:05:36
  3.  m:res  cs         ro                   ds                         p  mounted  fstype
  4.  0:r0   Connected  Secondary/Secondary  Inconsistent/Inconsistent  C

表明现在已经启动服务,但还没有设置同步(即需要设置Primary Node)

设置Primary Node

以下操作仅在node1执行。
设置node1为primary node:

  1. drbdadm primary –force r0

再次查看node1的状态:

  1. #cat /proc/drbd
  2. version: 8.4.1 (api:1/proto:86-100)
  3. GIT-hash: 91b4c048c1a0e06777b5f65d312b38d47abaea80 build by [email protected], 2012-02-12 06:47:37
  4.  
  5.  1: cs:Connected ro:Primary/Secondary ds:UpToDate/UpToDate C r—–
  6.     ns:52892 nr:0 dw:0 dr:52892 al:0 bm:10 lo:0 pe:0 ua:0 ap:0 ep:1 wo:b oos:0

我们看到状态已经变成Primary/Secondary,即设置primary node成功。

创建DRBD文件系统

以下操作仅在node1执行。
上面已经完成了/dev/drbd1的初始化,现在来把/dev/drbd1格式化成ext3格式的文件系统。

  1. #mkfs.ext3 /dev/drbd1

然后将/dev/drbd1挂载到之前创建的/db目录。

  1. #mount /dev/drbd1 /db

现在你只要把数据写入/db目录,drbd即会立刻把数据同步到备机192.168.1.103的/dev/hdb1分区上。

drbd同步测试

当在备机node2启动drbd时,它是无法挂载/dev/hdb1分区的,我们可以尝试写些数据到node1的目录/db上,然后停止node2的drbd。

  1. drbdadm down r0

之后就可以把node2的/dev/hdb1挂载到目录/db

  1. mount -t ext3 /dev/hdb1 /db

我们就可以查看node2的/db目录是否有node1的数据。

手动切换主备机

我们可以把node1改变为备机,而node2改变为主机。
在node1上操作:

  1. umount /dev/drbd1
  2. drbdadm secondary r0

在node2上操作:

  1. drbdadm primary r0

此时应该已经切换成功。
如果配置过程中出现错误,可以参考http://devops.webres.wang/2012/02/drbd-erros-faq/

CentOS编译安装Heartbeat

安装cluster glue

安装heartbeat之前需要安装glue。

  1. yum install autoconf automake libtool glib2-devel libxml2-devel bzip2-devel e2fsprogs-devel libxslt-devel
  2. groupadd haclient
  3. useradd -g haclient hacluster
  4. cd /tmp
  5. wget http://hg.linux-ha.org/glue/archive/glue-1.0.9.tar.bz2
  6. tar xjf glue-1.0.9.tar.bz2
  7. cd Reusable-Cluster-Components-glue–glue-1.0.9
  8. ./autogen.sh
  9. ./configure –prefix=/usr/local/heartbeat
  10. make && make install

安装Resource Agents

  1. cd /tmp
  2. wget –no-check-certificate https://github.com/ClusterLabs/resource-agents/tarball/v3.9.2
  3. tar xzf v3.9.2
  4. cd ClusterLabs-resource-agents-b735277/
  5. ./autogen.sh
  6. export CFLAGS="$CFLAGS -I/usr/local/heartbeat/include -L/usr/local/heartbeat/lib"
  7. ./configure –prefix=/usr/local/heartbeat
  8. ln -s  /usr/local/heartbeat/lib/* /lib/
  9. make && make install

安装Heartbeat

  1. cd /tmp
  2. wget http://hg.linux-ha.org/heartbeat-STABLE_3_0/archive/7e3a82377fa8.tar.bz2
  3. tar xjf 7e3a82377fa8.tar.bz2
  4. cd Heartbeat-3-0-7e3a82377fa8/
  5. ./bootstrap
  6. export CFLAGS="$CFLAGS -I/usr/local/heartbeat/include -L/usr/local/heartbeat/lib"
  7. ./configure –prefix=/usr/local/heartbeat
  8. make && make install
  9. cp doc/ha.cf /usr/local/heartbeat/etc/ha.d/
  10. cp doc/haresources /usr/local/heartbeat/etc/ha.d/
  11. cp doc/authkeys /usr/local/heartbeat/etc/ha.d/
  12. cp heartbeat/init.d/heartbeat /etc/rc.d/init.d/
  13. chkconfig –add heartbeat
  14. chkconfig heartbeat on
  15. chmod 600 /usr/local/heartbeat/etc/ha.d/authkeys
  16. sed -i ‘s#/usr/lib/ocf#/usr/local/heartbeat/usr/lib/ocf#g’ /usr/local/heartbeat/etc/ha.d/shellfuncs
  17. sed -i ‘s#/usr/lib/ocf#/usr/local/heartbeat/usr/lib/ocf#g’ /usr/local/heartbeat/usr/lib/ocf/lib//heartbeat/ocf-shellfuncs
  18. sed -i ‘s#/usr/lib/ocf#/usr/local/heartbeat/usr/lib/ocf#g’ /usr/local/heartbeat/etc/ha.d/resource.d//hto-mapfuncs

除错

1、错误:glue_config.h:99:1: error: “HA_HBCONF_DIR” redefined
解决方法:http://devops.webres.wang/2012/02/glue_config-h991-error-ha_hbconf_dir-redefined/
2、错误configure.ac:9: error: Autoconf version 2.63 or higher is required
解决方法:http://devops.webres.wang/2012/03/configure-ac9-error-autoconf-version-2-63-or-higher-is-required/
3、错误configure.ac:63: require Automake 1.10.1, but have 1.9.6
解决方法:http://devops.webres.wang/2012/03/configure-ac63-require-automake-1-10-1-but-have-1-9-6/