lvs简介

Linux 虚拟服务器(Linux Virtual Servers,LVS) 使用负载均衡技术将多台服务器组成一个虚拟服务器。它为适应快速增长的网络访问需求提供了一个负载能力易于扩展,而价格低廉的解决方案。
名词说明

单词 说明
LB 负载均衡器
VIP 负载均衡器IP地址,作为访问入口
CIP 客户端IP
RIP 真实服务器地址
RS 真实服务器

LVS结构与工作原理

1、LVS的结构

虚拟服务器的体系结构如图所示,一组服务器通过局域网或广域网相连接,前端有一个负载调度器(Load Balancer),
负载均衡器将网络请求调度至真实服务器 (Real Server RS)群 上,LVS这种结构对用户来说是透明的,用户访问只能看到一台作为LB的虚拟服务器 (virtual server VS), 当用户请求发往RS, LB根据设定的包转发策略和负载均衡调度算法在转发给RS, RS最终在将用户请求的结果返回。
LVS快速入手 - 图1

2、LVS内核模型

首先lvs是基于tcp四层传输层协议,它根据请求报文的目标IP和PORT将其转发至后端主机集群中的某一台主机(根据挑选算法)

  1. 当客户端的请求到达 LB 的内核空间时,首先会到达 PREROUTING链
  2. 当内核发现请求数据包的 目的地址是本机 时, 将数据包送往 INPUT链
  3. LVS由 用户空间的 ipvsadm内核空间的IPVS 组成, ipvsadm 用来定义规则, IPVS利用ipvsadm定义的规则工作, IPVS工作在INPUT链, 当数据包到达INPUT链时, 首先会被IPVS检查, 如果数据包里的 DIP和端口没有在规则里面,那么这条数据包将会放行至用户空间
  4. 如果数据包 DIP及端口在规则里, 那么该数据报文将被修改目的地址为事先定义好的后端服务器 ( RS ),并送往POSTROUTING 链
  5. 最后经由 POSTROUTING链 发往后端服务器

LVS快速入手 - 图2

3、LVS包转发模型

3.1、NAT模型

3.1.1、NAT工作原理

  1. client 将请求发往最前端的 LB, 请求报文源地址是 CIP,目标地址为 VIP
  2. LB收到报文后,发现请求的是规则里面存在的地址,它将客户端请求报文的目标地址改为了后端服务器的 RIP 并将报文根据算法发送出去
  3. 报文送到 RS 后, 由于报文地址是自己,所以会响应该请求,并将响应报文还给LVS
  4. 最后LVS 将此报文的源地址修改为本机(vip) 并发送给客户端, 注: 在NAT模式中,RS网关必须指向LVS,否则报文无法送到客户端

LVS快速入手 - 图3

3.1.2、特性

  1. 请求和响应的报文都得经过 Director ,在高负载场景中, Director 很可能成为性能瓶颈
  2. RS和DIP应该使用私网地址,且RS的网关必须指向DIP;
  3. RS的RIP和Directory的DIP必须在同一IP网络;
  4. RS可以使用任意OS;
  5. 支持端口映射

    3.2、DR模型

    3.2.1、DR工作原理

  6. client 将请求发往最前端的 LB, 请求报文源地址是 CIP,目标地址为 VIP

  7. LB 收到报文后, 发现请求的是规则里面存在的地址, 那么它将客户端请求报文的源MAC地址改成自己DIP的MAC地址, 目标MAC改为了RIP的MAC地址,并将此包发送给RS
  8. RS 发现请求报文中的目的MAC是自己, 就会将该报文接收下来,处理完请求报文后,将响应请求通过lo接口 送给eth0网卡 直接发送给客户端, 注: 需要设置lo接口的VIP不能响应本地网络内的arp请求, 使用最多还是这种, NAT调度器模型会有性能瓶颈

LVS快速入手 - 图4

3.2.2、特性

  1. RS 可以使用私有地址,还可以使用公网地址,此时可以直接通过互联网连入 RS ,以实现配置、监控等
  2. RS 的网关一定不能指向 DIP
  3. RS 跟 Dirctory 要在同一物理网络内(不能有路由器分隔) dip 跟 rip 最好在同一网络内
  4. 请求报文经过 Directory ,但响应报文一定不经过 Director
  5. 不支持端口映射

    3.3、TUN模型

  6. client 将请求发往最前端的 LB, 请求报文源地址是 CIP,目标地址为 VIP

  7. LB 收到报文后, 发现请求的是规则里面存在的地址,那么它将在客户端请求报文的首部再封装一层IP报文, 将源地址改为 DIP,目标地址改为 RIP, 并将此包发送给RS
  8. RS收到请求报文后,会首先拆开第一层封装,然后发现里面还有一层IP首部的目标地址是自己lo接口上的vip,所以会处理此次请求报文,并将响应报文通过lo接口送给eth0网卡 直接发送给客户端。 注: 需要设置lo接口的VIP不能在公网上出现

    4、LVS调度算法

    LVS的调度算法分为静态与动态两类

