目录
  1. 1. 安装
    1. 1.1. LVS工作模式
  2. 2. LVS-NAT
    1. 2.1. 简要工作流程
    2. 2.2. LVS-NAT配置
      1. 2.2.1. 关于ICMP重定向
      2. 2.2.2. LVS-NAT特殊情况处理
  3. 3. LVS-DR
    1. 3.1. 简要工作流程
    2. 3.2. LVS-DR模式注意事项
    3. 3.3. LVS-DR模式配置
      1. 3.3.1. 配置说明
  4. 4. LVS-TUN
    1. 4.1. 简要工作流程
    2. 4.2. LVS-TUN配置
      1. 4.2.1. 关于rp_filter
      2. 4.2.2. LVS-TUN问题集
  5. 5. LVS调度算法

安装

  • 安装依赖

    1
    $> yum install Kernel-devel gcc openssl openssl-devel popt
  • 查看系统是否支持ipvs

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    $> modprobe -l|grep ipvs
    kernel/net/netfilter/ipvs/ip_vs.ko
    kernel/net/netfilter/ipvs/ip_vs_rr.ko
    kernel/net/netfilter/ipvs/ip_vs_wrr.ko
    kernel/net/netfilter/ipvs/ip_vs_lc.ko
    kernel/net/netfilter/ipvs/ip_vs_wlc.ko
    kernel/net/netfilter/ipvs/ip_vs_lblc.ko
    kernel/net/netfilter/ipvs/ip_vs_lblcr.ko
    kernel/net/netfilter/ipvs/ip_vs_dh.ko
    kernel/net/netfilter/ipvs/ip_vs_sh.ko
    kernel/net/netfilter/ipvs/ip_vs_sed.ko
    kernel/net/netfilter/ipvs/ip_vs_nq.ko
    kernel/net/netfilter/ipvs/ip_vs_ftp.ko
  • YUM安装

    1
    yum install ipvsadm
  • 检查安装

    1
    2
    3
    4
    $> ipvsadm
    IP Virtual Server version 1.2.1 (size=4096)
    Prot LocalAddress:Port Scheduler Flags
    -> RemoteAddress:Port Forward Weight ActiveConn InActConn)
  • ipvsadm命令详解

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    ipvsadm -A|E -t|u|f virutal-service-address:port [-s scheduler] [-p
    [timeout]] [-M netmask]
    ipvsadm -D -t|u|f virtual-service-address
    ipvsadm -C
    ipvsadm -R
    ipvsadm -S [-n]
    ipvsadm -a|e -t|u|f service-address:port -r real-server-address:port
    [-g|i|m] [-w weight]
    ipvsadm -d -t|u|f service-address -r server-address
    ipvsadm -L|l [options]
    ipvsadm -Z [-t|u|f service-address]
    ipvsadm --set tcp tcpfin udp
    ipvsadm --start-daemon state [--mcast-interface interface]
    ipvsadm --stop-daemon
    ipvsadm -h
    命令选项解释:有两种命令选项格式,长的和短的,具有相同的意思。在实际使用时,两种都可以。
    -A --add-service 在内核的虚拟服务器表中添加一条新的虚拟服务器记录。也就是增加一台新的虚拟服务器。
    -E --edit-service 编辑内核虚拟服务器表中的一条虚拟服务器记录。
    -D --delete-service 删除内核虚拟服务器表中的一条虚拟服务器记录。
    -C --clear 清除内核虚拟服务器表中的所有记录。
    -R --restore 恢复虚拟服务器规则
    -S --save 保存虚拟服务器规则,输出为-R 选项可读的格式
    -a --add-server 在内核虚拟服务器表的一条记录里添加一条新的真实服务器记录。也就是在一个虚拟服务器中增加一台新的真实服务器
    -e --edit-server 编辑一条虚拟服务器记录中的某条真实服务器记录
    -d --delete-server 删除一条虚拟服务器记录中的某条真实服务器记录
    -L|-l --list 显示内核虚拟服务器表
    -Z --zero 虚拟服务表计数器清零(清空当前的连接数量等)
    --set tcp tcpfin udp 设置连接超时值
    --start-daemon 启动同步守护进程。他后面可以是master 或backup,用来说明LVS Router 是master 或是backup。在这个功能上也可以采用keepalived的VRRP 功能。
    --stop-daemon 停止同步守护进程
    -h --help 显示帮助信息
    其他的选项:

    -t --tcp-service service-address 说明虚拟服务器提供的是tcp 的服务
    [vip:port] or [real-server-ip:port]

    -u --udp-service service-address 说明虚拟服务器提供的是udp 的服务
    [vip:port] or [real-server-ip:port]

    -f --fwmark-service fwmark 说明是经过iptables 标记过的服务类型。
    -s --scheduler scheduler 使用的调度算法,有这样几个选项rr|wrr|lc|wlc|lblc|lblcr|dh|sh|sed|nq,默认的调度算法是: wlc.
    -p --persistent [timeout] 持久稳固的服务。这个选项的意思是来自同一个客户的多次请求,将被同一台真实的服务器处理。timeout 的默认值为300 秒。
    -M --netmask netmask persistent granularity mask
    -r --real-server server-address 真实的服务器[Real-Server:port]
    -g --gatewaying 指定LVS 的工作模式为直接路由模式(也是LVS 默认的模式)
    -i --ipip 指定LVS 的工作模式为隧道模式
    -m --masquerading 指定LVS 的工作模式为NAT 模式
    -w --weight weight 真实服务器的权值,数值越大,权重越高
    --mcast-interface interface 指定组播的同步接口
    -c --connection 显示LVS 目前的连接 如:ipvsadm -L -c
    --timeout 显示tcp tcpfin udp 的timeout 值 如:ipvsadm -L --timeout
    --daemon 显示同步守护进程状态
    --stats 显示统计信息
    --rate 显示速率信息
    --sort 对虚拟服务器和真实服务器排序输出
    --numeric -n 输出IP 地址和端口的数字形式

