lvs做四层负载均衡,效率高,性能强大。lvs全称,Linux virtual server,虚拟服务。
提供了很多种模式,常用DR模式(性能最强的一种模式)来做四层负载均衡。
为什么引入lvs?
七层顶不住了,来了读个七层,想要前面有个能把七层负载均衡起来,这种场景一定是要求效率极高,为了配置简单点用haproxy当然也可以,但是压力更大呢可能就需要上性能更强大的负载均衡了,可以买硬件或者用lvs。所以我们用它就是做四层负载均衡来追求效率的。
需要做四层负载均衡的场景有哪些?
1、四层代理七层负载均衡---->放大抗并发能力
2、但凡是用ip+port连过去的集群都可以用四层均衡
例如:代理mysql集群、Redis集群
负载均衡的方案:
硬件(F5、Array):支持四层、七层
特点:性能最强
LVS:支持四层
特点:lvs-dr模式:性能最强,底层是基于mac地址进行转发(mac地址欺骗),请求包经过负载均衡,而响应包直接回给客户端不走负载均衡(真正快的原因)。要求负载均衡与被代理的机器必须在一个局域网内,对网络依赖性强
haproxy:支持四层、七层
特点:在负载均衡层面上比nginx强一些,配置简单,对网络环境的依赖性小
nginx:支持四层、七层
特点:功能特多强大 ,性能够用,配置简单,对网络环境依赖性小
四层负载均衡(haproxy、lvs、硬件负载均衡)----七层负载均衡(nginx、haproxy)---- 多台应用服务器被代理起来----多台数据库机器被代理起来
补充:数据库做集群
前提:
1、必须保证数据一致(要做好主从)
2、而数据库的主从很多种方案
双主:
双主+多从(每个主下挂多个从):
一主多从+MHA(一个主库挂掉后,MHA会帮你从所有从库里选举出一个新的主库,自动帮从库都指向新主库):
写操作---->主库
读操作---->从库
做好主从后。下一件事就是要做:读写分离+负载均衡
lvs---->代理数据库
1、做负载均衡
负载多个主库---->提供一个写地址(lvs机器的地址)
负载多个从库---->提供一个读地址(lvs机器的地址)
2、应用软件
代码需要支持两个地址(读写操作要分开不同的地址)
数据库中间件---->代理数据库
1、中间件会帮我们做好读写分离,即中间件对外只提供一个地址
2、应用软件
代码只需支持一个地址就行(读写操作都用这一个地址)
解决架构问题的一种重要思想:分离(把问题细分出来,抽离成单独的层)
lvs的主要4种工作模式:
dr(效率最高)
nat:网络地址转换,基于ip地址,目标ip转换,分为snat,dnat,
tun
二、lvs构成与关键点
两部分:
ipvs(内核态):负责核心转发工作,直接工作在内核层的netfilter上
ipvsadm(用户态):是一个命令行工具,用来添加ipvs规则(只是在添加规则时用一下ipvsadm工具,转发根本不会用到ipvsadm)
特点:
主要用lvs dr模式
1、dr是通过mac地址欺骗进行转发,而mac地址是二层的概念,那为何将lvs称之为四层负载均衡?
转发是以复杂的过程
数据包来到lvs dr之后,是通过mac地址转发出去,但是在发之前,要计算应该发给谁(负载均衡),计算发给谁要用到负载均衡算法,友谊总负载均衡的算法least_conn ---->链接---->ip+port---->传输层。
2、lvs-dr
要求负载均衡与被代理的机器必须在同一个二层网络里
3、lvs为何快:
1、负责转发工作的ipvs是工作在内核态的,不需要经历频繁的用户态与内核态的切换
2、针对如果用lvs dr模式的话
请求包经过lvs,响应包不走lvs了,而是直接回给客户端
lvs的工作模式
DR
NAT
TUN:打破网络的限制。
CIP:客户端的ip地址
VIP:virtual ip 虚拟的ip地址---->配置在负载均衡、后端被代理的服务器上
只要不是固定死给某一台机器配置的ip地址,那都可以叫vip
DIP:director ip----> 配置在负载均衡上,负责与后端被代理服务器通信的地址
RIP:配置在后端被代理的服务器上
DS:director server,即lvs负载均衡器
BDS:backup director server,备份服务器
RS:real server 指的是被负载均衡代理的服务器。
配置概述:
负载均衡lvs
1、配置地址
负载均衡上的VIP和DIP都需要走网络流量,所以VIP和DIP都需要配置在走网络流量的物理网卡,不能配置在lo上,但是VIP与DIP是可以配置在一块走网络流量的网卡上的。
VIP:配置在走网络流量的物理网卡上
DIP:配置在走网络流量的物理网卡上
2、用ipvsadm添加ipvs的转发规则
被代理的机器rs
1、配置地址
RIP需要接收网络流量,VIP不需要走网络流量
RIP:应该配置在走网络流量的物理网卡上
VIP: 应该配置在不走网络流量的网卡上---->lo网卡
前提:
VIP是私网ip(公网IP是在运营商的网络设备上的)
一个公网IP应该关联/映射到私网IP上,这个关联怎么关联?
如果机器是托管在机房的,找机房(数据中心),如果是云主机(每个机器都有自己的公网IP)
客户端来自于外网是需要跨公网访问到我们的机器VIP,客户端的私有IP得转成客户端的公网IP(CIP),访问到我们集群暴露的公网IP,这个暴露的公网IP需要关联到VIP上。其中换目标IP叫DNAT转换,换源IP叫SNAT转换。
lvs-dr模式的工作流程
客户端:CIP---->VIP
lvs负载均衡接到请求包之后,给了一台rs机器,rs直接回包给客户端是怎么做到的呢?
五、lvs-dr模式原理-核心流程剖析
请求包抵达负载均衡后的处理流程:
1、收到包(源ip---->CIP,目标IP---->VIP)
2、做负载均衡:
1、找出一台机器
根据配置的ipvs规则来选择机器
规则里包含:
1、调度算法
2、转发给哪些机器的ip+port
2、把包发过去
不改源ip和目标ip,而是将包的目标mac地址改成算法调出的那台机器的mac地址
3、目标rs收到包之后
发现目标mac是自己,然后继续解析
解析到ip层(Linux机器判断目标IP是否是自己,会从所有网卡里进行比对,包括lo网卡,如果是就认为该包是自己的,否则就丢弃)
发现目标IP就是配置在自己机器上lo网卡上的vip地址,确定包就是给自己的,就开始回包,给源IP回,源IP就是CIP。
## 六、lvs-dr模式四层代理rs部署准备环境+部署负载均衡+部署real-server
先配置个简单的,lvs作为四层负载均衡是可以直接通过ip+port来负载均衡后面的机器,不一定在中间非要引入一个七层负载均衡,在放大网站的并发量的情况下才会引入一个七层,四层代理七层,七层代理web,这是一种方案,如果是直接代理数据库的话就没必要来一个七层代理数据库,七层是走http协议,直接四层跟要代理的对接就可以了。
针对两种场景:
lvs四层-------->被代理机器
lvs四层-------->七层负载均衡-------->web服务器
代理数据库要基于同步才好做。
针对场景一的部署:
第一步先准备环境(所有机器)
```
setenforce 0
systemctl stop firewalld
配置静态ip
配置时间同步
```
第二步主机规划
```
VIP:192.168.71.200
DIP:192.168.71.115
web01(nginx+静态页面): 192.168.71.112:8080
web02(nginx+静态页面): 192.168.71.113:8080
web03(nginx+静态页面): 192.168.71.114:8080
```
第三步部署好三台web服务器
```
以1台为例:
安装nginx软件
yum install nginx -y
修改配置文件
vim /etc/nginx/nginx.conf
改listen为8080
改好之后重启nginx,并设置成开机启动
systemctl restart nginx
为web准备应用程序:
测试访问:
curl
```
第四步lvs四层负载均衡部署
1、安装并启用lvs
内核模块:ipvs
用户态的工具:ipvsadm
```
# 1、安装ipvsadm等相关工具
yum -y install ipvsadm ipset sysstat conntrack libseccomp
# 2、配置加载
cat > /etc/sysconfig/modules/ipvs.modules <<"EOF"
#!/bin/bash
ipvs_modules="ip_vs ip_vs_lc ip_vs_wlc ip_vs_rr ip_vs_wrr ip_vs_lblc ip_vs_lblcr ip_vs_dh ip_vs_sh ip_vs_fo ip_vs_nq ip_vs_sed ip_vs_ftp nf_conntrack"
for kernel_module in ${ipvs_modules};
do
/sbin/modinfo -F filename ${kernel_module} > /dev/null 2>&1
if [ $? -eq 0 ]; then
/sbin/modprobe ${kernel_module}
fi
done
EOF
chmod 755 /etc/sysconfig/modules/ipvs.modules && bash /etc/sysconfig/modules/ipvs.modules && lsmod | grep ip_vs
```
2、配置VIP、DIP(就是配的静态IP)
```
#1、需要特别注意的是,虚拟ip地址的广播地址是它本身,子网掩码是255.255.255.255。
ifconfig ens36:0 192.168.71.200 broadcast 192.168.71.200 netmask 255.255.255.255 up
#2、添加路由规则
route add -host 192.168.71.200 dev ens36:0
#3、启用系统的包转发功能
echo "1" >/proc/sys/net/ipv4/ip_forward
```
3、添加负载均衡规则
```
# 强调强调强调:LVS本身不支持将请求的目标端口从一个端口转换到另一个端口,所以
# ipvsadm -a -t 192.168.71.200:6666 -r 192.168.71.112:8080 -g # 这种添加方法是错误的,必须端口一致
ipvsadm -C #清除内核虚拟服务器表中的所有记录
ipvsadm -A -t 192.168.71.200:8080 -s rr # -s rr表示采用轮询策略。
ipvsadm -a -t 192.168.71.200:8080 -r 192.168.71.112:8080 -g #添加服务器节点,-g表示指定LVS 的工作模式为直接路由模式
ipvsadm -a -t 192.168.71.200:8080 -r 192.168.71.113:8080 -g #添加服务器节点
ipvsadm -a -t 192.168.71.200:8080 -r 192.168.71.114:8080 -g #添加服务器节点
ipvsadm -Ln #查看节点状态,加个“-n”将以数字形式显示地址、端口信息
```
4、配置rs服务器
1、在本地回环网卡上lo配置vip(不接网络流量,只用于欺骗)
2、关闭arp响应
```
ifconfig lo:0 192.168.71.200 broadcast 192.168.71.200 netmask 255.255.255.255 up
route add -host 192.168.71.200 dev lo:0
#临时修改:
echo "1" >/proc/sys/net/ipv4/conf/lo/arp_ignore
echo "1" >/proc/sys/net/ipv4/conf/all/arp_ignore
echo "2" >/proc/sys/net/ipv4/conf/lo/arp_announce
echo "2" >/proc/sys/net/ipv4/conf/all/arp_announce
#永久生效:
cat >> /etc/sysctl.conf << EOF
net.ipv4.ip_forward=1
net.ipv4.conf.lo.arp_ignore=1
net.ipv4.conf.all.arp_ignore=1
net.ipv4.conf.lo.arp_announce=2
net.ipv4.conf.all.arp_announce=2
EOF
sysctl -p #使用修改生效
```
测试前做一件事:
把web服务器的keepaviled_timeout设置为0
有两种方式测试:
方式一:用浏览器访问测试
透传真实的客户端IP到服务端去,nginx、haproxy都需要开一个协议才能透传,而用lvs就不要,本身是透传的。
LVS四层代理转发至七层负载均衡器,再分发至Web服务器的场景下real-server应该是谁?
应该是七层负载均衡器。
1、环境准备(所有机器)
关selinux、firewalld
配置静态IP
同步时间
2、主机规划
四层负载均衡(lvs-dr)
七层负载均衡(至少两台)
web服务器(至少三台)
# 1、四层
VIP:192.168.71.200
DIP:192.168.71.115
# 2、两台七层
七层01(用nginx做七层负载):192.168.71.116:8081
七层02(用nginx做七层负载):192.168.71.111:8081
# 3、三台web
web01(nginx+静态页面): 192.168.71.112:8080
web02(nginx+静态页面): 192.168.71.113:8080
web03(nginx+静态页面): 192.168.71.114:8080
3、配置三台web服务器
以1台为例:
安装nginx软件
yum install nginx -y
修改配置文件
vim /etc/nginx/nginx.conf
改listen为8080
改好之后重启nginx,并设置成开机启动
systemctl restart nginx
4、配置两台七层负载均衡
以一台为例:
yum install nginx -y
#配置:
events {
worker_connections 1024;
}
http {
upstream web_app_servers {
server 192.168.71.112:8080 weight=1;
server 192.168.71.113:8080 weight=1;
server 192.168.71.114:8080 weight=1;
}
server {
listen 8081; # 强调:这里个的配置直接就监听端口,我们之前的课程中在其末尾加的proxy_protocol一定要去掉
location / {
proxy_pass http://web_app_servers;
}
}
}
5、配置四层负载均衡
安装ipvsadm并加载ipvs模块
# 1、安装ipvsadm等相关工具
yum -y install ipvsadm ipset sysstat conntrack libseccomp
# 2、配置加载
cat > /etc/sysconfig/modules/ipvs.modules <<"EOF"
#!/bin/bash
ipvs_modules="ip_vs ip_vs_lc ip_vs_wlc ip_vs_rr ip_vs_wrr ip_vs_lblc ip_vs_lblcr ip_vs_dh ip_vs_sh ip_vs_fo ip_vs_nq ip_vs_sed ip_vs_ftp nf_conntrack"
for kernel_module in ${ipvs_modules};
do
/sbin/modinfo -F filename ${kernel_module} > /dev/null 2>&1
if [ $? -eq 0 ]; then
/sbin/modprobe ${kernel_module}
fi
done
EOF
chmod 755 /etc/sysconfig/modules/ipvs.modules && bash /etc/sysconfig/modules/ipvs.modules && lsmod | grep ip_vs
配置vip、dip
#1、需要特别注意的是,虚拟ip地址的广播地址是它本身,子网掩码是255.255.255.255。
ifconfig ens36:0 192.168.71.200 broadcast 192.168.71.200 netmask 255.255.255.255 up
#2、添加路由规则
route add -host 192.168.71.200 dev ens36:0
#3、启用系统的包转发功能
echo "1" >/proc/sys/net/ipv4/ip_forward
添加负载均衡规则
ipvsadm -C #清除内核虚拟服务器表中的所有记录
ipvsadm -A -t 192.168.71.200:8081 -s rr # -s rr表示采用轮询策略。
ipvsadm -a -t 192.168.71.200:8081 -r 192.168.71.116:8081 -g #添加服务器节点,-g表示指定LVS 的工作模式为直接路由模式
ipvsadm -a -t 192.168.71.200:8081 -r 192.168.71.111:8081 -g #添加服务器节点
ipvsadm -Ln #查看节点状态,加个“-n”将以数字形式显示地址、端口信息
5、rs配置(在七层负载均衡,而不是web)
在本地回环网卡上配置VIP
ifconfig lo:0 192.168.71.200 broadcast 192.168.71.200 netmask 255.255.255.255 up
route add -host 192.168.71.200 dev lo:0
关闭arp解析
cat >> /etc/sysctl.conf << EOF
net.ipv4.ip_forward=1
net.ipv4.conf.lo.arp_ignore=1
net.ipv4.conf.all.arp_ignore=1
net.ipv4.conf.lo.arp_announce=2
net.ipv4.conf.all.arp_announce=2
EOF
sysctl -p #使用修改生效
6、访问测试
curl命令测试:
[root@web01 ~]# curl http://192.168.71.200:8081/1.txt
--------------------web01111111111111111
[root@web01 ~]# curl http://192.168.71.200:8081/1.txt
--------------------web01111111111111111
[root@web01 ~]# curl http://192.168.71.200:8081/1.txt
-------------web02222222222222222222
[root@web01 ~]# curl http://192.168.71.200:8081/1.txt
-------------web02222222222222222222
[root@web01 ~]# curl http://192.168.71.200:8081/1.txt
---------------------web033333333333333333333333333333333333
[root@web01 ~]# curl http://192.168.71.200:8081/1.txt
---------------------web03333333333333333333333333333333333
浏览器测试:
http {
keepalive_timeout 0;
}
如果只是四层代理了一个东西,本身就是透传客户端IP的,但是四层代理了七层,七层再往下一层发的时候,协议包就不会透传了,要想透传只能取出来加到X-Forwarded-For里。
七层负载均衡 proxy_set_header
vim /etc/nginx/nginx.conf
events {
worker_connections 1024;
}
http {
#keepalive_timeout 0;
upstream web_app_servers {
server 192.168.71.112:8080 weight=1;
server 192.168.71.113:8080 weight=1;
server 192.168.71.114:8080 weight=1;
}
server {
listen 8081;
location / {
proxy_pass http://web_app_servers;
# -------------------》只加上下面这一段即可
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
}
后端web服务器从x_forwarded_for里面取
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"'; # 末尾加个$http_x_forwarded_for