一、概要

1、概述
上一篇我们测试了基于LVS NAT模型搭建wordpress服务,以及简单说明了LVS-NAT,LVS-DR等模型的概念;由于LVS-NAT模型的负载有一个缺陷,就是所有请求与响应都需要通过DR,所以在大并发下容易出现瓶颈,而LVS-DR模型就很好的解决了这个问题;

2、LVS-DR模型:
直接路由,通过为请求报文重新封装一个MAC首部进行转发,源MAC是DIP所在的接口的MAC,目标MAC是某挑选出的RS的RIP所在接口的MAC地址;源IP/PORT,以及目标IP/PORT均保持不变;

3、LVS-DR模型特点:
Director和各RS都得配置使用VIP;
(1) 确保前端路由器将目标IP为VIP的请求报文发往Director:
在RS上修改内核参数以限制arp通告及应答级别即修改内核arp_announce,arp_ignore参数;
(2) RS的RIP可以使用私网地址,也可以是公网地址;RIP与DIP在同一IP网络;RIP的网关不能指向DIP,以确保响应报文不会经由Director;
(3) RS跟Director要在同一个物理网络;
(4) 请求报文要经由Director,但响应不能经由Director,而是由RS直接发往Client;
(5) 不支持端口映射;

4、本次测试拓扑结构
LVS之DR模型搭建wordpress服务及会话持久与绑定

以上涉及到的NFS共享存储,MySQL,nginx,php部署,本篇将不在详细给出部署步骤,可以参考上一篇<手把手基于LVS负载均衡搭建wordpress服务>请添加链接描述

二、LVS-DR模型配置

1、RS基础配置
a、挂载NFS
tail -n 5 /etc/rc.local

if ping -c 2  172.16.0.254
then
        mount -t nfs 172.16.0.254:/data1/NFS2  /data1/web/WordPress
fi

b、PHP,nginx,mysql配置
具体配置参考之前教程

# php -v
PHP 5.4.16 (cli) (built: Nov  6 2016 00:29:02) 
Copyright (c) 1997-2013 The PHP Group
Zend Engine v2.4.0, Copyright (c) 1998-2013 Zend Technologies
#nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
#数据库授权访问:
> grant all privileges on *.* to root@'172.16.0.%' identified by "redhat";
Query OK, 0 rows affected (0.00 sec)
#创建数据库wordpress_dr
> create database wordpress_dr charset=utf8;
Query OK, 1 row affected (0.00 sec)

2、RS网络内核参数配置

修改内核参数通告与响应级别
作用描述:
由于用户请求报文首先到达director上VIP,DR调度到某一RS,RS再直接响应用户;所以DR 和RS都配置有VIP地址且在同一个网段,势必造成冲突,所以要把RS上arp广播通告给阻断,来确保用户请求来时,只有DR响应,而其他RS上的VIP不响应,等DR调度到给RS时再响应客户端用户(使用自己的VIP和目标的CIP响应);

配置RS的lo接口VIP地址172.16.0.99

#ifconfig lo:0 172.16.0.99 netmask 255.255.255.255 broadcast 172.16.0.99 up
#ifconfig
lo:0: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 172.16.0.99  netmask 255.255.255.255
        loop  txqueuelen 1  (Local Loopback)

修改RS两个接口通告模式与响应级别:

 #仅是把发往自己接口请求给予响应,默认是0表示不管来自那个接口,只要本地有这个ip都给予响应
echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore    
echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore      
 #仅把自己接口向外通告,默认是0表示开机时把自己所有的ip向外通告
echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce

为了便于配置参数写成以下脚本
#cat setarp.sh

#!/bin/bash
case $1 in 
start)
    echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
    echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore
    echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
    echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce
    ;;

stop)
    echo 0 > /proc/sys/net/ipv4/conf/all/arp_ignore
    echo 0 > /proc/sys/net/ipv4/conf/lo/arp_ignore
    echo 0 > /proc/sys/net/ipv4/conf/all/arp_announce
    echo 0 > /proc/sys/net/ipv4/conf/lo/arp_announce
    ;;

