LVS

22 篇文章 0 订阅

LB集群的实现:
软件层面上基于工作的协议层次划分:

    传输层:lvs ,haproxy(mode tcp)
        haproxy工作在套接字上,连接数量会有限制。
    应用层:haproxy , nginx , ats , perlbal(基本上都是反向代理)

当用户请求到达时,假设用户请求3306端口,正常处理是请求经由PREROUTING到达INPUT并送往内部的应用程序中,这样没法对请求进行调度了,我们得打破这种规则。因此需要在内核tcp协议栈上建立一个负载均衡调度法则,而且它必须能分析协议报文,识别出哪些是定义成为集群服务的服务,能把对这些服务的请求直接转发至后端主机。

lvs: linux virtual server (四层交换,四层路由)

(1)调度器假装自己提供了用户所需的服务,实际上它不真正提供服务,所以是Virtual server
(2)工作方式:根据请求备报文的目标IP和PORT将其转发至后台主机集群中的某一台主机上(根据挑选算法)
(3)lvs是附着在netfilter上工作,工作在INPUT上
所以基于lvs工作:REROUTING--->INPUT------>(强行)POSTROUTING
至于怎么强行扔给POSTROUTING,有可能修改目标ip,也有可能不该,也就是说lvs工作机制不止DNAT一种。

LVS工作需要指明两点:

(1)哪个服务作为集群服务工作
(2)这个服务对应的后端主机有多少个

ipvsadm:用户空间的命令行工具,用于管理集群服务
ipvs:工作在内核中netfilter INPUT 钩子上;

二者关系:
ipvsadm是让用户定义集群服务及规则,然后通过系统调用将规则扔给INPUT上的ipvs

支持的协议: TCP、UDP、AH、EST、AH_EST 、SCTP等诸多协议

如何检测你的系统是否支持ipvs
这里写图片描述

lvs架构组成:

调度器:(blancer)负载均衡器,director,dispatcher(分发器)
RS:real server
Client IP:CIP 
Director Virtual IP:VIP
Director IP:DIP
Real Server IP:RIP

lvs类型:

lvs-nat : RIP与DIP必须处于同一网段
lvs-dr(direct routing):Director与RS必须处于同一物理网络中
lvs-tun( ip tunneling)
lvs-fullnat

lvs-nat:多目标的DNAT(iptables):他通过修改请求报文的目标ip地址(同时可能修改目标端口)至挑选出的某RS的RIP地址实现转发

(1)RS应该和DIP使用私网地址,且RS的网关应该指向DIP;
(2)请求和响应报文都要将由Director转发;极高负载场景中Director可能成为系统瓶颈,
(3)支持端口映射(你请求的是80,realserver可以使用8080,在响应时通过director再改回成80就成了)
(4)RS可以使用任意OS
(5)RIP和DIP必须处于同一IP网络中,因为realserver的网关要指向director。

工作过程:

调度器上有两块网卡,一块为面向互联网(公网 vip),一块面向real sever(私网 dip)
接收报文: prerouting—->input——>postrouting
入栈时,报文先到达prerouting,再到input,在input上被强行修改到postrouting上。
进去时,源地址为cip ,目标地址为vip
当请求到达INPUT链上后通过我们定义的ipvs规则强行将请求改到postrouting上
出去时,源地址cip, 目标地址 rip

回复报文: rerouting——>forward——>postrouting
报文由real server 到 director 这个过程中
源ip(rip),目标ip(cip)。
( 因为客户端刚开始的目标ip是vip ,所以在回复时最终客户端看到的源ip只能是vip,所以我们必须要经过调度器将源ip转化成vip,要想经过调度器,则real server 的网关必须指向 调度器)
报文由调度器到达客户端的过程中:
源ip(vip),目标ip(cip)

lvs-dr(direct routing): 通过修改请求报文的目标MAC地址实现转发;
这里写图片描述

(1)为什么realserver上要配置vip
Director和各realserver直接连在同一个交换机上,客户端请求会经过层层路由过来,在这层层路由的过程中,源ip和目标ip一直不变,在报文到达最后一层路由后,源mac是路由器上某个接口的mac,目标mac是vip所在主机的mac,(那么vip所在主机的mac是如何被知道的呢?通过arp地址解析协议进行广播)
由于dr模型响应报文不经由Director,但是客户端请求的是vip,所以在realserver上也要配置vip,这样以来用户请求可能会直接到达realserver,就达不到负载均衡的目的了。这就是我们要解决的重点问题之一。
(2)为什么realserver要配置rip
当用户请求到达Director后,Direcor会挑选一个主机进行响应,这个挑选不能通过vip,因为每个主机都有vip,只能通过rip,所以每个realserver都得配置rip
(3)为什么Director要配置dip
Director和realserver通信时靠的是Dip,所以Director上还得配置dip
所以我们最终要配置如ip
  Director: VIP  DIP
  RSs:RIP  ,VIP

工作过程:
请求报文:

请求报文从路由器到达交换机的过程时,源ip(cip),目标ip是vip,
交换机把报文发给地调度器,这时源ip还是cip,目标ip还是vip,
调度器如何把报文扔给realserver?通过修改mac地址,将源ip改成调度器的mac,目标mac改成你所挑选的realserevr的mac,
这时候把报文又扔给交换机,交换机通过mac地址将报文发给realserver
realserver收到报文后,将外面的mac地址拆掉,看到ip首部,目标ip是vip,vip是本地的ip地址,所以本地要响应。这时realserver以vip作为源地址,直接响应客户端

试想这样一种场景:

路由器接口A与交换机相连,假设其ip为aip ,aip与vip在同一网段,vip与rip不在同一网段中,这时候rip能把网关指向路由器接口ip吗? (realserver上有vip和rip,不能把vip作为与外部进行通信的地址,因为vip要隐藏起来,避免arp地址解析产生响应)
不能, 因为aip与rip不在同一网段中。
这时候如果路由器上有其他接口,该接口与rip在同一网段,将rip指向它。

这时候又有一种问题产生,对linux 而言,响应报文从哪个网卡出去,则源地址就是哪个网卡的地址。
rip配置在网卡上,则意味着响应报文的源地址是rip,但客户请求的是vip,所以响应报文的源地址应该是vip,这可怎么办?

对于每个realserver而言,rip配置在物理网卡上,vip配置在lo接口的别名上,要求从哪个接口进来的请求报文必须从哪个接口出去(Director将报文转发过来,报文从rip所在接口进来,发现目标ip在本地的lo上,所以报文从物理网卡转发到lo上,再从lo到达web服务器上。web服务器在响应时正常情况下是通过物理网卡出去的(因为响应报文的目标地址不是lo,势必不会经过lo接口),所以我们得强行限制响应报文先经由lo,这时源地址就是lo接口上的地址,再发送给物理网卡)

 (1) 保证前端路由器将目标IP作为VIP的请求报文发给Director;
      解决方案
         静态绑定(将vip与Director的mac地址绑定,这样就不用就行arp地址解析了)
         arptables
         修改RS主机内核的参数  
  (2)RS的RIP可以使用私有地址;但也可以使用共有地址
  (3)RS跟Director必须在同一物理网络中(保证Director可以正常取得各realserver得mac地址,由于要使用ARP地址解析,所以他们直接不能通过路由器,可以在多个交换机上)
  (4)请求报文经由Director调度,但响应报文不经过Director
  (5)不支持端口映射
  (6)RS可以是大多数OS
  (7)RS的网关不能指向DIP;

lvs-nat:RIP与DIP必须在同一网段
lvs-dr:Director与RS必须在同一物理网络中
以上两种都限制了拓扑上的灵活性(在地域上有限制),这就需要用到lvs-tun模型了。
lvs-tun:不修改请求报文的ip首部,通过在原有的ip首部外再封装一个ip首部

lvs-tun:不需要修改请求报文的ip首部(cip—->vip),而是通过再原有的ip首部外再封装一个ip首部( dip——>rip)。
工作过程:

director可以在任何位置,vip封装在director上,realserver也可以放置在任何位置,各realserver上配置有rip,这里要求rip必须得是公网地址(在互联网上能够被找到),
因此,当客户端的请求报文发给director后,请求报文中源地址cip,目标地址vip,director收到请求后,在原有的ip首部外面又封装一层ip首部,源地址为dip,目标地址为rip,这样就把报文发给realserver了,
realserver一看目标地址就是自己,它就把ip首部拆掉,一看,又一个ip首部,这个ip首部的目标地址是vip,为了保证我们的realserver一定会接收此报文,所以realserver上也得配置vip
由于外面又封装了一个ip首部,源地址是dip目标地址是rip,这就是正常的互联网任意两个之间的通信,所以就不要求realserver和director在同一个网络中了。
这就要求:
1、支持隧道协议
2、MTU:最大传输单元。

 (1)rip,dip,vip必须全是公网地址
 (2)RS的网关不能指向dip
 (3)请求报文必须经由Director调度,但响应报文必须不能经由Director(即不支持端口映射)
 (4)不支持端口映射(因为响应报文不经由director)
 (5)RS的OS必须支持隧道功能

这几种类型中
lvs-nat:支持端口映射,dip和rip在同一网段中
lvs-dr:不支持端口映射,但director和RS必须在同一物理网路中
lvs-tun:没有网络没有限制了,但rip可以被直接访问,因为它是公网地址
如果向隐藏realserver(不想让其在互联网上直接被访问),又希望director与realserevr之间的网络没有限制,肿么办?这就要用到lvs-fallnat模型了

lvs-fullnat:
工作过程

director经由nat模式进行调度时,director与realserevr之间有多个路由器
请求报文有客户端到达director过程中,源ip是cip,目标ip是vip,
到达director后,
Director同时修改请求报文的目标地址和源地址进行转发,
请求报文:director此时要同时修改源地址和目标地址,源地址改成dip,目标地址改成rip。
报文通过路由从director到达realserver后,realserevr进行响应,响应时,源地址是rip,目标地址是dip
当响应报文到达director后,director再进行源地址和目标地址转换,源地址变成dip,目标地址变成cip

