当前位置: 首页 > news >正文

负载均衡层详解part3-lvs

一、集群架构演变详细剖析

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

full-nat

二、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模式术语与配置概述

lvs的工作模式

DR

NAT

TUN:打破网络的限制。

FULL-NAT

image

 

储备专业术语:

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网卡

2、关闭arp相应(针对VIP冲突的解决方案)

四、lvs-dr模式原理-CIP公私网之分

前提:

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构建完之后,客户端访问的IP地址是VIP

五、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 #使用修改生效
```

七、lvs-dr模式四层代理rs部署成功测试

测试前做一件事:

把web服务器的keepaviled_timeout设置为0

有两种方式测试:

方式一:用浏览器访问测试

方式二:用curl命令

 

八、lvs四层代理七层负载均衡架构+部署

透传真实的客户端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;
   
}
 

九、lvs四层代理七层透传客户端真实IP

如果只是四层代理了一个东西,本身就是透传客户端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
 
http://www.wxhsa.cn/company.asp?id=6820

相关文章:

  • 4. MySQL 索引优化实战
  • 算法课第一周作业
  • 线段树懒标记模板
  • 谁在我这位置遗留或丢失了一颗口罩爆珠(好像是桃子味)?
  • python小计划——学生管理系统
  • C++ 并发
  • UML 5章
  • 《微服务事务管理》 - 教程
  • python之socket udp服务器实现
  • kylin SP3安装mysql 8.4.5
  • Unity中是否可以禁用GC
  • 经典SQL语句大全
  • 开源软件图形库
  • IvorySQL 与 deepin 完成兼容性认证,共创开源生态新篇章
  • 在 Nginx 上搭建静态站点
  • 测试
  • 认真做膜你赛
  • 使用GitHub Dork快速发现漏洞:我的第一个Bugcrowd漏洞挖掘实战
  • kylin SP3安装mysql8.0.41
  • DIFY 项目中通过 Makefile 调用 Dockerfile 并采用 sudo make build-web 命令构建 web 镜像的方法和注意事项
  • 代码随想录算法训练营第一天 | 704. 二分查找、27. 移除元素、209.长度最小的子数组
  • 从 MLPerf Storage v2.0 看 AI 训练中的存储性能与扩展能力
  • Revit二次开发 钢筋生成API(二)
  • 创建会计凭证报错:FI/CO接口:待更新的不一致的FI/CO凭证标题数据(转)
  • Uri uri = new Uri(Path); 这行代码的作用
  • Qt函数方法传入参数未使用-警告warning错误error提示解决
  • mysql 性能监控,关键指标解析与优化案例剖析
  • 如何提取docker镜像用于NAS手动安装
  • 百家大型企业共同选择:2025年人力资源管理系统权威推荐榜单
  • 不修改环境变量的基础下使用Java