lvs/linux虚拟服务器.md
2025-04-05 23:20:36 +08:00

18 KiB
Raw Blame History

LVS


LVS 简介

1. 简介

LVSLinux Virtual Server即Linux虚拟服务器是由章文嵩博士主导的开源负载均衡项目目前LVS已经被集成到Linux内核模块中。LVS基于内核网络层工作有着超强的并发处理能力单台LVS可以承受上万的并发连接。LVS是基于4层的负载均衡软件因此LVS在所有负载均衡软件中性能最强稳定性最高消耗CPU和内存少。LVS是工作在4层所以它可以对应用层的所有协议作负载均衡包括http、DNS、ftp等。

2. LVS 分层及组成

LVS 负载均衡分为3层

  • 第一层Load Balancer它负责负载均衡有一台或多台调度器是整个集群的总代理。它有两个网卡一个网卡面向访问网站的客户端一个网卡面向集群内部。负责将客户的请求发送到服务器上执行。
  • 第二层Server Array这一层是真正执行客户请求的服务器可以当做WEB服务器。
  • 第三层Shared Storage它为服务器池提供一个共享的存储区这样很容易使得服务器池拥有相同的内容提供相同的服务。

3. 工作原理

  1. 用户请求的数据包到达负载均衡器的内核空间首先经过的是内核的PREROUTING链
  2. 因为请求的数据包的目的地址一定是本机然后将数据包送到INPUT链
  3. ipvs就工作在INPUT链上ipvs利用ipvsadm定义的规则工作ipvs对数据包进行检查如果目的地址和端口不在规则里边则将数据包送往用户空间
  4. 如果目的地址和端口在规则里边则将数据包的目的地址和端口修改为后端真实服务器然后将修改后的数据包送往POSTROUTING链
  5. 最后经过POSTROUTING链将数据包转发给后端服务器。

二:集群 Cluster

1. 概念

集群是为了解决某个特定问题将多台计算机组合起来形成的单个系统。

2. 常见类型

  • LBLoadBalancing负载均衡由多个主机组成每个主机只承担一部分访问
  • HAHigh Availiablity高可用
    1. MTBF:Mean Time Between Failure 平均无故障时间,正常时间
    2. MTTR:Mean Time To Restoration repair平均恢复前时间故障时间 A=MTBF/MTBF+MTTR
    3. SLAService level agreement服务等级协议
    4. SLA是在一定开销下为保障服务的性能和可用性服 务提供商与用户间定义的一种双方认可的协定。
  • HPCHigh-performance computing高性能计算

3. LVS 集群类型

  • **lvs-nat**修改请求报文的目标IP,多目标的DNAT
  • **lvs-dr**操纵新封装的MAC地址
  • **lvs-tun**再远请求IP报文之外新加一个IP首部
  • **lvs-fullnat**修改请求报文的源和目标IP

三:分布式

1. 概念

分布式是将一个业务被拆成多个子业务或将本身就是不同的业务部署在多台服务器上。在分布式中,每一台服务器实现的功能是有差别的,数据和代码也是不一样的,分布式每台服务器功能加起来,才是完整的业务。

2. 集群和分布式的区别

集群是将同一个业务部署在多台服务器上,每一台服务器实现的功能没有差别,数据和代码都是一样的;分布式中每一台服务器实现的功能是有差别的,数据和代码也是不一样的,分布式每台服务器功能加起来,才是完整的业务。

分布式是以缩短单个任务的执行时间来提升效率的,而集群则是通过提高单位时间内执行的任务数来提升效率。

LVS 运行原理

1. nat 模式

概念

本质是多目标IPDNAT,通过将请求报文中的目标地址和目标端口修改为某挑出的RSRIPPORT实现转发。

RIPDIP应在同一个IP网络,且应使用私网地址;RS的网关要指向DIP

请求报文和响应报文都必须经由Director转发Director易于成为系统瓶颈

支持端口映射,可修改请求报文的目标`PORT`。

VS必须是Linux系统,RS可以是任意OS系统。

数据逻辑

  1. 客户端发送访问请求请求数据包中含有请求来源cip访问目标地址VIP访问目标端口 9000port
  2. VS服务器接收到访问请求做DNAT把请求数据包中的目的地由VIP换成RS的RIP和相应端口
  3. RS1相应请求发送响应数据包包中的相应保温为数据来源RIP1响应目标CIP相应端口 9000port
  4. VS服务器接收到响应数据包改变包中的数据来源RIP1-->VIP,响应目标端口9000-->80
  5. VS服务器把修改过报文的响应数据包回传给客户端
  6. lvs的NAT模式接收和返回客户端数据包时都要经过lvs的调度机所以lvs的调度机容易阻塞