*)
    echo  "USAGE: $(basename $0) start|stop"
    ;;
esac

分别在两台RS上运行脚本;

3、修改RS路由
修改RS路由的目的就是但DR把用户请求的报文调度到某RS时,由于VIP是配置在RS的回环lo:0接口上,RS的直接通过 VIP地址响应给客户端用户,所以需要 经过lo:0网卡出去响应,所以需要添加路由

添加之前路由
# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         172.16.0.1      0.0.0.0         UG    100    0        0 ens33
172.16.0.0      0.0.0.0         255.255.255.0   U     100    0        0 ens33

#添加主机路由
[root@rs1 ~]# route add -host 172.16.0.99 dev lo:0

#查看
[root@rs1 ~]# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         172.16.0.1      0.0.0.0         UG    100    0        0 ens33
172.16.0.0      0.0.0.0         255.255.255.0   U     100    0        0 ens33
172.16.0.99     0.0.0.0         255.255.255.255 UH    0      0        0 lo

4、启动RS各服务
RS01配置wordpress
#cat /etc/nginx/conf.d/wordpress.conf

server{
listen  80;
server_name 172.16.0.7;
root /data1/web/WordPress;
index index.html index.php;

location ~ \.php$ {
            fastcgi_pass   127.0.0.1:9000;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
            include        fastcgi_params;
        }
}

RS02配置wordpress
#cat /etc/nginx/conf.d/wordpress.conf

server{
listen  80;
server_name 172.16.0.8;
root /data1/web/WordPress;
index index.html index.php;

location ~ \.php$ {
            fastcgi_pass   127.0.0.1:9000;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
            include        fastcgi_params;
        }
}
#systemctl start nginx
#systemctl start php-fpm

到此两台RS配置wordpress完成~

5、安装配置wordpress
由于之前配置是基于nat 172.16.0.6的ip安装wordpress,所以本次需要 重新下载安装配置,以下在NFS服务器上操作

##下载
[root@publicsrvs]# wget https://cn.wordpress.org/wordpress-4.9.1-zh_CN.tar.gz
#解压
[root@publicsrvs]# tar xvf wordpress-4.9.1-zh_CN.tar.gz -C /data1/NFS2
[root@publicsrvs]# cd /data1/NFS2/wordpress
[root@publicsrvs]# mv * ../
##修改权限 
[root@publicsrvs]# chown nginx.nginx * -R
[root@publicsrvs]# chmod 775 * -R
[root@publicsrvs]#cp wp-config-sample.php wp-config.php
#配置数据连接信息
[root@publicsrvs]#  cat wp-config.php
/** WordPress数据库的名称 */
define('DB_NAME', 'wordpress_dr');

/** MySQL数据库用户名 */
define('DB_USER', 'root');

/** MySQL数据库密码 */
define('DB_PASSWORD', 'redhat');

/** MySQL主机 */
define('DB_HOST', '172.16.0.254');

/** 创建数据表时默认的文字编码 */
define('DB_CHARSET', 'utf8');

5、DR配置
a、配置VIP在物理网卡上

[root@dr ~]# ifconfig ens33:0 172.16.0.99 netmask  255.255.255.255 broadcast 172.16.0.99 up

b、安装配置ipvs

[root@dr ~]# yum install ipvsadm -y

c、添加集群及节点

[root@dr ~]# ipvsadm  -A -t 172.16.0.99:80 -s sh       #sh用于绑定会话
[root@dr ~]# ipvsadm -ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  172.16.0.99:80 sh

[root@dr ~]# ipvsadm -a -t 172.16.0.99:80 -r 172.16.0.7 -g     #-g为DR模型
[root@dr ~]# ipvsadm -a -t 172.16.0.99:80 -r 172.16.0.8 -g
[root@dr ~]# ipvsadm -ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  172.16.0.99:80 sh
  -> 172.16.0.7:80                Route   1      0          0         
  -> 172.16.0.8:80                Route   1      0          0