LVS工作模式

 LVS有3种工作模式:LVS-NATLVS-DRLVS-TUN。下面分别进行说明及配置实例。

LVS-NAT

LVS-NAT模式客户端将请求数据包VIP,LB将数据包中的目标地址修改成RS中的一台并转发,RS处理完后将数据报回复给LB,LB将回复数据包中的源地址修改成VIP后发送给客户端。所有进出的流量都需要进过LB并进行NAT转发。

简要工作流程

  1. client向VIP发送请求(SOURCE:client_ip,DEST:LB_VIP)
  2. LB接收请求后根据调度算法选择RS,将连接信息记录hash表,修改DEST地址为RS的IP并将请求转发给该RS(SOURCE:client_ip,DEST:RS_IP)
  3. RS接收请求后,查看目的地址为自身IP于是处理请求,将处理结果回复给LB(SOURCE:RS_IP,DEST:client_ip)
  4. LB接收RS的回复包,将源地址修改为VIP后发送给client(SOURCE:LB_VIP,DEST:client_ip)
  5. 以后此连接后续的请求到达LB时,LB直接查询hash表后直接转发给RS。连接释放或超时后,LB自动将记录从hash表中删除。

LVS-NAT配置

  1. LVS-NAT模式只需要在LoadBalance上配置,RealServer并不需要特殊配置只需要将网关指向LoadBalance即可route add default gw VIP)
  2. 开启ip_forward,关闭ICMP重定向
     NAT模式下,必须打开Load Balancer的ip_forward,关闭ICMP重定向

    1
    2
    3
    4
    #turn OFF icmp redirects (1 on, 0 off)
    echo "0" >/proc/sys/net/ipv4/conf/all/send_redirects
    echo "0" >/proc/sys/net/ipv4/conf/default/send_redirects
    echo "0" >/proc/sys/net/ipv4/conf/eth0/send_redirects
  3. 只有LVS-NAT模式才支持端口转发

    1
    2
    3
    4
    5
    6
    7
    8
    9
    #NAT模式LoadBalance上必须开启IP路由转发
    echo 1 > /proc/sys/net/ipv4/ip_forward

    #-A 新增虚拟服务器(VIP)/-t tcp服务/-s 调度算法(rr|wrr|lc|wlc|lblc|lblcr|dh|sh|sed|nq)
    ipvsadm -A -t 192.168.244.132:80 -s rr

    #-a 添加RealServer服务器/-t tcp服务/-r RealServer服务器IP:Port/-m LVS-NAT模式
    ipvsadm -a -t 192.168.244.132:80 -r 192.168.27.131:8080 -m
    ipvsadm -a -t 192.168.244.132:80 -r 192.168.27.130:8080 -m
  4. 若要修改调度算法则

    1
    2
    3
    4
    5
    6
    7
    #修改调度算法
    #-E --edit-service 编辑内核虚拟服务器表中的一条虚拟服务器记录。
    ipvsadm -E -t 192.168.244.132:80 -s wrr

    #-e --edit-server 编辑一条虚拟服务器记录中的某条真实服务器记录
    ipvsadm -e -t 192.168.244.132:80 -r 192.168.27.130:8080 -m -w 2
    ipvsadm -e -t 192.168.244.132:80 -r 192.168.27.131:8080 -m -w 1