2. DR 模式

概念

DRDirect Routing直接路由LVS默认模式,应用最广泛,通过为请求报文重新封装一个MAC首部进行 转发,源MACDIP所在的接口的MAC,目标MAC是某挑选出的RSRIP所在接口的MAC地址;源IP/PORT,以及目标IP/PORT均保持不变。

DR模式数据传输过程

  1. 客户端发送数据帧给vs调度主机帧中内容为客户端IP+客户端的MAC+VIP+VIPMAC
  2. VS调度主机接收到数据帧后把帧中的VIPMAC该为RS1MAC,此时帧中的数据为客户端IP+客户端 的MAC+VIP+RS1MAC
  3. RS1得到2中的数据包做出响应回传数据包数据包中的内容为VIP+RS1MAC+客户端IP+客户端IPMAC

DR模式的特点

  1. Director和各RS都配置有VIP
  2. 确保前端路由器将目标IPVIP的请求报文发往Director
  3. 在前端网关做静态绑定VIPDirectorMAC地址
  4. RSRIP可以使用私网地址,也可以是公网地址;RIPDIP在同一IP网络;
  5. RIP的网关不能指向DIP,以确保响应报文不会经由Director
  6. RSDirector要在同一个物理网络
  7. 请求报文要经由Director,但响应报文不经由Director,而由RS直接发往Client
  8. 不支持端口映射(端口不能修败)
  9. RS可使用大多数OS系统

3. TUN 模式

概念

转发方式不修改请求报文的IP首部源IP为CIP目标IP为VIP而在原IP报文之外再封装一个IP首部 源IP是DIP目标IP是RIP将报文发往挑选出的目标RSRS直接响应给客户端源IP是VIP目标IP是CIP

TUN 模式传输数据过程

  1. 客户端发送请求数据包包内有源IP+vip+dport
  2. 到达vs调度器后对客户端发送过来的数据包重新封装添加IP报文头新添加的IP报文头中包含TUNSRCIP(DIP)+TUNDESTIP(RSIP1)并发送到RS1
  3. RS收到VS调度器发送过来的数据包做出响应生成的响应报文中包含SRCIP(VIP)+DSTIPCIP+port响应数据包通过网络直接回传给client

TUN 模式特点

  1. DIP, VIP, RIP都应该是公网地址
  2. RS的网关一般不能指向DIP
  3. 请求报文要经由Director但响应不能经由Director
  4. 不支持端口映射
  5. RS的OS须支持隧道功能

4. LVS 类型总结

NAT模式 TUN模式 DR模式
RS操作系统 不限 支持隧道 禁用arp
调度器和服务器网络 可跨网络 可跨网络 不可跨网络
调度服务器数量
RS服务器网关 指向调度器DIP 指向路由 指向路由
  • **lvs-nat与lvs-fullnat**请求和响应报文都经由Director
  • lvs-natRIP的网关要指向DIP
  • lvs-fullnatRIPDIP未必在同一IP网络,但要能通信
  • **lvs-dr与lvs-tun**请求报文要经由Director,但响应报文由RS直接发往Client
  • **lvs-dr**通过封装新的MAC首部实现,通过MAC网络转发
  • **lvs-tun**通过在原IP报文外封装新IP头实现转发,支持远距离通信

LVS 调度算法

1. 调度算法类型

**ipvs scheduler**根据其调度时是否考虑各RS当前的负载状态被分为两种:静态方法和动态方法。

  • 静态方法:仅根据算法本身进行调度,不考虑RS的负载情况
  • 动态方法:主要根据每RS当前的负载状态及调度算法进行调度Overhead=value较小的RS将被调度

2. 静态调度算法

  1. RRroundrobin 轮询 RS分别被调度当RS配置有差别时不推荐
  2. WRRWeighted RR加权轮询根据RS的配置进行加权调度性能差的RS被调度的次数少
  3. SHSource Hashing实现session sticky源IP地址hash将来自于同一个IP地址的请求始终发往 第一次挑中的RS从而实现会话绑定
  4. DHDestination Hashing目标地址哈希第一次轮询调度至RS后续将发往同一个目标地址的请 求始终转发至第一次挑中的RS典型使用场景是正向代理缓存场景中的负载均衡宽带运营商

3. 动态调度算法