4.1、静态算法(4种)

只根据算法进行调度 而不考虑后端服务器的实际连接情况和负载情况

  1. RR: 轮询调度(Round Robin)
    调度器通过 “轮叫” 算法将外部请求按顺序轮流分配到集群中的RS上, 它均等对待每一台服务器,而不会考虑服务器的实际连接数及系统负载。
  2. WRR: 加权轮询 (Weight RR)
    调度器通过 “加权轮叫” 算法根据RS的不同处理能力来调度访问请求, 调度器可以自动问询RS的负载情况并动态调整其权值, 注:需要根据服务性能来手动控制其权重。
  3. DH: 目标地址散列调度 (Desination Hash)
    根据请求的目标IP地址, 作为散列键 从 静态分配的散列表找出对应服务器, 若该服务器是可用的且未超载, 则将请求发送到该服务器,否则返回空。
  4. SH: 源地址hash
    “源地址散列” 算法根据请求的源IP地址, 作为散列键 从 静态分配的散列表找出对应服务器, 若该服务器是可用的且未超载, 则将请求发送到该服务器,否则返回空。

    4.2、动态算法(6种)

    前端的调度器根据后端RS的实际连接情况来进行动态分配请求

  5. LC: 最少连接(Least Connections)
    调度器通过 “最少连接” 调度算法 将网络请求调度到已建立链接数最少的服务器上,如果集群系统的RS具有相近的系统性能,采用 “最少连接” 算法可以较好的负载均衡

  6. WLC: 加权最少连接(默认采用的就是这种) (Weighted Least Connections)
    在集群系统中的服务器性能差异较大的情况下, 调度器采用 “加权最少连接” 调度算法 优化负载均衡性能,具有较高权值的服务器将随较大比例的活动连接负载, 调度器可以自动问询真实服务器的负载情况 并动态地调整其权值
  7. SED:最短延迟调度(Shortest Expected Delay )
    在WLC基础上改进, Overhead = (ACTIVE +1) 256/加权, 不在考虑非活动状态, 把当前处于*活动状态的数目+1来实现,数目最小的接受下次请求, +1的目的是为了考虑加权的时候,非活动连接过多缺陷,当权限过大的时候,会倒置空闲服务器一直处于无连接状态
  8. NQ: 永不排队/最少队列调度(Never Queue Scheduling NQ)
  9. LBLC:基于局部性的最少链接(locality-Based Least Connections)
  10. LBLCR:带复制的基于局部性最少连接(Locality-Based Least Connections with Replication)

    5、LVS

    5.1、LVS组件

    1. # 安装: ~]# yum -y install ipvsadm
    2. ipvsadm (定义集群服务写规则) /ipvs (工作于内核中INPUT链)
    3. ipvsadm: 用户空间的命令行工具,用于管理集群服务(增删查改)
    4. ipvs: 工作于内核中 netfilter INPUT 钩子上:

    5.1.1、ipvsadm用法

  11. 管理集群服务

    管理集群服务
    ipvsadm -A|E -t|u|f service-address [-s scheduler]   
    ipvsadm -D -t|u|f service-address
    -A: 添加一个集群服务
    -t : tcp
    -u : udp
    -f : firewall make 通常应用于将两个或以上的服务绑定为一个服务进行处理时使用
    service-address
    tcp: -t ip:port
    udp:  -u ip:port
    fwm:  -f mark   防火墙标记
    -s scheduler
    默认为wlc
    如 添加:  ~]# ipvsadm -A -t VIP地址:端口 -s rr
    删除: ~]# ipvsadm -D -t VIP地址:端口
    
  12. 管理集群服务中的RS

    管理集群服务中的RS
    ipvsadm -a|e -t|u|f service-address -r server-address
    ipvsadm -d -t|u|f service-address -r server-address
    server-address:      ip[:port]   端口一般可省略
    lvs-type:
    -g: gateway, dr
    -i:ipip, tun
    -m: masquerade, net
    添加: ~]# ipvsadm -a -t vip地址:端口号 -r 真实地址:端口 -m
    删除:  ~]# ipvsadm -d -t VIP地址:端口 -r 192.168.9.32:80
    
  13. 通用查看命令

    ipvsadm -C                           清空所有
    ipvsadm -L|l [options]               查看
    -n: numeric, 基于数字格式显示地址和端口:
    -c: connection, 显示连接
    --stats: 统计数据
    --rate: 速率
    --sort: 排序
    --exact:  显示精确值
    ipvsadm -R                           重载
    ipvsadm -S [-n]                      保存
    ipvsadm -Z [-t|u|f service-address]  置零记数器
    

    5.2、lvs-nat配置

    LVS快速入手 - 图5
    LVS配置

    echo "1" > /proc/sys/net/ipv4/ip_forward #开启LVS服务器的IP路由转发功能
    # 添加虚拟地址
    ~]# ifconfig ens160:1 192.168.9.111 netmask 255.255.255.0
    ~]# ip addr 
    2: ens160: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP qlen 1000
     inet 192.168.9.224/24 brd 192.168.9.255 scope global ens160
        valid_lft forever preferred_lft forever
     inet 192.168.9.111/24 brd 192.168.9.255 scope global secondary ens160:1
    ~]# ipvsadm -a -t 192.168.9.111:999 -r 192.168.9.31:80 -m
    ~]# ipvsadm -a -t 192.168.9.111:999 -r 192.168.9.32:80 -m
    # 查看地址
    ~]# ipvsadm -L -n 
     IP Virtual Server version 1.2.1 (size=4096)
     Prot LocalAddress:Port Scheduler Flags
       -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
     TCP  192.168.9.111:999 rr
       -> 192.168.9.31:80              Masq    1      0          0         
       -> 192.168.9.32:80              Masq    1      0          0
    

    RS配置

    # 必须将网关地址指向DIP
    # 启动服务即可, systemctl restart nginx
    

    测试

    ~]# for i in {1..10};do curl http://192.168.9.111:999;sleep 2;done
     192.168.9.32
     192.168.9.31
     192.168.9.32
     192.168.9.31
     ....
    ~]# ipvsadm
     IP Virtual Server version 1.2.1 (size=4096)
     Prot LocalAddress:Port Scheduler Flags
       -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
     TCP  192.168.9.111:garcon rr
       -> 192.168.9.31:http            Masq    1      0          15        
       -> 192.168.9.32:http            Masq    1      0          15
    

    5.3、lvs-dr配置

    重要参数

    两个内核参数
     /proc/sys/net/ipv4/conf/lo/
     /proc/sys/net/ipv4/conf/all/
    arp_annonce (通告)
     0 : 通告所有的地址
     1 : 尽量避免向本网段地址通告
     2 : 总是用最佳本地地址通告
    arp_ignore
     0   : 通告所有
     1   : 请求报文是从哪接口进入,从哪个接口响应
    

    LVS快速入手 - 图6
    LVS配置

    # 配置虚拟地址,广播地址设置为自己
    ~]# ifconfig ens160:1 192.168.9.111 broadcast 192.168.9.111 netmask 255.255.255.0 up
    ~]# ifconfig ens160:1
    ens160:1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
         inet 192.168.9.111  netmask 255.255.255.255  broadcast 192.168.9.111
    # 添加路由
    ~]# ip route add 192.168.9.111 dev ens160:1
    ~]# ip route show
     192.168.9.111 dev ens160  scope link 
    ~]# ipvsadm -A -t 192.168.9.111:999 -s rr   # 测试使用轮询查看效果
    ~]# ipvsadm -a -t 192.168.9.111:999 -r 192.168.9.31 -g  
    ~]# ipvsadm -a -t 192.168.9.111:999 -r 192.168.9.32 -g  
    # 需要注意的是 不支持端口映射, 写了端口也会跟vip端口一样
    ~]# ipvsadm
    IP Virtual Server version 1.2.1 (size=4096)
    Prot LocalAddress:Port Scheduler Flags
    -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
    TCP  192.168.9.111:garcon rr
    -> 192.168.9.31:garcon          Route   1      0          0         
    -> 192.168.9.32:garcon          Route   1      0          0
    

    LVS-DR 后端服务器配置

    ~]# ifconfig lo:0 192.168.9.111 netmask 255.255.255.255 broadcast  192.168.9.111 up  # 配置回环地址
    ~]#  ifconfig  # 查看 
    # lo:0: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
    #         inet 192.168.9.111  netmask 255.255.255.255
    #          loop  txqueuelen 1000  (Local Loopback)
    ~]# route add -host 192.168.9.111 dev lo:0   # 添加路由 
    ~]# ip route   # 查看路由
    # 通告
     echo "1" > /proc/sys/net/ipv4/conf/lo/arp_ignore
     echo "2" > /proc/sys/net/ipv4/conf/all/arp_announce
     echo "1" > /proc/sys/net/ipv4/conf/all/arp_ignore
     echo "2" > /proc/sys/net/ipv4/conf/lo/arp_announce
    

    参考文档:
    LVS原理详解: http://www.178linux.com/13570
    Linux服务器集群系统: http://linux-vs.org/zh/lvs1.html
    LVS(NAT和DR)模式详细配置: https://www.jianshu.com/p/2ed85a5204cc
    CentOS 7 网络配置详解: https://blog.51cto.com/simonhu/1588971