6、安装wordpress
http://172.16.0.99
如图:
LVS之DR模型搭建wordpress服务及会话持久与绑定
点安装wordpress
如图提示安装成功
LVS之DR模型搭建wordpress服务及会话持久与绑定

点登录如图:
LVS之DR模型搭建wordpress服务及会话持久与绑定
wordpress安装成功
至于写文章以及上传图片时注意的事项和之前 LVS-nat下部署一样;这里就不做演示!
最终用admin写了一个测试文章插入图片,创建一个san用户进行登录访问效果如下:
LVS之DR模型搭建wordpress服务及会话持久与绑定

到这里通过 LVS-DR模型部署wordpress完成 !
但这里有一些问题:
a、如果 一个RS宕机,按照上面的sh会话绑定,将出导致a用户访问时可能就会一直访问不了,需要在DR上去除这个RS节点!
b、除了sh会话绑定还有没有别的方案?
c、当宕机的RS恢复时如果自动添加到可用的节点?
d、RS意外重启是否能自动 恢复?

三、优化LVS-DR模型方案

对于以上的问题我们通过以下一一解决
针对RS节点出现故障,DR上需要能自动检测到问题RS,并将其从集群中(ipvs规则中)去除,等恢复时再添加到集群;这里通过 ldirectord服务实现
1、安装ldriectord服务

#下载
[root@dr ~]# wget https://rpmfind.net/linux/fedora/linux/releases/25/Everything/x86_64/os/Packages/l/ldirectord-3.9.7-4.fc24.x86_64.rpm

#安装
[root@dr ~]# yum install ./ldirectord-3.9.7-4.fc24.x86_64.rpm
[root@dr ~]# cp /usr/share/doc/ldirectord/ldirectord.cf  /etc/ha.d/ldirectord.cf


2、配置ldirectord

为了符合配置规范,当两台RS都不能访问时让DR做出提示
因此dr上安装 nginx显示 维护 页

[root@dr ~]# yum install nginx -y
[root@dr ~]#vim /etc/nginx.conf
修改42行为
root   /data/nginx/html;

[root@dr ~]# mkdir -pv /data/nginx/html 
[root@dr ~]# echo "<h1>Sorry,Maintanance Time~</h1>"   >/data/nginx/html/index.html
[root@dr ~]# systemctl restart nginx

#DR上测试
[root@dr nginx]# curl http://localhost
<h1>Sorry,Maintanance Time~</h1>

在RS上(NFS下wordpress上创建一个check.html文件,用于ldirectord服务检测使用)

#cd /data1/web/WordPress
#cat check.html
<h1> check_ok </h1>

配置ldirectord
#cat /etc/ha.d/ldirectod.cf

# Global Directives
checktimeout=3      #检测超时时间
checkinterval=1      #检查时间间隔 
#fallback=127.0.0.1:80
#fallback6=[::1]:80
autoreload=yes       #有变动 是否自动加载
logfile="/var/log/ldirectord.log"   #记录日志 位置 
quiescent=no

# Sample for an http virtual service
virtual=172.16.0.99:80           #集群
        real=172.16.0.7:80 gate  #节点及模式 
        real=172.16.0.8:80 gate
        fallback=127.0.0.1:80 gate   #本地响应节点
        service=http     #服务名
        scheduler=sh   #算法
        #persistent=600
        #netmask=255.255.255.255
        protocol=tcp     #协议
        checktype=negotiate  
        checkport=80   #检测端口
        request="check.html"   #检测文件夹
        receive="check_ok   #检测内容

#清空ipvs规则并启动ldirectord服务

[root@dr ha.d]# ipvsadm -C
[root@dr ha.d]# systemctl start ldirectord
[root@dr ha.d]# ipvsadm -ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  172.16.0.99:80 sh
  -> 172.16.0.7:80                Route   1      0          0         
  -> 172.16.0.8:80                Route   1      0          0

3、模拟RS岩机
#岩机前访问,可以看到访问由172.16.0.8提供~

[root@dr ha.d]# ipvsadm -ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  172.16.0.99:80 sh
  -> 172.16.0.7:80                Route   1      0          0         
  -> 172.16.0.8:80                Route   1      8          0  