关于ICMP重定向

 当路由器检测到主机使用了非最优路由时,会通过向该主机发送ICMP重定向报文,请求改变主机的路由使其达到最优路由。
 LVS-NAT模式中ICMP重定向之所以会产生个人分析如下(或许会有误):

  1. 简要工作流程说明中的34步骤,当RS处理完请求,回复处理结果给LB(SOURCE:RS_IP,DEST:client_ip)
  2. 当LB接收到回复包时,检查发现源和目的地址为SOURCE:RS_IP,DEST:client_ip,判断此回复包并不需要经过LB而只需直接给GateWay即可,于是发送ICMP重定向报文给RS。(ICMP重定向前路由路径:RS——>LB——>GW——>client,LB认为此路由并非最优路由而应该是:RS——>GW——>client。)
  3. 当RS接收到LB发送的ICMP重定向包后,会修改路由表直接将回复包交给GW。此时回复包并没有被LB改写源和目的地址,LVS-NAT模式出现问题。

LVS-NAT特殊情况处理

 在LVS-NAT模式中可能会遇到一种特殊情况,需要对RS额外的特殊处理,此情况是当client、LB和RS都处于同一网段。
 机器路由表中默认会有一条到同网段的路由规则

1
2
3
4
5
$> route -n
内核 IP 路由表
目标 网关 子网掩码 标志 跃点 引用 使用 接口
0.0.0.0 192.168.1.1 0.0.0.0 UG 0 0 0 wlan0
192.168.1.0 0.0.0.0 255.255.255.0 U 9 0 0 wlan0

 当RS和client处于同一网段时,原本是需要回复给LB的回复包(SOURCE:RS_IP,DEST:client_ip),由于RS查自身路由表发现有到同网段的路由规则,不会将回复包传给LB而是直接将包回复给client,从而造成LVS-NAT模式出现问题。
 因此针对client、LB和RS处于同一网段的特殊情况,RS需要将到同网段的路由规则删除,让RS的所有流量都通过LB

1
2
#根据自身实际情况修改
$> route del -net 192.168.1.0 netmask 255.255.255.0 dev wlan0

LVS-DR

 LVS-DR模式应该是最为常用的模式。LVS-DR模式并未涉及IP地址的变换,主要是MAC地址的变换,因此对ARP协议会涉及较多。

简要工作流程

  1. client向VIP发送请求
  2. LB接收请求后根据调度算法选择RS,将连接信息记录hash表,修改DEST_MAC目的MAC地址为RS的MAC地址,然后将请求转发给RS。
  3. RS处理请求得出结果后(RS的lo:0接口绑定VIP),直接将请求结果回复给client
  4. 以后此连接后续的请求到达LB时,LB直接查询hash表后修改DEST_MAC后直接转发给RS。连接释放或超时后,LB自动将记录从hash表中删除。

