一、概述

本次测试环境说明:
一台公共服务器提供NTPD,vsftpd(yum内网库),NFS网络共享(用于wordpress共享) 模拟公网:172.16.0.254 内网:192.168.10.253

DR(调度器) 双网卡:VIP(172.16.0.6) DIP:192.168.0.254
两台RS分别是:
RS01:192.168.10.11
RS02:192.168.10.12

测试拓扑:
手把手基于LVS-NAT模型负载均衡搭建wordpress服务

注意:本次测试的NTPD为集群提供时间的服务器在测试时可不用搭建,后面附搭建教程;vsftpd搭建内网yum也非必须,但前提要配置好LNP(nginx,php,php-fpm)和nfs挂载客户端工具;所有192.168.10.0/24网络均为仅主机模式。双网卡配置192.168.10.0/24段 内网ip时可以通过nmtui图形化工具配置。这里不演示。两台RS网关都指向DR上的DIP(192.168.10.254)所有主机(DR RS)都保持时间同步 。

所有虚拟主机系统均为CentOS7.4_x64 最小化安装。
关闭selinux,关闭firewalld 关闭防火墙.便于测试,(生产线请注意防火墙不要关闭,并配置好规则)

二、LVS-nat模式简单应用

1、LVS简介**
LVS(Linux Virtual Server)是四层调度,根据请求报文的目标IP和目标协议及端口将其调度转发至某RealServer(RS后端提供服务的主机),根据调度算法来挑选RS;ipvsadm:用户空间的命令行工具,规则管理器,用于管理集群服务及相关的RealServer;
DR(Director):即lvs调度器。
ipvs:工作于内核空间的netfilter的INPUT钩子之上的框架;

lvs集群的类型:
lvs-nat:修改请求报文的目标IP;多目标IP的DNAT;
lvs-dr:操纵封装新的MAC地址;
lvs-tun:在原请求IP报文之外新加一个IP首部;
lvs-fullnat:修改请求报文的源和目标IP;(需要额外打补丁实现)

2、lvs -nat模型
多目标IP的DNAT,通过将请求报文中的目标地址和目标端口修改为某挑出的RS的RIP和PORT实现转发;
(1)RIP和DIP必须在同一个IP网络,且应该使用私网地址;RS的网关要指向DIP;
(2)请求报文和响应报文都必须经由Director转发;Director易于成为系统瓶颈;
(3)支持端口映射,可修改请求报文的目标PORT;
(4)vs必须是Linux系统,rs可以是任意系统;

本次实验使用到的即是nat模型,见上图架构。

3、配置LVS DR
CentOS7安装好默认就已经支持内核级别ipvs框架,仅需要安装用户空间的管理工具ipvsadm

#设置主机名为dr
[root@centos7 ~]# hostnamectl set-hostname dr
[root@dr ~]# yum install ipvsadm -y
[root@dr ~]# rpm -ql ipvsadm
/etc/sysconfig/ipvsadm-config
/usr/lib/systemd/system/ipvsadm.service
/usr/sbin/ipvsadm
/usr/sbin/ipvsadm-restore
/usr/sbin/ipvsadm-save
/usr/share/doc/ipvsadm-1.27
/usr/share/doc/ipvsadm-1.27/README
/usr/share/man/man8/ipvsadm-restore.8.gz
/usr/share/man/man8/ipvsadm-save.8.gz
/usr/share/man/man8/ipvsadm.8.gz
#查看ipvsadm使用帮助
[root@dr ~]# ipvsadm -h

4、配置web集群
添加集群:

[root@dr ~]# ipvsadm -A -t 172.16.0.6:80 -s rr
#查看
[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.6:80 rr

添加计划任务同步时间

[root@dr ~]# crontab -l
*/10 * * * * ntpdate 192.168.10.253

添加节点RS

[root@dr ~]# ipvsadm -a -t 172.16.0.6:80 -r 192.168.10.11 -m
[root@dr ~]# ipvsadm -a -t 172.16.0.6:80 -r 192.168.10.12 -m
[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.6:80 rr
  -> 192.168.10.11:80             Masq    1      0          0         
  -> 192.168.10.12:80             Masq    1      0          0 

开启核心转发

[root@dr ~]# sysctl -w net.ipv4.ip_forward=1
或
直接写入sysctl.conf文件中
[root@dr ~]# tail -n 2 /etc/sysctl.conf
net.ipv4.ip_forward = 1

5、RS配置
两台RS上安装nginx
由于网络是仅主机模式所以先要安装好nginx或用内网yum安装好。
并添加计划任务保持时间同步 。

#安装nginx
#yum install nginx -y
#添加计划任务保持时间同步
# crontab -l
*/10 * * * * ntpdate 192.168.10.253

分别在每台的添加 测试页

[root@rs1 boot]# cat /usr/share/nginx/html/test1.html 
<h1>RS1 192.168.10.11</h1>

[root@rs2 conf.d]# cat /usr/share/nginx/html/test1.html 
<h1>RS2 192.168.10.12</h1>

6、测试
在另一台内网机器上
curl http://172.16.0.6/test1.html 如图:
手把手基于LVS-NAT模型负载均衡搭建wordpress服务

从图上可以看到rr算法调度轮循。

修改权重
[root@dr ~]# ipvsadm -e -t 172.16.0.6:80 -r 192.168.10.11 -m -w 2
[root@dr ~]# ipvsadm -e -t 172.16.0.6:80 -r 192.168.10.12 -m -w 3
[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.6:80 rr
  -> 192.168.10.11:80             Masq    2      0          10        
  -> 192.168.10.12:80             Masq    3      0          10  

在修改好权重后再访问,看到统计 的forward中也是2:3
清空统计

[root@dr ~]# ipvsadm -Z
[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.6:80 rr
  -> 192.168.10.11:80             Masq    2      0          10        
  -> 192.168.10.12:80             Masq    3      0          10       

查看速率

[root@dr ~]# ipvsadm -Ln --rate
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port                 CPS    InPPS   OutPPS    InBPS   OutBPS
  -> RemoteAddress:Port
TCP  172.16.0.6:80                       0        0        0        0        0
  -> 192.168.10.11:80                    0        0        0        0        0
  -> 192.168.10.12:80                    0        0        0        0        0

参数说明 :
CPS每秒建立的连接数    
InPPS每秒in 报文数
OutPPS   每秒out报文数
InBPS    每秒in字节数
OuBPS    每秒out字节数
ipvsadmin -Z   清空计数器

查看当前状态

[root@dr ~]# ipvsadm -Ln --stats
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port               Conns   InPkts  OutPkts  InBytes OutBytes
  -> RemoteAddress:Port
TCP  172.16.0.6:80                       0        0        0        0        0
  -> 192.168.10.11:80                    0        0        0        0        0
  -> 192.168.10.12:80                    0  
说明 :
Conns:连接总数
InPkts:每秒进来的数据包
OutPkts:每秒出去的数据包
InBytes: 每秒进来 的字节数
OutBytes:每秒出去的字节数

修改高度算法为加权轮循(wrr)
[root@dr ~]# ipvsadm -E -t 172.16.0.6:80 -s wrr
[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.6:80 wrr
-> 192.168.10.11:80 Masq 2 0 10
-> 192.168.10.12:80 Masq 3 0 10

测试

[root@minion-one ~]# for i in {1..20};do sleep 1;curl http://172.16.0.6/test1.html;done
<h1>RS2 192.168.10.12</h1>
<h1>RS2 192.168.10.12</h1>
<h1>RS1 192.168.10.11</h1>
<h1>RS2 192.168.10.12</h1>
<h1>RS1 192.168.10.11</h1>
<h1>RS2 192.168.10.12</h1>
<h1>RS2 192.168.10.12</h1>
<h1>RS1 192.168.10.11</h1>
<h1>RS2 192.168.10.12</h1>
<h1>RS1 192.168.10.11</h1>
<h1>RS2 192.168.10.12</h1>
<h1>RS2 192.168.10.12</h1>
<h1>RS1 192.168.10.11</h1>
省略...

假设一台岩机(192.168.10.12)
岩机可以通过两种方法实现,修改权重为0或删除该主机来模拟也或把这台主机关机。

#权重修改为0
#ipvsadm -e -t 172.16.0.6:80 -r 192.168.10.11 -m -w 0

#删除
[root@dr ~]# ipvsadm -d -t 172.16.0.6:80 -r 192.168.10.12
[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.6:80 wrr
  -> 192.168.10.11:80             Masq    2      0          0        

无论那种模拟岩机效果测试如下:

[root@minion-one ~]# for i in {1..20};do curl http://172.16.0.6/test1.html;done
<h1>RS1 192.168.10.11</h1>
<h1>RS1 192.168.10.11</h1>
<h1>RS1 192.168.10.11</h1>
<h1>RS1 192.168.10.11</h1>
<h1>RS1 192.168.10.11</h1>
<h1>RS1 192.168.10.11</h1>

模拟两台都岩机

模拟两台都挂了
[root@dr ~]# ipvsadm -d -t 172.16.0.6:80 -r 192.168.10.11
[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.6:80 wrr

测试效果:
[root@minion-one ~]# for i in {1..20};do curl http://172.16.0.6/test1.html;done
curl: (7) couldn't connect to host
curl: (7) couldn't connect to host
curl: (7) couldn't connect to host
curl: (7) couldn't connect to host
curl: (7) couldn't connect to host

但两台都岩机时我们让DR显示一个sorry页面而非curl: (7) couldn't connect to host;

在DR上也安装nginx
[root@dr ~]# yum install nginx -y
安装配置好dr上nginx
systemctl start nginx
外网依然不通通过 vip来访问 dr上的nginx服务
原因是 input链上被截了
但DIP上可以访问
[root@dr ~]# curl http://192.168.10.254
<h1>Sorry,web error!</h1>

因此添加DIP的节点
[root@dr ~]# ipvsadm -a -t 172.16.0.6:80 -r 127.0.0.1 -m
[[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.6:80 wrr
  -> 127.0.0.1:80                 Masq    1      0          0     

发现以上配置不行需要如下
[root@dr ~]# ipvsadm -e -t 172.16.0.6:80 -r 127.0.0.1 -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.6:80 wrr
  -> 127.0.0.1:80                 Route   1      0          1  

 [root@minion-one ~]# for i in {1..20};do curl http://172.16.0.6;done
<h1>Sorry,web error!</h1>
<h1>Sorry,web error!</h1>
<h1>Sorry,web error!</h1>
<h1>Sorry,web error!</h1>
<h1>Sorry,web error!</h1>
<h1>Sorry,web error!</h1>
<h1>Sorry,web error!</h1>

7、ipvs规则管理

保存规则:

[root@dr ~]# systemctl stop ipvsadm
[root@dr ~]# cat /etc/sysconfig/ipvsadm
-A -t 172.16.0.6:80 -s wrr
-a -t 172.16.0.6:80 -r 192.168.10.11:80 -m -w 1
-a -t 172.16.0.6:80 -r 192.168.10.12:80 -m -w 1
或
[root@dr ~]# ipvsadm -S -n > /etc/sysconfig/ipvsadm

清空规则:

[root@dr ~]# ipvsadm -C
[root@dr ~]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn

还原规则:

[root@dr ~]# ipvsadm -R </etc/sysconfig/ipvsadm
或
[root@dr ~]# systemctl restart ipvsadm

至此LVS nat模型的简单配置完成

问题:

以上是对静态页面的负载调度,要是对动态的网站和需要 上传文件,需要保持会话这种简单配置就有问题,试想要是用户第一个请求分配到RS1第二个上传文件被分配到RS02上不是出问题了?
因此需要修改高度算法 sh或统一会话管理高度,本次通过共享数据库,共享数据文件和sh算法来搭建wordpress服务;

三、基于LVS-nat搭建wordpress服务

本次测试需要 用到NFS(共享 网络文件系统 ) 后面附教程,共享数据库;
1、数据库配置

数据库:
[root@publicsrvs ~]# yum -y install mariadb-server mariadb-devel
MariaDB [mysql]> set password for root@localhost = password("redhat");
授权root在192.168.10.0网段有权限访问数据库
>grant all privileges on *.* to root@'192.168.10.%' identified by "redhat";
#创建wordpress数据库
>create database wordpress charset=utf8;

两台wordpress机器上安装mysql客户端 php php-mysql
#yum install maridb php php-mysql -y

RS上测试连接数据库:
[root@rs1 ~]# mysql -uroot -h 192.168.10.253 -p
Enter password: 
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 8
Server version: 5.5.56-MariaDB MariaDB Server
Copyright (c) 2000, 2017, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]> 

2、RS挂载NFS共享

两台RS挂载NFS共享
#yum install nfs-utils
#mount -t nfs 192.168.10.253:/data1/NFS  /data1/web/WordPress
#添加开机自动挂载
#chmod +x /etc/rc.local
#tail -n 6 /etc/rc.local
touch /var/lock/subsys/local
if ping -c 2 192.168.10.253
then
    mount -t nfs 192.168.10.253:/data1/NFS  /data1/web/WordPress
fi

3、修改调度算法 为sh

[root@dr ~]# ipvsadm -E -t 172.16.0.6:80 -s 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.6:23 wlc
  -> 192.168.10.11:23             Masq    1      0          0         
  -> 192.168.10.12:23             Masq    1      0          0         
TCP  172.16.0.6:80 sh
  -> 192.168.10.11:80             Masq    1      0          0         
  -> 192.168.10.12:80             Masq    1      0          0 

4、两台RS nginx配置

#cat /etc/nginx/conf.d/wordpress.conf

[root@rs2 conf.d]# cat wordpress.conf 
server{
listen  80;
server_name 172.16.0.6;       #指向DR VIP
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;
        }

}

5、RS上配置wordpress

#wget https://cn.wordpress.org/wordpress-4.9.1-zh_CN.tar.gz
#mkdir /data1/web/Wordpress
#tar xvf latest.tar.gz -C /data1/web/Wordpress
#chown nginx.nginx /data1/web/Wordpress
#chmod 775 /data1/web/Wordpress -R
#nginx -t
#nginx -s reload

6、wordpress数据库配置

到其中一台RS服务器的/data1/web/WordPress目录中或到NFS中修改wordpress数据库连接信息

#[root@publicsrvs NFS]# cp  wp-config-sample.php  wp-config.php
主要修改以下项
21 // ** MySQL 设置 - 具体信息来自您正在使用的主机 ** //
22 /** WordPress数据库的名称 */
23 define('DB_NAME', 'wordpress');
24 
25 /** MySQL数据库用户名 */
26 define('DB_USER', 'root');
27 
28 /** MySQL数据库密码 */
29 define('DB_PASSWORD', 'redhat');
30 
 31 /** MySQL主机 */
 32 define('DB_HOST', '192.168.10.253');
 33 
 34 /** 创建数据表时默认的文字编码 */
 35 define('DB_CHARSET', 'utf8');


7、网页配置wordpress

浏览器上访问http://172.16.0.6
如图:
手把手基于LVS-NAT模型负载均衡搭建wordpress服务

手把手基于LVS-NAT模型负载均衡搭建wordpress服务

点登录 写一篇测试文章并上传一个图片出现 如下错误
手把手基于LVS-NAT模型负载均衡搭建wordpress服务

原因是上传的目录 没有权限
解决:

[root@rs1 WordPress]# pwd
/data1/web/WordPress
[root@rs1 WordPress]# chmod 775 wp-content/
[root@rs1 WordPress]# 

再次上传成功如图:
手把手基于LVS-NAT模型负载均衡搭建wordpress服务
手把手基于LVS-NAT模型负载均衡搭建wordpress服务

到DR上查看连接状态

[root@dr ~]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags     
TCP  172.16.0.6:80 sh
  -> 192.168.10.11:80             Masq    1      0          0         
  -> 192.168.10.12:80             Masq    1      1          1 

可以发现通过sh算法 把来自同一个客户端的请求转发到一个RS上,而RS上的数据库和数据文件都是同一个主机,因此解决了数据同步和负载问题。

四、相关公共服务的搭建

1、NFS服务

#yum -y install nfs-utils rpcbind
配置文件在/etc/exports中
cat /etc/exports
/data1/NFS 192.168.10.0/24(rw,no_root_squash,no_all_squash,sync)
/data1/NFS2 172.16.0.0/24(rw,no_root_squash,no_all_squash,sync)

注:配置文件说明:
/data1/NFS 为共享目录

192.168.10.0/24  可以为一个网段,一个IP,也可以是域名,域名支持通配符 如: *.qq.com
rw:read-write,可读写;
ro:read-only,只读;
sync:文件同时写入硬盘和内存;
async:文件暂存于内存,而不是直接写入内存;
no_root_squash:NFS客户端连接服务端时如果使用的是root的话,那么对服务端分享的目录来说,也拥有root权限。显然开启这项是不安全的。
root_squash:NFS客户端连接服务端时如果使用的是root的话,那么对服务端分享的目录来说,拥有匿名用户权限,通常他将使用nobody或nfsnobody身份;
all_squash:不论NFS客户端连接服务端时使用什么用户,对服务端分享的目录来说都是拥有匿名用户权限;
anonuid:匿名用户的UID值,可以在此处自行设定。
anongid:匿名用户的GID值。

使配置生效
exportfs -r
systemctl enable nfs
systemctl enable rpcbind
systemctl start rpcbind
systemctl start nfs

2、NTPD服务

#yum install ntp ntpupdate -y
#cat /etc/ntp.conf
driftfile /var/lib/ntp/drift
restrict default nomodify notrap nopeer noquery
restrict 127.0.0.1 
restrict 192.168.10.254 
restrict ::1
restrict 172.16.0.0 mask 255.255.255.0 nomodify notrap
restrict 192.168.10.0 mask 255.255.255.0 nomodify notrap
server time.windows.com     iburst
server 2.cn.pool.ntp.org    iburst
server 1.asia.pool.ntp.org  iburst
server 2.asia.pool.ntp.org  obirst
restrict 2.cn.pool.ntp.org nomodify notrap noquery
restrict 1.asia.pool.ntp.org nomodify notrap noquery
restrict 2.asia.pool.ntp.org nomodify notrap noquery
server  127.127.1.0     # local clock
fudge   127.127.1.0 stratum 10
includefile /etc/ntp/crypto/pw
keys /etc/ntp/keys
disable monitor

#systemctl enable ntpd
#systemctl start ntpd
注:配置好后稍等 时间就会同步

以上所有配置本人在4core 8G机器都测试通过,如有错误 不当或遗漏之处,欢迎指正交流,谢谢!