#把172.16.0.8 RS服务shutdown

[root@rs2 conf.d]# systemctl stop nginx
[root@rs2 conf.d]# systemctl status nginx
● nginx.service - The nginx HTTP and reverse proxy server
   Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; vendor preset: disabled)
   Active: inactive (dead) since Sat 2018-01-06 18:32:52 CST; 9s ago

再访问http://172.16.0.99 以发现依然正常访问

LVS之DR模型搭建wordpress服务及会话持久与绑定
再看DR上ipvs规则

[root@dr ha.d]# ipvsadm -ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  172.16.0.99:80 sh
  -> 172.16.0.7:80                Route   1      2          0         

可以看到 RS2 (172.16.0.8)已经被ldirectord删除,同时访问由172.16.0.7提供~

再把RS1(172.16.0.7)服务stop再查看 DR ipvs规则

[root@dr ha.d]# ipvsadm -ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  172.16.0.99:80 sh
  -> 127.0.0.1:80                 Route   1      0          0    

再次访问http://172.16.0.99 出现sorry页
LVS之DR模型搭建wordpress服务及会话持久与绑定

可以看到已经达到 预期效果~!
再次启动两台RS nginx服务~
查看DR上的ipvs规则状态

[root@dr ha.d]# ipvsadm -ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  172.16.0.99:80 sh
  -> 172.16.0.7:80                Route   1      0          0         
  -> 172.16.0.8:80                Route   1      6          0  

再次访问http://172.16.0.99
LVS之DR模型搭建wordpress服务及会话持久与绑定

至此基于ldirectord服务检查RS健康并自动管理节点上下线完成!

4、优化DR及RS脚本
a、RS配置
为了达到 RS意外关机重启,让节点能自动 配置达到上线标准
配置网络参数和配置VIP脚本
#cat setarp.sh

#!/bin/bash
vip='172.16.0.99'
mask='255.255.255.255'
iface='lo:0'
case $1 in 
start)
    echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
    echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore
    echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
    echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce

    ifconfig $iface $vip netmask $mask broadcast $vip up
    route add -host $vip  dev $iface
    ;;

stop)
    ifconfig $iface down

    echo 0 > /proc/sys/net/ipv4/conf/all/arp_ignore
    echo 0 > /proc/sys/net/ipv4/conf/lo/arp_ignore
    echo 0 > /proc/sys/net/ipv4/conf/all/arp_announce
    echo 0 > /proc/sys/net/ipv4/conf/lo/arp_announce
    ;;

*)
    echo  "USAGE: $(basename $0) start|stop"
    ;;
esac

添加开机自动 运行
#chmod +x /etc/rc.local
tail -f 10 /etc/rc.local

#自动挂载NFS
if ping -c 2 172.16.0.254
then
        mount -t nfs 172.16.0.254:/data1/NFS2  /data1/web/WordPress
fi
#自动配置网络
/root/setarp.sh start

#systemctl enable nginx

b、DR配置脚本
[root@dr ha.d]# systemctl enable ldirectord
#cat setDrVip.sh

[root@dr ~]# cat setDrVip.sh 
#!/bin/bash
#
vip='172.16.0.99'
iface='ens33:0'
mask='255.255.255.255'
port='80'
rs1='172.16.0.7'
rs2='172.16.0.8'
scheduler='rr'
type='-g'
case $1 in
start)
ifconfig $iface $vip netmask $mask broadcast $vip up
iptables -F

ipvsadm -A -t ${vip}:${port} -s $scheduler
ipvsadm -a -t ${vip}:${port} -r ${rs1} $type -w 1
ipvsadm -a -t ${vip}:${port} -r ${rs2} $type -w 1
    ;;
stop)
ipvsadm -C
ifconfig $iface down
    ;;
*)
echo "Usage $(basename $0) start|stop"
exit 1
    ;;
esac        

到此一个基于LVS DR模型 和ldirectord服务的wordpress服务 完成 !
另外本次测试过程繁多,不免有遗漏之处!欢迎交流指正~