LVS-DR模式注意事项

  1. LB和RS必须在同一广播域内, LB修改目的MAC地址后转发给RS
  2. LVS-DR的LB不需要开启路由转发ip_forward
  3. LVS-DR模式中,RS必须绑定VIP(LB只修改目的MAC后转发给RS,包的目标IP还是VIP,若RS接收到包后查看目标IP不为自己会丢弃,故RS上需要绑定VIP)(/sbin/ifconfig lo:0 inet VIP netmask 255.255.255.255)
  4. RS的VIP掩码为255.255.255.255,广播地址为本身,防止RS发出ARP广播使得LB实际的VIP与RS的VIP发生冲突
  5. 关闭RS的ARP查询(内核2.6.x)

LVS-DR模式配置

  • 环境说明
    LB:VIP_eth0:0_10.0.2.222 eth0_10.0.2.56
    RS1: VIP_lo:0_10.0.2.222 eth0_10.0.2.51
    RS2: VIP_lo:0_10.0.2.222 eth0_10.0.2.29
  • LB配置

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    #配置
    VIP=10.0.2.222
    /sbin/ifconfig eth0:0 $VIP broadcast $VIP netmask 255.255.255.0 up
    #/sbin/route add -host 10.0.2.222 dev eth0:0
    echo "0" >/proc/sys/net/ipv4/ip_forward
    /sbin/ipvsadm -A -t $VIP:80 -s wrr
    /sbin/ipvsadm -a -t $VIP:80 -r 10.0.2.51:80 -g -w 3
    /sbin/ipvsadm -a -t $VIP:80 -r 10.0.2.29:80 -g -w 1

    #查看
    $> ipvsadm -ln
    IP Virtual Server version 1.2.1 (size=4096)
    Prot LocalAddress:Port Scheduler Flags
    -> RemoteAddress:Port Forward Weight ActiveConn InActConn
    TCP 10.0.2.222:80 wrr
    -> 10.0.2.29:80 Route 1 0 0
    -> 10.0.2.51:80 Route 3 0 0
  • RS配置
     RS的VIP掩码必须为255.255.255.255

    1
    2
    3
    4
    5
    6
    7
    VIP=10.0.2.222
    echo "1" > /proc/sys/net/ipv4/conf/all/arp_ignore
    echo "2" > /proc/sys/net/ipv4/conf/all/arp_announce
    echo "1">/proc/sys/net/ipv4/conf/eth0/arp_ignore
    echo "2">/proc/sys/net/ipv4/conf/eth0/arp_announce
    ifconfig lo:0 $VIP netmask 255.255.255.255 broadcast $VIP
    #/sbin/route add -host 10.0.2.222 dev lo:0

配置说明

  • arp_ignore——定义接收到ARP请求时的响应级别
    0:默认,只用本地配置的有响应地址都给予响应
    1:仅仅在目标IP是本地地址,并且是配置在请求进来的接口上的时候才给予响应(仅在请求的目标地址配置请求到达的接口上的时候,才给予响应)
    arp_ignore=1
     reply only if the target IP address is local address configured on the incoming interface
     只回复目标IP是配置在本地入口设备的arp请求;即当RS的网卡(假定为eth0)接收到arp请求,如果需要查询的IP没有绑定在eth0接口上(RS的VIP绑定在lo:0)则不响应这个arp请求

  • arp_announce——定义将自己的地址向外通告时的级别
    0:默认,表示使用配置在任何接口的任何地址向外通告
    1:试图仅向目标网络通告与其网络匹配的地址
    2:仅向与本地接口上地址匹配的网络进行通告
    arp_announce=2
     Always use the best local address for this target.In this mode we ignore the source address in the IP packet and try to select local address that we prefer for talks with the target host. Such local address is selected by looking for primary IP addresses on all our subnets on the outgoing interface that include the target IP address. If no suitable local address is found we select the first local address we have on the outgoing interface or on all other interfaces, with the hope we will receive reply for our request and even sometimes no matter the source IP address we announce
     对查询目标使用最适当的本地地址.在此模式下将忽略IP数据包的源地址并尝试选择能和该地址通信的本地地址.首要是选择所有的网络接口的子网中外出访问子网中包含该目标IP地址的本地地址. 如果没有合适的地址被发现,将选择当前的发送网络接口或其他的有可能接收到该ARP回应的网络接口来进行发送;
     个人理解:当RS需要向外通信就要获得网关的MAC,此时会发送广播一个arp请求,默认是将自身的IP作为SourceIP封装在arp请求包里,所以当lo:0接口发送这个arp请求包时SourceIP是VIP,arp请求包里的内容是SIP=VIP/SMAC=eth0_ mac;DIP=gateway_ip/DMAC=255.255.255.255,这样当网关收到这个arp请求时就会更新自身的arp表”VIP RealServer_eth0_mac”,若所有RealServer都发送这样的arp请求则会造成网关的arp表混乱。简而言之,将arp_announce设置成2是为了不让SourceIP为VIP产生arp通告而只有eth0上的IP可进行arp通告。