主要根据RS当前的负载状态及调度算法进行调度Overhead=value较小的RS会被调度。

  1. LCleast connections最少链接发适用于长连接应用Overhead负载值=activeconns活动链接数 x 256+inactiveconns非活 动链接数)
  2. WLCWeighted LC权重最少链接 默认调度方法Overhead=(activeconns x256+inactiveconns)/weight
  3. SEDShortest Expection Delay,初始连接高权重优先Overhead=(activeconns+1+inactiveconns) x 256/weight但是当node1的权重为1node2的权重为10经过运算前几次的调度都会被node2承接
  4. NQNever Queue第一轮均匀分配后续SED
  5. LBLCLocality-Based LC动态的DH算法使用场景根据负载状态实现正向代理
  6. LBLCRLBLC with Replication带复制功能的LBLC解决LBLC负载不均衡问题从负载重的复制 到负载轻的RS

4. 新增调度算法

  1. FO(Weighted Fai Over)调度算法常用作灰度发布。在FO算法中遍历虚拟服务所关联的真实服务器链表找到还未过载的且权重最高的真实服务器进行调度当服务器承接大量链接我们可以对此服务器进行过载标记那么vs调度器就不会把链接调度到有过载标记的主机中。
  2. OVF(Overflow-connection)调度算法:基于真实服务器的活动连接数量和权重值实现。将新连接调度到权重值最高的真实服务器,直到其活动 连接数量超过权重值,之后调度到下一个权重值最高的真实服务器,在此OVF算法中遍历虚拟服务相关 联的真实服务器链表,找到权重值最高的可用真实服务器。一个可用的真实服务器需要同时满足以下条件:
    1. 未过载(未设置IP_VS_DEST_F OVERLOAD标志)
    2. 真实服务器当前的活动连接数量小于其权重值
    3. 其权重值不为零

LVS 命令

1. LVS 软件相关信息

程序包ipvsadm Unit File: ipvsadm.service

主程序:/usr/sbin/ipvsadm

规则保存工具:/usr/sbin/ipvsadm-save

规则重载工具:/usr/sbin/ipvsadm-restore

配置文件:/etc/sysconfig/ipvsadm-config ipvs

调度规则文件:/etc/sysconfig/ipvsadm

2. ipvsadm 命令

语法格式:

ipvsadm -A|E -t|u|f service-address [-s scheduler] [-p [timeout]]

参数:
-A     # 添加
-E     # 修改
-t     # tcp服务
-u     # udp服务
-s     # 指定调度算法默认为WLC
-p     # 设置持久连接超时持久连接可以理解为在同一个时间段同一个来源的请求调度到同一Realserver
-f     # firewall mask 火墙标记,是一个数字



ipvsadm -a|e -t|u|f service-address -r realserver-address [-g|i|m] [-w weight]
参数:
-a     # 添加realserver
-e     # 更改realserver
-t     # tcp协议
-u     # udp协议
-f     # 火墙标签
-r     # realserver地址
-g     # 直连路由模式
-i     # ipip隧道模式
-m     # nat模式
-w     # 设定权重
-Z     # 清空计数器
-C     # 清空lvs策略
-L     # 查看lvs策略
-n     # 不做解析
--rate :输出速率信息

七:实战

1. nat 模式

实验环境:

主机名 ip vip 角色
director server nat192.168.159.131 仅主机192.168.137.131 调度器
real-server1 nat192.168.159.132 null 真实服务器
real-server2 nat192.168.159.133 null 真实服务器
client 仅主机192.168.137.2 null 测试机

Director Server

启动IP转发

[root@director ~]# echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
[root@director ~]# sysctl -p

配置VIP

[root@director ~]# nmcli connection modify 有线连接\ 1 ipv4.method manual ipv4.addresses 192.168.137.131/24 ipv4.gateway 192.168.137.1 ipv4.dns 192.168.137.1 autoconnect yes
[root@director ~]# nmcli con up 有线连接\ 1

配置ip

[root@director ~]# vim /etc/sysconfig/network-scripts/ifcfg-ens33
BOOTPROTO="static"
ONBOOT="yes"
IPADDR=192.168.159.131
GATEWAY=192.168.159.2
NETMASK=255.255.255.0
DNS1=192.168.159.2
[root@director ~]# systemctl restart network

配置LVS规则

# 安装ipvsadm
[root@director ~]# yum install ipvsadm -y

# 创建虚拟服务
[root@director ~]# ipvsadm -A -t 192.168.137.131:80 -s rr

# 添加Real Server节点-m表示NAT模式
[root@director ~]# ipvsadm -a -t 192.168.137.131:80 -r 192.168.159.132:80 -m
[root@director ~]# ipvsadm -a -t 192.168.137.131:80 -r 192.168.159.133:80 -m