请求报文:

cip—–vip经由调度器改成vip—-rip
响应报文时:
rip—–dip经由调度器改成vip—–cip

(1)vip是公网地址,RIP和dip都是私网地址,二者无需再同一网络中;
(2)rip的网关没有必要再指向durector了,响应报文会经过层层路由从realserevr到达director。
(3)RIP接收到的请求报文的源地址为DIP,因此要响应给DIP;
(4)请求报文和响应报文都必须经由Director
(5)支持端口映射
(6)可以使用任意OS

lvs scheduler:
这里写图片描述

静态方法: 仅根据算法本身进行调度(保证了起点公平)
    RR:round robin, 轮调,轮叫,轮询
    WRR:weighted rr(加权轮调)
    SH:Source hash,源地址hash,实现session保持的机制,将来自同一IP的请求始终调度至同一RS(会损害负载均衡效果),通过lvs在本地维持一个hash表实现
    DH:Destination hash,目标地址hash,将对同一目标的请求始终发往至同一RS
        举个栗子:在根据url调度时:如果后端的realserver是一个缓存服务器:缓存服务器1,缓存服务器2,缓存服务器3......,第一个客户段请求资源时,比如被调度到缓存服务器1上,缓存服务器1本地发现自己没有,它回到原始服务器上取内容缓存至本地,那么以后其他客户端去访问该资源时直接调度到缓存服务器1上就ok了。
        问题来了,lvs仅仅是根据目标ip和目标端口进行调度的,为什么还会用到DH这种调度算法呢?
        假设公司有两个防火墙作为网关,所有公司内网的主机都要通过这两个防火墙出去,我们可以在防火墙前面使用调度器进行调度,防火墙有连接追踪机制,我们期望从哪个火墙出去的报文依旧能从该火墙送回来,这时可以在请求报文与火墙之间的调度器上做SH,在响应报文与火墙之间的调度器上做DH,这就实现了连接追踪机制。

动态方法:根据算法及RS当前负载状态进行调度(保证结果公平)

    首次请求由算法调度,后续请求根据服务器的Overhead(当前的负载),挑选出负载较小的那台服务器

    LC:Least Connection(最小连接数,哪台主机当前请求数量最少,就调度给哪台主机)    
        Overhead=Active*256+Inactive
    WLC:Wighted LC
        Overhead=(Active*256+Inactive)/weight
        WLC算法有一个缺陷:假设当前有3台主机,权重自上而下分别为123。首次调度恰好就来了一个请求,发给谁呢?因为所有的服务器的Overhead都为0,那就交给第一个,第一个心里肯定会说:凭啥交给我呀。所以就有了SED这种机制。
    SED:Shortest Expection Delay(最短期望延迟)
        Overhead=(Active+1)*256/weghit
    NQ:Nerver Queue()
    LBLC:
    LBLCR:

ipvs的集群服务:

(1)一个ipvs主机可以同时定义多个cluster service;
(2)一个cluster service上至少有一个real server

ipvsadm的用法:
管理集群服务

LVS-nat的配置:
vip为公网地址(172.25.254.1)
dip,rip为私网地址(172.25.44.*)
rip的网关指向dip

Director:
这里写图片描述
开启路由机制
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
安装ipvsadm并写规则
这里写图片描述
刷掉iptables规则

RSs:
配置ip和网关
这里写图片描述
这里写图片描述
刷掉iptables

开启apache,并编写测试页面
这里写图片描述
这里写图片描述

测试:
这里写图片描述
这时ipvsadm上的连接数会发生变化
这里写图片描述
保存ipvsadm规则
这里写图片描述

LVS-dr的配置
Director:

[root@server1 yum.repos.d]# yum install ipvsadm

1、在LVS上增加Service

命令:

ipvsadm –A –t <VIP>:<Port> -s <schedule: rr|wrr|lc|wlc|lblc|lblcr|dh|sh|sed|nq>

在lvs上为http添加一个虚拟IP为172.25.44.100的service, 并设置调度方式为 Round Robin
这里写图片描述
添加vip
这里写图片描述
2、增加Real Server
命令:

ipvsadm –a –t <VIP>:<Port> -r <RIP>:<Port> <Forward Mode: -b | -m | -g | -i >

这里写图片描述
-b: lvs-fullnat
-m: lvs-nat
-g: lvs-dr
-i: lvs-tunnel
这里写图片描述
这里写图片描述

保存策略至文件,这样重启之后策略依然存在
这里写图片描述

这里写图片描述

RSs:
为两台RS主机添加vip
这里写图片描述
保证请求报文发给Director 而不是RS
这里写图片描述
因为响应报文的源地址必须是vip,但是响应报文是从物理网卡上出去的,按照惯例,报文从哪个网卡出去,哪个网卡上的ip就是源地址,这样就矛盾了。所以,我们把RS上的vip放在lo上,当响应报文过来后让他先走lo,再由lo传给rip,这样源ip就是vip了

server2,server3编写测试页面分别为haha-server2 ,haha-server3
测试
这里写图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值