LVS-TUN

 当LB和RS不在同一个网络时,则需使用到LVS-TUN模式实现负载均衡。

简要工作流程

  1. client向VIP发送请求
  2. LB接收请求后根据调度算法选择RS,将连接信息记录hash表,然后将此请求包重新封装到新的数据包中(新IP包中的目的IP为RS的IP),将新IP包转发给RS
  3. RS接收到新IP包后,首先将新IP包解封装,处理client请求(RS的tunl0接口绑定VIP),得到处理结果后直接回复给client
  4. 以后此连接后续的请求到达LB时,LB直接查询hash表后封装成新IP包直接转发给RS。连接释放或超时后,LB自动将记录从hash表中删除

LVS-TUN配置

  • LB配置

    1
    2
    3
    4
    5
    6
    7
    8
    9
    VIP=10.0.2.222
    /sbin/ifconfig eth0:0 $VIP broadcast $VIP netmask 255.255.255.0 up
    /sbin/ipvsadm -A -t $VIP:80 -s wrr
    /sbin/ipvsadm -a -t $VIP:80 -r 10.0.2.51:80 -i -w 1
    /sbin/ipvsadm -a -t $VIP:80 -r 10.0.2.29:80 -i -w 1
    echo "0" >/proc/sys/net/ipv4/ip_forward
    echo "1" >/proc/sys/net/ipv4/conf/all/send_redirects
    echo "1" >/proc/sys/net/ipv4/conf/default/send_redirects
    echo "1" >/proc/sys/net/ipv4/conf/eth0/send_redirects
  • RS配置

    1
    2
    3
    4
    5
    6
    7
    8
    VIP=10.0.2.222
    ifconfig tunl0 $VIP netmask 255.255.255.255 broadcast $VIP
    echo 1 >/proc/sys/net/ipv4/conf/eth0/arp_ignore
    echo 2 >/proc/sys/net/ipv4/conf/eth0/arp_announce
    echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
    echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
    echo 0 > /proc/sys/net/ipv4/conf/tunl0/rp_filter
    echo 0 > /proc/sys/net/ipv4/conf/all/rp_filter

关于rp_filter

 rp_filter—逆向路径过滤,借助接口的路由信息及源地址判断数据包是否合理。
 简要检查流程—若接口eth0接受到一个数据包(SIP=10.0.2.114, DIP=10.0.12.222, DEV=eth0),当响应包需要出去时候rp_filter查询路由表,<SIP=10.0.12.222, DIP=10.0.1.114>此包的输出接口是否为eth0,若不是则rp_filter失败,丢弃该响应包。
 tunl0是必须关闭rp_filter的,否则LVS-TUN模式能向VIP发出请求但无法收到RealServer的响应