# 保存规则
[root@director ~]# ipvsadm-save > /etc/sysconfig/ipvsadm
[root@director ~]# systemctl restart ipvsadm

Real Server 配置

配置IP

[root@real-server1/2 ~]# vim /etc/sysconfig/network-scripts/ifcfg-ens33
BOOTPROTO="static"
ONBOOT="yes"
IPADDR=192.168.159.132/133
GATEWAY=192.168.159.131    // ds 的DIP
NETMASK=255.255.255.0
DNS1=192.168.159.2

配置web服务

[root@real-server1/2 ~]# yum -y install httpd
[root@real-server1/2 ~]# systemctl start httpd
[root@real-server1/2 ~]# systemctl enable httpd

[root@real-server1/2 ~]# echo "Real Server1" > /var/www/html/index.html
[root@real-server2 ~]# echo "Real Server2" > /var/www/html/index.html

[root@real-server1/2 ~]# systemctl restart httpd

Client 配置

配置IP

[root@client ~]# nmcli connection modify ens33 ipv4.method manual ipv4.addresses 192.168.137.132/24 ipv4.gateway 192.168.137.1 ipv4.dns 192.168.137.1 autoconnect yes
[root@client ~]# nmcli con up ens33

测试

[root@client ~]# for i in {1..10}; do
> curl http://192.168.137.131:80
> done
real-server1
real-server2
real-server1
real-server2
real-server1
real-server2
real-server1
real-server2
real-server1
real-server2

2. dr 模式

实验环境

主机名 ip vip 角色
director server nat192.168.159.10 仅主机192.168.137.100 调度器
real-server1 nat192.168.159.21 lo:0192.168.137.100 真实服务器
real-server2 nat192.168.159.22 lo:0192.168.137.100 真实服务器
client nat192.168.159.30 null 测试机

Director Server

配置IP

[root@director ~]# vim /etc/sysconfig/network-scripts/ifcfg-ens33
BOOTPROTO="static"
ONBOOT="yes"
IPADDR=192.168.159.131
GATEWAY=192.168.159.2
NETMASK=255.255.255.0
DNS1=192.168.159.2
[root@director ~]# systemctl restart network

配置VIP

[root@director ~]# nmcli connection modify 有线连接\ 1 ipv4.method manual ipv4.addresses 192.168.159.100/24 ipv4.gateway 192.168.159.2 ipv4.dns 192.168.159.2 autoconnect yes
[root@director ~]# nmcli con up 有线连接\ 1

配置LVS规则

# 安装ipvsadm
[root@director ~]# yum install ipvsadm -y

# 创建虚拟服务
[root@director ~]# ipvsadm -A -t 192.168.159.100:80 -s rr

# 添加Real Server节点-g表示dr模式
[root@director ~]# ipvsadm -a -t 192.168.159.100:80 -r 192.168.159.21:80 -g
[root@director ~]# ipvsadm -a -t 192.168.159.100:80 -r 192.168.159.22:80 -g

# 保存规则
[root@director ~]# ipvsadm-save > /etc/sysconfig/ipvsadm
[root@director ~]# systemctl restart ipvsadm

# 查看
[root@director ~]# 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.159.100:80 rr
  -> 192.168.159.21:80            Route   1      0          0         
  -> 192.168.159.22:80            Route   1      0          0

Real Server 配置

配置VIP在lo接口

[root@real-server1/2 ~]# echo 'DEVICE=lo:0 IPADDR=192.168.159.100 NETMASK=255.255.255.255 ONBOOT=yes' > /etc/sysconfig/network-scripts/ifcfg-lo:0
[root@real-server1/2 ~]# ifup lo:0

编辑/etc/sysctl.conf

[root@real-server1/2 ~]# vim /etc/sysctl.conf
net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.all.arp_announce = 2
net.ipv4.conf.lo.arp_ignore = 1
net.ipv4.conf.lo.arp_announce = 2

[root@real-server1/2 ~]# sysctl -p

配置web服务

[root@real-server1/2 ~]# yum -y install httpd
[root@real-server1/2 ~]# systemctl start httpd
[root@real-server1/2 ~]# systemctl enable httpd

[root@real-server1/2 ~]# echo "Real Server1" > /var/www/html/index.html
[root@real-server2 ~]# echo "Real Server2" > /var/www/html/index.html

[root@real-server1/2 ~]# systemctl restart httpd

Client 配置

[root@client ~]# for i in {1..10}; do
> curl http://192.168.159.100
> done
Real Server1
Real Server2
Real Server1
Real Server2
Real Server1
Real Server2
Real Server1
Real Server2
Real Server1
Real Server2