赞
踩
- DNS 实现负载均衡
DNS 实现负载均衡是最基础简单的方式。一个域名通过 DNS 解析到多个 IP,每个 IP 对应不同的服务器实例,这样就完成了流量的调度,虽然没有使用常规的负载均衡器,但也的确完成了简单负载均衡的功能。
- 硬件负载均衡
硬件负载均衡是通过专门的硬件设备来实现负载均衡功能,类似于交换机、路由器,是一个负载均衡专用的网络设备。目前业界典型的硬件负载均衡设备有两款:F5 和 A10。这类设备性能强劲、功能强大,但价格非常昂贵,一般只有 “土豪” 公司才会使用此类设备,普通业务量级的公司一般负担不起,二是业务量没那么大,用这些设备也是浪费。
- 软件负载均衡
软件负载均衡,可以在普通的服务器上运行负载均衡软件,实现负载均衡功能。目前常见的有 Nginx、HAproxy、LVS。 区别:
-Nginx :是 7 层负载均衡,支持 HTTP、E-mail 协议,貌似也支持 4 层负载均衡了。
-HAproxy :是 7 层负载均衡软件,支持 7 层规则的设置,性能也很不错。OpenStack 默认使用的负载均衡软件就是 HAproxy
-LVS :是纯 4 层的负载均衡,运行在内核态,性能是软件负载均衡中最高的,因为是在四层,所以也更通用一些。
LB集群的架构和原理很简单,就是当用户的请求过来时,会直接分发到Director Server上,然后它把用户的请求根据设置好的调度算法,智能均衡地分发到后端真正服务器(real server)上。为了避免不同机器上用户请求得到的数据不一样,需要用到了共享存储,这样保证所有用户请求的数据是一样的。
LVS是 Linux Virtual Server 的简称,也就是Linux虚拟服务器。这是一个由章文嵩博士发起的一个开源项目, 现在 LVS 已经是 Linux 内核标准的一部分。使用 LVS 可以达到的技术目标是:通过 LVS 达到的负载均衡技术和 Linux 操作系统实现一个高性能高可用的 Linux 服务器集群,它具有良好的可靠性、可扩展性和可操作性。从而以低廉的成本实现最优的性能。LVS 是一个实现负载均衡集群的开源软件项目,LVS架构从逻辑上可分为调度层、Server集群层和共享存储。
1.当用户向负载均衡调度器(Director Server)发起请求,调度器将请求发往至内核空间
2.PREROUTING链首先会接收到用户请求,判断目标IP确定是本机IP,将数据包发往INPUT链
3.IPVS是工作在INPUT链上的,当用户请求到达INPUT时,IPVS会将用户请求和自己已定义好的集群服务进行比对,如果用户请求的就是定义的集群服务,那么此时IPVS会强行修改数据包里的目标IP地址及端口,并将新的数据包发往POSTROUTING链
4.POSTROUTING链接收数据包后发现目标IP地址刚好是自己的后端服务器,那么此时通过选路,将数据包最终发送给后端的服务器
- 前端:负载均衡层
-由一台或多台负载调度器构成
- 中间:服务器群组层
-由一组实际运行应用服务的服务器组成
- 底端:数据共享存储层
-提供共享存储空间的存储区域
DS: Director Server。指的是前端负载均衡器节点。
RS: Real Server。后端真实的工作服务器。
CIP: Client IP,表示的是客户端 IP 地址。
VIP: Virtual IP,表示负载均衡对外提供访问的 IP 地址,一般负载均衡 IP 都会通过 Virtual IP 实现高可用。
RIP: RealServer IP,表示负载均衡后端的真实服务器 IP 地址。
DIP: Director IP,表示负载均衡与后端服务器通信的 IP 地址。
LVS/NAT:网络地址转换
-通过网络地址转换实现的虚拟服务器
-大并发访问时,调度器的性能成为瓶颈
-LVS/DR:直接路由
-直接使用路由技术实现虚拟服务器
-节点服务器需要配置VIP,注意MAC地址广播
-LVS/TUN:IP隧道
-通过隧道方式实现虚拟服务器
更详细原理可参考博客:https://blog.csdn.net/liwei0526vip/article/details/103104483
1.网络地址转换(LVS-NAT)
1.当用户请求到达Director Server,此时请求的数据报文会先到内核空间的PREROUTING链。 此时报文的源IP为CIP,目标IP为VIP 。2.PREROUTING检查发现数据包的目标IP是本机,将数据包送至INPUT链3.IPVS比对数据包请求的服务是否为集群服务,若是则将请求报文中的源MAC地址[CIP]修改为DIP的MAC地址,将目标MAC地址[VIP]修改RIP的MAC地址,然后将数据包发至POSTROUTING链[LVS]。 此时的源IP和目的IP均未修改,仅修改了源MAC地址为DIP的MAC地址,目标MAC地址为RIP的MAC地址4.由于DS和RS在同一个网络中,所以是通过二层来传输。POSTROUTING链检查目标MAC地址为RIP的MAC地址[ARP广播],那么此时数据包将会发至Real Server。5.RS发现请求报文的MAC地址是自己的MAC地址,就接收此报文。处理完成之后,将响应报文通过自己的lo接口传送给eth0网卡然后向外发出[ARP广播]。此时的源IP地址为VIP,目标IP为CIP. 注意: 如果没有给RS设置外网IP,RS将ARP广播查找CIP,内网没有就提交给网关,网关直接外网发送出去,会有可能提高网关压力6.响应报文最终送达至客户端
2.直接路由(LVS-DR)
1.当用户请求到达Director Server,此时请求的数据报文会先到内核空间的PREROUTING链。 此时报文的源IP为CIP,目标IP为VIP 。2.PREROUTING检查发现数据包的目标IP是本机,将数据包送至INPUT链3.IPVS比对数据包请求的服务是否为集群服务,若是,在请求报文的首部再次封装一层IP报文,封装源IP为为DIP,目标IP为RIP。然后发至POSTROUTING链。 此时源IP为DIP,目标IP为RIP ④、POSTROUTING链根据最新封装的IP报文,将数据包发至RS(因为在外层封装多了一层IP首部,所以可以理解为此时通过隧道传输)。 此时源IP为DIP,目标IP为RIP4.RS接收到报文后发现是自己的IP地址,就将报文接收下来,拆除掉最外层的IP后,会发现里面还有一层IP首部,而且目标是自己的lo接口VIP,那么此时RS开始处理此请求,处理完成之后,通过lo接口送给eth0网卡,然后向外传递。 此时的源IP地址为VIP,目标IP为CIP5.响应报文最终送达至客户端
特点: 多了一个Mac地址,作用是让真实服务器可以找到客户端,直接发送响应报文,并且整个过程的客户端IP(CIP)和负载均衡器的IP都没有改变,只是Mac地址变了,目的是让客户端知道,你发送请求的报文,和响应你报文的是一个人。
3.IP隧道(LVS-TUN)
1.当用户请求到达Director Server,此时请求的数据报文会先到内核空间的PREROUTING链。 此时报文的源IP为CIP,目标IP为VIP 。2.PREROUTING检查发现数据包的目标IP是本机,将数据包送至INPUT链3.IPVS比对数据包请求的服务是否为集群服务,若是,在请求报文的首部再次封装一层IP报文,封装源IP为为DIP,目标IP为RIP。然后发至POSTROUTING链。 此时源IP为DIP,目标IP为RIP ④、POSTROUTING链根据最新封装的IP报文,将数据包发至RS(因为在外层封装多了一层IP首部,所以可以理解为此时通过隧道传输)。 此时源IP为DIP,目标IP为RIP4.RS接收到报文后发现是自己的IP地址,就将报文接收下来,拆除掉最外层的IP后,会发现里面还有一层IP首部,而且目标是自己的lo接口VIP,那么此时RS开始处理此请求,处理完成之后,通过lo接口送给eth0网卡,然后向外传递。 此时的源IP地址为VIP,目标IP为CIP5.响应报文最终送达至客户端
ipvsadm -A 创建虚拟服务器 ipvsadm -E 修改虚拟服务器 ipvsadm -D 删除虚拟服务器 ipvsadm -t 设置集群地址(VIP,Virtual IP) ipvsadm -s 指定集群算法 ----> rr(轮询)、wrr(加权轮询)、lc(最少连接)、wlc(加权最少连接)、sh(ip_hash) ipvsadm -a 添加真实服务器 ipvsadm -e 修改真实服务器 ipvsadm -d 删除真实服务器 ipvsadm -r 指定真实服务器的地址 ipvsadm -w 为节点服务器设置权重,默认为1 ipvsadm -C 清空所有 ipvsadm -L 查看LVS规则表 ---> 一般跟n一起用,以数字形式输出(-Ln) ipvsadm -m 使用NAT模式 ipvsadm -g 使用DR模式 ipvsadm -i 使用TUN模式
NAT模式特性
RS应该使用私有地址,RS的网关必须指向DIP(调度器IP)DIP和RIP必须在同一个网段内,请求和响应报文都需要经过Director Server,高负载场景中,Director Server易成为性能瓶颈支持端口映射RS可以使用任意操作系统缺陷:对Director Server压力会比较大,请求和响应都需经过director server
环境介绍
客户端:192.168.4.132 (4网段充当外网)
负载均衡服务器: ens37:192.168.4.133 (4网段充当外网) ens33:192.168.2.130(test3)
后端服务器1:192.168.2.128(localhost)网关:192.168.2.130
后端服务器2:192.168.2.129(test2)网关:192.168.2.130
内核版本:3.10.0-862.el7.x86_64
系统版本:CentOS 7.5
注意:
1.两台后端服务器必须配置网关地址,且网关地址都要指定为调度服务器的内网地址。(即:192.168.2.130)
2.LVS无论NAT及DR模式,均要求LVS server(调度器)和Real server在同一个网段内,NAT需要把LVS server(调度器)当作各个Real server的默认网关,
一、基础环境配置
1.两台后端服务器128/129分别安装Nginx
[root@localhost ~]# wget http://nginx.org/download/nginx-1.16.1.tar.gz[root@localhost ~]# yum -y install gcc pcre-devel openssl-devel[root@localhost ~]# useradd -s /sbin/nologin nginx //创建禁止登陆解释器的用户(为了安全)[root@localhost ~]# id nginxuid=1001(nginx) gid=1001(nginx) 组=1001(nginx)[root@localhost ~]# tar -xf nginx-1.16.1.tar.gz[root@localhost ~]# cd nginx-1.16.1[root@localhost nginx-1.16.1]# ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_ssl_module --prefix=/usr/local/nginx //指定安装路径 --user=nginx //指定用户 --group=nginx //指定组 --with-http_ssl_module //安装ssl模块,开启其中的SSL加密功能(需要什么模块就安装什么模块) ...... ...... nginx modules path: "/usr/local/nginx/modules" nginx configuration prefix: "/usr/local/nginx/conf" nginx configuration file: "/usr/local/nginx/conf/nginx.conf" nginx pid file: "/usr/local/nginx/logs/nginx.pid" nginx error log file: "/usr/local/nginx/logs/error.log" nginx http access log file: "/usr/local/nginx/logs/access.log" nginx http client request body temporary files: "client_body_temp" nginx http proxy temporary files: "proxy_temp" nginx http fastcgi temporary files: "fastcgi_temp" nginx http uwsgi temporary files: "uwsgi_temp" nginx http scgi temporary files: "scgi_temp"[root@localhost nginx-1.16.1]# make && make install //编译并且安装...... '/usr/local/nginx/conf/scgi_params.default'test -f '/usr/local/nginx/conf/nginx.conf' || cp conf/nginx.conf '/usr/local/nginx/conf/nginx.conf'cp conf/nginx.conf '/usr/local/nginx/conf/nginx.conf.default'test -d '/usr/local/nginx/logs' || mkdir -p '/usr/local/nginx/logs'test -d '/usr/local/nginx/logs' || mkdir -p '/usr/local/nginx/logs'test -d '/usr/local/nginx/html' || cp -R html '/usr/local/nginx'test -d '/usr/local/nginx/logs' || mkdir -p '/usr/local/nginx/logs'make[1]: 离开目录“/root/nginx-1.16.1”[root@localhost ~]# /usr/local/nginx/sbin/nginx -Vnginx version: nginx/1.16.1built by gcc 4.8.5 20150623 (Red Hat 4.8.5-39) (GCC)built with OpenSSL 1.0.2k-fips 26 Jan 2017TLS SNI support enabledconfigure arguments: --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_ssl_module[root@test2 ~]# /usr/local/nginx/sbin/nginx -Vnginx version: nginx/1.16.1built by gcc 4.8.5 20150623 (Red Hat 4.8.5-39) (GCC)built with OpenSSL 1.0.2k-fips 26 Jan 2017TLS SNI support enabledconfigure arguments: --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_ssl_module
2.创建测试页面
[root@localhost ~]# echo "I am 192.168.2.128" > /usr/local/nginx/html/index.html[root@test2 ~]# echo "I am 192.168.2.129" > /usr/local/nginx/html/index.html
3.启动Nginx
[root@localhost nginx-1.16.1]# /usr/local/nginx/sbin/nginx [root@localhost nginx-1.16.1]# netstat -antulp | grep :80tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 6079/nginx: master或者[root@localhost nginx-1.16.1]# netstat -antulp | grep nginxtcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 6079/nginx: master
3.关闭防火墙与selinux
两台后端服务器都需要操作。
[root@test2 ~]# systmctl stop firewalld[root@test2 ~]# setenforce 0[root@test2 ~]# getenforceDisabled[root@test2 ~]# vim /etc/sysconfig/selinux //永久关闭selinuxSELINUX=disabled
二、部署LVS-NAT模式调度器
1.确认调度器的路由转发功能是否开启(必须开启)
[root@test3 ~]# cat /proc/sys/net/ipv4/ip_forward1若没有开启,则:[root@test3 ~]# echo 1 > /proc/sys/net/ipv4/ip_forward[root@test3 ~]# echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf 修改配置文件,设置路由转发永久规则
2.调度器再添加一张网卡
[root@test3 ~]# ifconfigens33: flags=4163 mtu 1500 inet 192.168.2.130 netmask 255.255.255.0 broadcast 192.168.2.255 inet6 fe80::1e8a:7d4a:beb0:fd6c prefixlen 64 scopeid 0x20 inet6 fe80::2c27:a02c:731a:2219 prefixlen 64 scopeid 0x20 ether 00:0c:29:53:71:a2 txqueuelen 1000 (Ethernet) RX packets 66342 bytes 15217275 (14.5 MiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 13974 bytes 1254299 (1.1 MiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0lo: flags=73 mtu 65536 inet 127.0.0.1 netmask 255.0.0.0 inet6 ::1 prefixlen 128 scopeid 0x10 loop txqueuelen 1000 (Local Loopback) RX packets 48 bytes 3781 (3.6 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 48 bytes 3781 (3.6 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions
[root@test3 ~]# ifconfigens33: flags=4163 mtu 1500 inet 192.168.2.130 netmask 255.255.255.0 broadcast 192.168.2.255 inet6 fe80::1e8a:7d4a:beb0:fd6c prefixlen 64 scopeid 0x20 inet6 fe80::2c27:a02c:731a:2219 prefixlen 64 scopeid 0x20 ether 00:0c:29:53:71:a2 txqueuelen 1000 (Ethernet) RX packets 66416 bytes 15223172 (14.5 MiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 13996 bytes 1256226 (1.1 MiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0ens37: flags=4163 mtu 1500 inet 192.168.4.133 netmask 255.255.255.0 broadcast 192.168.4.255 inet6 fe80::7e5e:fea8:ba8e:ee18 prefixlen 64 scopeid 0x20 ether 00:0c:29:53:71:ac txqueuelen 1000 (Ethernet) RX packets 5018 bytes 385651 (376.6 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 2524 bytes 269779 (263.4 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0lo: flags=73 mtu 65536 inet 127.0.0.1 netmask 255.0.0.0 inet6 ::1 prefixlen 128 scopeid 0x10 loop txqueuelen 1000 (Local Loopback) RX packets 48 bytes 3781 (3.6 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 48 bytes 3781 (3.6 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
3.两台后端服务器配置网关地址
[root@localhost ~]# cat /etc/sysconfig/network-scripts/ifcfg-ens37TYPE=EthernetPROXY_METHOD=noneBROWSER_ONLY=noBOOTPROTO="static"DEFROUTE=yesIPV4_FAILURE_FATAL=noIPV6INIT=yesIPV6_AUTOCONF=yesIPV6_DEFROUTE=yesIPV6_FAILURE_FATAL=noIPV6_ADDR_GEN_MODE=stable-privacyNAME=ens37UUID=2d899e46-1b9d-40d5-9fed-8a88cb181d79DEVICE=ens37ONBOOT=yesIPADDR="192.168.2.128"PREFIX="24"GATEWAY="192.168.2.130" //网关地址配置为调度器的内网地址DNS1="8.8.8.8"[root@test2 ~]# cat /etc/sysconfig/network-scripts/ifcfg-ens33TYPE=EthernetPROXY_METHOD=noneBROWSER_ONLY=noBOOTPROTO="static"DEFROUTE=yesIPV4_FAILURE_FATAL=noIPV6INIT=yesIPV6_AUTOCONF=yesIPV6_DEFROUTE=yesIPV6_FAILURE_FATAL=noIPV6_ADDR_GEN_MODE=stable-privacyNAME=ens33UUID=2d899e46-1b9d-40d5-9fed-8a88cb181d65DEVICE=ens33ONBOOT=yesIPADDR="192.168.2.129"PREFIX="24"GATEWAY="192.168.2.130" //网关地址配置为调度器的内网地址DNS1="8.8.8.8"[root@localhost ~]# systemctl restart network[root@test2 ~]# systemctl restart network
以下步骤在调度器上操作
||
4.创建集群调度服务器
[root@test3 ~]# yum -y install ipvsadm[root@test3 ~]# ipvsadm -A -t 192.168.4.133:80 -s wrr 创建虚拟集群服务器并设置调度算法为加权轮询wrr
5.添加真实服务器组
[root@test3 ~]# ipvsadm -a -t 192.168.4.133:80 -r 192.168.2.128 -w 1 -m[root@test3 ~]# ipvsadm -a -t 192.168.4.133:80 -r 192.168.2.129 -w 2 -m
4.查看规则列表,并保存规则
[root@test3 ~]# ipvsadm -LnIP Virtual Server version 1.2.1 (size=4096)Prot LocalAddress:Port Scheduler Flags -> RemoteAddress:Port Forward Weight ActiveConn InActConnTCP 192.168.4.133:80 wrr -> 192.168.2.128:80 Masq 1 0 0 -> 192.168.2.129:80 Masq 2 0 0[root@test3 ~]# ipvsadm-save -n > /etc/sysconfig/ipvsadm-config
三、客户端上测试
可以看到每当我们执行一次curl命令(相当于刷新一次网页),调度器都会根据权重值轮询到不同的后端真实服务器。
1.停掉后端129服务器nginx服务
[root@test2 ~]# /usr/local/nginx/sbin/nginx -s stop
2.使用客户端访问,查看轮询结果
3.再停掉后端128服务器nginx服务器
[root@localhost ~]# /usr/local/nginx/sbin/nginx -s stop
4.再使用客户端访问,查看轮询结果
可以看到负载均衡调度服务器并不会顶替工作。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。