个人分析过程:

  • CIP-客户端IP
  • VIP-LVS的虚拟IP
  • LBIP-LB的内部地址
  • SIP-源地址
  • DIP-目标地址
  • RIP-RealServer的IP
  1. 客户端CIP访问LVS的VIP LB上的数据包 [SIP=CIP, DIP=VIP]
  2. LVS-TUN根据算法将请求转给RealServer的DIP RealServer上的数据包(此数据包是ipip封装包) [SIP=LBIP, DIP=RIP [SIP=CIP, DIP=VIP]]
  3. RealServer接收到ipip数据包,解封后交给tunl0 tunl0接收的数据包 [SIP=CIP, DIP=VIP, DEV=tunl0]
  4. RealServer应用层处理后得出响应包, 响应包[SIP=VIP, DIP=CIP]
  5. rp_filter对响应包进行逆向路由过滤,在路由表查找[SIP=VIP, DIP=CIP]的路由条目,发现无匹配则选择默认路由从eth0出,得出[SIP=VIP, DIP=CIP, DEV=eth0],发现DEV和进来的不同(3中tunl0的数据包),于是丢弃该响应包

LVS-TUN问题集

  • 若配置完后访问不成功,检查是否加载ipip模块lsmod|grep tun,加载ipip模块modprobe ipip && modprobe ip_gre
  • RealServer上可以利用iptables做端口转发iptables -t nat -A PREROUTING -d $VIP -p tcp -m tcp --dport 80 -j DNAT --to-destination $VIP:8080

LVS调度算法

 目前LVS已实现10种调度算法:

  • rr:轮叫调度(Round-Robin Scheduling)
     将请求按顺序轮流分配给后端的RS,均等对待所有RS,不考虑RS实际连接与负载情况。
  • wrr:加权轮叫调度(Weighted Round-Robin Scheduling)
     带权重的轮叫调度,根据RS权重的大小分配请求。
  • lc:最小连接调度(Least-Connection Scheduling)
     将新的请求分配给当前连接数最小的RS。通过RS当前所活跃的连接数来估计负载情况,LB记录每个RS已建立的连接数目,当一个请求被调度到某台RS,其连接数+1;当连接中止或超时,其连接数-1
  • wlc:加权最小连接调度(Weighted Least-Connection Scheduling)
     用权重表示RS处理性能,默认权重都为1(可动态设置)。此算法在调度新连接时尽可能使服务器的已建立连接数和其权值成比例。
     wcl算法计算公式:overhead = (active * 256 + inactive) / weight
  • lblc:基于局部性的最少链接(Locality-Based Least Connections Scheduling)
     此算法是针对请求报文的目标IP地址的负载均衡调度,主要用于Cache集群系统。算法的设计目标是在RS的负载基本平衡情况下,将相同目标IP地址的请求调度到同一台RS上。
     此调度算法先根据请求的目标 IP 地址找出该目标 IP 地址最近使用的服务器,若该服务器是可用的且没有超载,将请求发送到该服务器;若服务器不存在,或者该服务器超载且有服务器处于其一半的工作负载,则用“最少链接”的原则选出一个可用的服务器,将请求发送到该服务器
  • lblcr:带复制的基于局部性最少链接(Locality-Based Least Connections with Replication Scheduling)
     此调度算法同样根据目的IP地址进行负载均衡,也主要用于Cache集群系统。和lblc仅维护一个目的IP到一台RS的关系,而lblcr维护一个目的IP到一组RS的关系。
     LBLCR 调度算法将热点映射到一组 Cache 服务器(RS集合),当热点的请求负载增加时,会增加集合里的 Cache 服务器,来处理不断增长的负载;当热点的请求负载降低时,会减少集合里的 Cache 服务器数目。
  • dh:目标地址散列调度(Destination Hashing Scheduling)
     针对目标IP地址的负载均衡,通过一个Hash函数将一个目标IP地址映射到一台服务器。
  • sh:源地址散列调度(Source Hashing Scheduling)
     针对源IP地址的负载均衡,通过一个Hash函数将一个源IP地址映射到一台服务器。
  • sed:最短预期延时调度(Shortest Expected Delay Scheduling)
     基于wlc调度算法,不在考虑非活动状态。算法计算公式:overhead = (active+1)*256 / weight
  • nq:不排队调度(Never Queue Scheduling)
     无队列,若RS连接数为0则直接分配,不需要进行SED运算。

参考文章

Powered: Hexo, Theme: Nadya remastered from NadyMain