18.6 负载均衡集群介绍
- 主流开源软件LVS、keepalived、haproxy、nginx等
- 其中LVS属于4层(网络OSI 7层模型),nginx属于7层,haproxy既可以认为是4层,也可以当做7层使用
- keepalived的负载均衡功能其实就是LVS(keepalived内置带有LVS)
- lvs这种4层的负载均衡是可以分发除80外的其他端口通信的,比如MySQL的,而nginx仅仅支持http,https,mail,haproxy也支持MySQL这种
- 相比较来说,LVS这种4层的更稳定,能承受更多的请求,而nginx这种7层的更加灵活,能实现更多的个性化需求
18.7 LVS介绍
- LVS是由国人章文嵩开发
- 流行度不亚于apache的httpd,基于TCP/IP做的路由和转发,稳定性和效率很高
- LVS最新版本基于Linux内核2.6,有好多年不更新了
- LVS有三种常见的模式:NAT(iptables nat表)、DR、IP Tunnel
- LVS架构中有一个核心角色叫做分发器(Load balance),它用来分发用户的请求,还有诸多处理用户请求的服务器(Real Server,简称rs)
LVS NAT模式
- 这种模式借助iptables的nat表来实现
- 用户的请求到分发器后,通过预设的iptables规则,把请求的数据包转发到后端的rs上去
- rs需要设定网关为分发器的内网ip
- 用户请求的数据包和返回给用户的数据包全部经过分发器,所以分发器成为瓶颈
- 在nat模式中,只需要分发器有公网ip即可,所以比较节省公网ip资源
- 这种模式的好处是节省公网IP,但是调度器会成为一个瓶颈。因为当访问量巨大的时候,调度器的请求量也会随着变大,所以处理用户请求和分发rs的结果处理会严重影响效率。
- 一般使用NAT的模式访问量不能太大,规模也不支持太大,一般建议10台以下服务器。要想想10台以上服务器,需要巨大的成本来升级硬件配置。
- NAT模式就是利用iptables转发
LVS IP Tunnel模式
- load balancer与rs建立ip tunnel,实现原理是更改了数据包的目的ip。
- 这种模式,需要有一个公共的IP(为用户提供服务)配置在分发器和所有rs上,我们把它叫做vip
- 客户端请求的目标IP为vip,分发器接收到请求数据包后,会对数据包做一个加工,会把目标IP改为rs的IP,这样数据包就到了rs上
- rs接收数据包后,会还原原始数据包,这样目标IP为vip,因为所有rs上配置了这个vip,所以它会认为是它自己
- 每台rs也需要配置vip,便于与用户(来源ip)进行通信,这样的做的话,load balancer就没有瓶颈的情况了,因为此时load balancer只是把用户的请求转给rs
- IP Tunnel模式把目标ip做了更改,方便与用户进行通信。
LVS DR模式
- 这种模式,也需要有一个公共的IP配置在分发器和所有rs上,也就是vip
- rs接收数据包后,会还原原始数据包,这样目标IP为vip,因为所有rs上配置了这个vip,所以它会认为是它自己
- 和IP Tunnel不同的是,它会把数据包的MAC地址修改为rs的MAC地址
18.8 LVS调度算法
- 轮询 Round-Robin rr
- 加权轮询 Weight Round-Robin wrr
- 最小连接 Least-Connection lc
- 加权最小连接 Weight Least-Connection wlc
- 基于局部性的最小连接 Locality-Based Least Connections lblc
- 带复制的基于局部性最小连接 Locality-Based Least Connections with Replication lblcr
- 目标地址散列调度 Destination Hashing dh
- 源地址散列调度 Source Hashing sh
其中1-4是常用的,需要熟记。
18.9-18.10 LVS NAT模式搭建
18.9 LVS NAT模式搭建(上)
准备工作
三台机器,分别是centos7-01,centos7-02,centos7-03(可以克隆一台,也可以重新安装一台,记得修改克隆后的主机名和ip地址)
分发器(两个网卡:一个内网,一个外网),也叫调度器(简写为dir)
内网:192.168.189.128,外网:192.168.149.147(vmware仅主机模式)
rs1
内网:192.168.189.129,设置网关为192.168.189.128
rs2
内网:192.168.189.130,设置网关为192.168.189.128
rs1(centos-02)和rs2(centos-03)的设置(以下操作是rs1,rs2都要操作)
1 网关为192.168.189.128
[root@centos7-02 ~]# !vim
vim /etc/sysconfig/network-scripts/ifcfg-ens33
TYPE=Ethernet
PROXY_METHOD=none
BROWSER_ONLY=no
BOOTPROTO=static
DEFROUTE=yes
IPV4_FAILURE_FATAL=no
IPV6INIT=yes
IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
IPV6_FAILURE_FATAL=no
IPV6_ADDR_GEN_MODE=stable-privacy
NAME=ens33
DEVICE=ens33
ONBOOT=yes
IPADDR=192.168.189.129
NETMASK=255.255.255.0
GATEWAY=192.168.189.128
DNS1=114.114.114.114 [root@centos7-03 ~]# !vim
vim /etc/sysconfig/network-scripts/ifcfg-ens33
TYPE=Ethernet
PROXY_METHOD=none
BROWSER_ONLY=no
BOOTPROTO=static
DEFROUTE=yes
IPV4_FAILURE_FATAL=no
IPV6INIT=yes
IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
IPV6_FAILURE_FATAL=no
IPV6_ADDR_GEN_MODE=stable-privacy
NAME=ens33
DEVICE=ens33
ONBOOT=yes
IPADDR=192.168.189.130
NETMASK=255.255.255.0
GATEWAY=192.168.189.128
DNS1=114.114.114.114 2 重启网络服务
3 检查网关
[root@centos7-02 ~]# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 192.168.189.128 0.0.0.0 UG 100 0 0 ens33
192.168.189.0 0.0.0.0 255.255.255.0 U 100 0 0 ens33
[root@centos7-03 ~]# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 192.168.189.128 0.0.0.0 UG 100 0 0 ens33
192.168.189.0 0.0.0.0 255.255.255.0 U 100 0 0 ens33 分发器设置:
1 分发器的外网网卡在VMware上面设为仅主机模式
2 设置分发器外网网卡的ip
先查看虚拟机给出的默认网段(根据实际情况,支持自定义)
设置外网网卡的ip(无须设置网关)
[root@centos7-01 ~]# vim /etc/sysconfig/network-scripts/ifcfg-ens37
TYPE=Ethernet
PROXY_METHOD=none
BROWSER_ONLY=no
BOOTPROTO=static
DEFROUTE=yes
IPV4_FAILURE_FATAL=no
IPV6INIT=yes
IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
IPV6_FAILURE_FATAL=no
IPV6_ADDR_GEN_MODE=stable-privacy
NAME=ens37
UUID=c4f0cd67-7c4c-43ea-bc4d-08612727aefa
DEVICE=ens37
ONBOOT=yes
IPADDR=192.168.149.147
NETMASK=255.255.255.0
DNS1=114.114.114.114 3 开启37网卡,并重启网络服务,然后查看ens37网卡的ip地址是否修改成功。
[root@centos7-01 ~]# ifup ens37
[root@centos7-01 ~]# systemctl restart network
[root@centos7-01 ~]# ifconfig
ens33: flags=4163 mtu 1500
inet 192.168.189.128 netmask 255.255.255.0 broadcast 192.168.189.255
inet6 fe80::243c:86d7:d85e:224d prefixlen 64 scopeid 0x20
ether 00:0c:29:15:53:53 txqueuelen 1000 (Ethernet)
RX packets 562 bytes 53931 (52.6 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 468 bytes 62851 (61.3 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
ens33:0: flags=4163 mtu 1500
inet 192.168.189.150 netmask 255.255.255.0 broadcast 192.168.189.255
ether 00:0c:29:15:53:53 txqueuelen 1000 (Ethernet)
ens37: flags=4163 mtu 1500
inet 192.168.149.147 netmask 255.255.255.0 broadcast 192.168.149.255
inet6 fe80::20c:29ff:fe15:535d prefixlen 64 scopeid 0x20
ether 00:0c:29:15:53:5d txqueuelen 1000 (Ethernet)
RX packets 80 bytes 26981 (26.3 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 239 bytes 35802 (34.9 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73 mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10
loop txqueuelen 1 (Local Loopback)
RX packets 78 bytes 6220 (6.0 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 78 bytes 6220 (6.0 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 4 在linux上设置网络地址后,在windows上ping一下147的连通性
5 关闭防火墙
三台机器上都执行执行
- # getenforce
- # setenforce 0 (关闭selinux)
保险起见,修改selinux的配置文件(/etc/selinux/config),把enforcing改成disabled
- #systemctl stop firewalld
- #systemctl disable firewalld
- #systemctl enable iptables.services
- #systemctl start iptables.services
- #iptables -F
- #iptables -nvL
- #service iptables save
分发器dir的操作,
[root@centos7-01 ~]# getenforce
Disabled
[root@centos7-01 ~]# systemctl stop firewalld
[root@centos7-01 ~]# systemctl disable firewalld
[root@centos7-01 ~]# systemctl enable iptables
[root@centos7-01 ~]# systemctl start iptables
[root@centos7-01 ~]# iptables -F
[root@centos7-01 ~]# iptables -nvL
Chain INPUT (policy ACCEPT 22 packets, 1556 bytes)
pkts bytes target prot opt in out source destination
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 14 packets, 1368 bytes)
pkts bytes target prot opt in out source destination
[root@centos7-01 ~]# service iptables save
iptables: Saving firewall rules to /etc/sysconfig/iptables:[ 确定 ] rs1上的操作,
[root@centos7-02 ~]# getenforce
Enforcing
[root@centos7-02 ~]# setenforce 0
[root@centos7-02 ~]# getenforce
Permissive
[root@centos7-02 ~]# vim /etc/selinux/config
[root@centos7-02 ~]# getenforce
Permissive
[root@centos7-02 ~]# systemctl stop firewalld
[root@centos7-02 ~]# systemctl disable firewalld
[root@centos7-02 ~]# systemctl enable iptables.service
Created symlink from /etc/systemd/system/basic.target.wants/iptables.service to /usr/lib/systemd/system/iptables.service.
[root@centos7-02 ~]# systemctl start iptables.service
[root@centos7-02 ~]# iptables -F
[root@centos7-02 ~]# iptables -F
[root@centos7-02 ~]# iptables -nvL
Chain INPUT (policy ACCEPT 13 packets, 952 bytes)
pkts bytes target prot opt in out source destination
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 9 packets, 924 bytes)
pkts bytes target prot opt in out source destination
[root@centos7-02 ~]# service iptables save
iptables: Saving firewall rules to /etc/sysconfig/iptables:[ 确定 ] rs2的操作,
[root@centos7-03 ~]# getenforce
Enforcing
[root@centos7-03 ~]# setenforce 0
[root@centos7-03 ~]# vim /etc/selinux/config
[root@centos7-03 ~]# getenforce
Permissive
[root@centos7-03 ~]# systemctl stop firewalld
[root@centos7-03 ~]# systemctl disable firewalld
[root@centos7-03 ~]# systemctl start iptables.service
[root@centos7-03 ~]# systemctl enable iptables.service
Created symlink from /etc/systemd/system/basic.target.wants/iptables.service to /usr/lib/systemd/system/iptables.service.
[root@centos7-03 ~]# iptables -F
[root@centos7-03 ~]# iptables -nvL
Chain INPUT (policy ACCEPT 12 packets, 860 bytes)
pkts bytes target prot opt in out source destination
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 9 packets, 804 bytes)
pkts bytes target prot opt in out source destination
[root@centos7-03 ~]# service iptables save
iptables: Saving firewall rules to /etc/sysconfig/iptables:[ 确定 ] 第5步的小结:
开启iptables服务是为了,让其调用一个新规则,免得默认的规则影响后续实验效果。
18.10 NAT模式搭建(下)
1 在分发器dir上安装ipvsadm
[root@centos7-01 ~]# yum install -y ipvsadm
2 在dir上编写脚本,vim /usr/local/sbin/lvs_nat.sh//内容如下
#! /bin/bash
# director 服务器上开启路由转发功能
echo 1 > /proc/sys/net/ipv4/ip_forward
# 关闭icmp的重定向
echo 0 > /proc/sys/net/ipv4/conf/all/send_redirects
echo 0 > /proc/sys/net/ipv4/conf/default/send_redirects
# 注意区分网卡名字,两个网卡分别为ens33和ens37
echo 0 > /proc/sys/net/ipv4/conf/ens33/send_redirects
echo 0 > /proc/sys/net/ipv4/conf/ens37/send_redirects
# director 设置nat防火墙
iptables -t nat -F
iptables -t nat -X
iptables -t nat -A POSTROUTING -s 192.168.133.0/24 -j MASQUERADE
# director设置ipvsadm
IPVSADM='/usr/sbin/ipvsadm'
$IPVSADM -C
$IPVSADM -A -t 192.168.149.128:80 -s lc -p 3
$IPVSADM -a -t 192.168.149.128:80 -r 192.168.189.129:80 -m -w 1
$IPVSADM -a -t 192.168.149.128:80 -r 192.168.189.130:80 -m -w 1 参数解释:
ipvsadm是LVS的功能
其中ipvsadm -C选项可以清空规则,防止之前的规则有影响。
ipvsadm -A增加Virtual,-t为TCP,指定dir的IP:port
ipvsadm -s选项指定调度算法,wlc为带权重的最小连接算法。
ipvsadm -p指定超时时间,以s(秒)为单位。在某个时间段内,同一个来源ip可以指定某个rs上
ipvsadm -a 增加rs,
ipvsadm -r 指定rs的IP:port
ipvsadm -m 表示LVS的模式为NAT(masquerad),如果是-g表示LVS模式为DR,
ipvsadm -i 表示LVS模式为IP Tunnel,-w 指定权重。
3 执行脚本
[root@centos7-01 ~]#sh /usr/local/sbin/lvs_nat.sh
4 效果测试
测试前准备:
两台rs上都安装nginx
rs1,
[root@centos7-02 ~]# ps aux |grep nginx
root 877 0.0 0.0 20380 596 ? Ss 10:25 0:00 nginx: master process /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
nobody 882 0.0 0.3 22824 3164 ? S 10:25 0:00 nginx: worker process
nobody 883 0.0 0.3 22824 3164 ? S 10:25 0:02 nginx: worker process
root 3027 0.0 0.0 112720 972 pts/0 S+ 15:00 0:00 grep --color=auto nginx
[root@centos7-02 ~]# netstat -lntp |grep 80
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 877/nginx: master p rs2,
[root@centos7-03 ~]# ps aux |grep nginx
root 890 0.0 0.0 20380 596 ? Ss 10:12 0:00 nginx: master process /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
nobody 892 0.0 0.3 22824 3164 ? S 10:12 0:02 nginx: worker process
nobody 893 0.0 0.3 22824 3164 ? S 10:12 0:00 nginx: worker process
root 3698 0.0 0.0 112720 972 pts/0 R+ 15:00 0:00 grep --color=auto nginx
[root@centos7-03 ~]# netstat -lntp |grep 80
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 890/nginx: master p 修改索引页,便于后续区分
rs1索引页内容追加rs1,
[root@centos7-02 ~]# echo "rs1" >> !$
echo "rs1" >> /data/wwwroot/aaa.com/index.html
[root@centos7-02 ~]# cat !$
cat /data/wwwroot/aaa.com/index.html
rs1 rs2索引页内容追加rs2,
[root@centos7-03 ~]# echo "rs2" >> /data/wwwroot/aaa.com/index.html
[root@centos7-03 ~]# cat !$
cat /data/wwwroot/aaa.com/index.html
rs2 在windows端浏览器访问公网ip 192.168.149.128
访问多次的结果反馈都是rs2,看不出效果,此处应该是脚本的-p参数影响到结果了,把-p参数取消
[root@centos7-01 ~]#vim /usr/local/sbin/lvs_nat.sh
.
.
.
.
.
.
$IPVSADM -C
$IPVSADM -A -t 192.168.149.128:80 -s lc -p 3
$IPVSADM -a -t 192.168.149.128:80 -r 192.168.189.129:80 -m -w 1
$IPVSADM -a -t 192.168.149.128:80 -r 192.168.189.130:80 -m -w 1
重新加载脚本
[root@centos7-01 ~]# !sh
sh /usr/local/sbin/lvs_nat.sh
查看ipvsadm的规则
[root@centos7-01 ~]# ipvsadm -ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 192.168.149.128:80 lc
-> 192.168.189.129:80 Masq 1 0 0
-> 192.168.189.130:80 Masq 1 0 0
因为windows浏览器的浏览器缓存问题,所以在linux端利用curl进行测试
在dir上区分好rs1与rs2的对应ip
[root@centos7-01 ~]# curl 192.168.189.129
rs1
[root@centos7-01 ~]# curl 192.168.189.130
rs2 多次访问外网ip,可以看到rs1与rs2来回切换,实现了均衡访问。
[root@centos7-01 ~]# curl 192.168.149.128
rs2
[root@centos7-01 ~]# curl 192.168.149.128
rs1
[root@centos7-01 ~]# curl 192.168.149.128
rs2
[root@centos7-01 ~]# curl 192.168.149.128
rs1
[root@centos7-01 ~]# curl 192.168.149.128
rs2
[root@centos7-01 ~]# curl 192.168.149.128
rs1
[root@centos7-01 ~]# curl 192.168.149.128 rs2
扩展
lvs 三种模式详解 http://www.it165.net/admin/html/201401/2248.html
lvs几种算法 http://www.aminglinux.com/bbs/thread-7407-1-1.html
关于arp_ignore和 arp_announce http://www.cnblogs.com/lgfeng/archive/2012/10/16/2726308.html
lvs原理相关的 http://blog.csdn.net/pi9nc/article/details/23380589
|