Loading... # LVS原理以及搭建 ## 网络架构 ![01.png][1] 网络有七层架构,自上而下分别是,应用层、表示层、会话层、传输控制层、网络层、链路层、物理层。在实际应用中,可以把应用层、表示层、会话层合并成应用层,简化为五层结构。 如果客户端与服务器之间要建立通信,首先要建立连接,然后才能传输数据,建立连接的过程由位于传输控制层的TCP协议负责,在本地随机开一个端口与的目标端口进行三次握手,开启一个socket会话,然后就可以通过该会话传输数据,数据传输完成之后,四次挥手断开连接。我们可以模拟该过程: ``` cd /proc/$$/fd exec 8<> /dev/tcp/www.baidu.com/80 echo -e 'GET / HTTP/1.0\n' >& 8 cat <& 8 ``` ![02.png][2] 可以看到正确返回了HTTP的请求结果。 ## 下一跳机制 TCP/IP协议是基于下一跳机制的,IP是端点间,MAC是节点间,互联网是由无数个子网络组成,子网络还有子网络,网络与网络之间通过路由器连接,我们想访问某个网络中一台服务器上的资源,是如何找到对方位置的呢?当然,我们可以给每个用户都保留一份完整的路由表,包含internet中全部的网关地址与网关中子网的ip地址,但是internet中有几十亿的用户,这样做的成本相当高,因此,TCP/IP协议基于下一跳,由网络工程师在主干路由中配置路由表,当然不是全量的,每个路由中记录一部分,保证要访问的IP在通过多个路由之后可以被访问到,也就是网络规划。数据发送时,会带上自己的ip与目标的ip,然后再包装上本机mac与下一跳的mac,当下一跳接收到数据包时,会拿掉mac包装,查看ip地址,发现目标ip是自己,就留下,并给源ip返回信息,如果不是自己,就再包装上自己的mac和下一跳的mac丢出去。那么,计算机是如何确定下一跳是哪里的呢?计算机启动时,会通过arp协议广播,并获取所在网络的mac地址,在启动时,会发送一个数据包,源mac是自己的mac,目标mac是ff-ff-ff-ff-ff-ff,当网络中的其他节点接收到ff-ff-ff-ff-ff-ff的数据包时,会记录下数据包的源ip与源mac地址,并返回自己的ip与mac地址,这样,处于相同网络中的计算机都互相知道对方的ip地址与mac地址。 ## NAT网络地址转换 知道了下一跳机制,那么,我们就可以在数据包的ip上做文章了。 ### 路由器工作原理 比如我们的局域网有两台计算机,ip分别是192.168.1.2与192.168.1.3,通过一个路由器连接,路由器的内网ip地址是192.168.1.1,外网ip地址是6.6.6.6,现在我们想访问百度,假设百度的ip地址是8.8.8.8,应该怎么访问呢?我们知道,通信时客户端会随机开启一个端口,假设是666,它要与8.8.8.8的80端口通信,理论上,可以通过NAT协议,将192.168.1.2:666,转换成6.6.6.6:666然后访问百度,之后会给6.6.6.6:666返回数据,路由器再将6.6.6.6转化成192.168.1.2就能成功返回数据了。但是,假设两台电脑都同时访问百度,而且恰巧都开启了同一个端口,也就是192.168.1.2:666和192.168.1.3:666,它们都会被路由器转化成6.6.6.6:666,然后两个人搜索的关键词不同,返回的结果自然不同,路由器怎么区分返回的结果是谁的呢?实际上,每次连接,路由器也会开一个端口,当两个人同时访问的时候,192.168.2.666对应6.6.6.6:888,而192.168.1.3对应6.6.6.6:999,并记录端口所对应的源ip和端口,当结果返回时,路由器就可以通过端口区分不同的用户,再转换ip和端口,返回数据。 ![03.png][3] 由于该方式是转换的源ip和端口,所以称为SNAT,也就是source源。路由器就是这么工作,实现内网转外网。 ## LVS工作模式 如果要建立通信,首先需要TCP三次握手,然而,握手的过程会消耗时间和服务器资源,那么怎么避免握手呢,这就是LVS的强大之处,我们知道TCP协议是发生在第四层也就是传输控制层的,像Nginx是基于七层协议的,它必然会经历握手,但是,LVS是基于四层协议的,实际上是三层半,它实际并没有到第四层,而是“偷窥”了一下第四层的内容(记录连接状态),然后看一眼就丢出去了,也就是说它并没有建立连接。由于只到第四层,所以并不能判断具体访问的url,因此,必须保证serices提供的服务一致(镜像)。 我们先来定义几个名词: CIP:客户端ip地址 VIP:LVS对外提供服务的ip地址 DIP:用来和RIP进行交互的IP地址 RIP: realip,后台真正提供服务的ip地址 由CIP发起请求肯定会访问VIP也就是CIP->VIP,然后再由负载均衡服务器转发给RIP,然而先不管用什么手段转发,如果直接转发给RIP它会收吗?显然不会,数据包里有CIP,有VIP就是没有RIP,所以RIP收到之后就会丢弃,怎么解决这个问题呢? ### DNAT ![04.png][4] 该模式由CIP发送给VIP,VIP收到之后,通过NAT协议,将目标IP转换成RIP,这样,RIP就会收到一个CIP->RIP的数据包,返回的时候,我们期望直接通过RIP->CIP返回数据,然而,CIP仍然不会收,CIP只记得自己是给VIP发送的数据,RIP从来没建立过连接,莫名其妙返回一个数据包,CIP肯定不会接,因此,RIP还要将数据包返回给负载均衡服务器,再通过NAT协议,转换为VIP->CIP,这种模式由于转换的是目标IP,区别SNAT叫做DNAT。 弊端: 由于发送和返回都要经过负载均衡服务器,因此,带宽会成为瓶颈,网络传输是非对称的,我们请求时发送的数据大多时候就是几个参数,而返回的数据可能是一整个页面,最极端情况可能是一个大文件,就像一堆卡车司机,去上班,去的时候骑得是电动车,然后开着装满货的卡车出来,造成路的堵塞,降低吞吐量。NAT来回转换IP也会消耗算力。 ### DR模式 ![05.png][5] 相对于DNAT模式,我们期望RIP不经过负载均衡服务器,直接返回数据给CIP。我们知道,IP协议基于下一跳,也就是说,当VIP收到数据后,包一层RIP的MAC地址丢出去,RIP就会收到数据,这种方式叫MAC地址欺骗,~~网络是最好欺骗的~~然而,由于数据包中没有RIP,所以RIP仍然不会收下数据,怎么解决呢?一台计算机可以有多个IP(多个网卡或者虚拟ip),我们让RIP同时保留一个VIP,它就会收下数据了,但是同一个网络内,两个相同ip会冲突,因此,需要将RIP上配置的VIP藏起来不被发现。RIP收到的数据包是CIP->VIP的,返回的时候可以直接返回给CIP而不用通过负载均衡服务器。该模式速度快,成本低,是最常用的模式。 ### TUN隧道技术 ![06.png][6] 该模式类似DR模式,但是用的不是MAC地址欺骗,而是用DIP->RIP,作为隧道包装CIP->VIP数据包,类似VPN的机制。 ## LVS配置 ### 创建VIP 负载均衡服务器上 ``` ifconfig eth0:8 192.168.150.100/24 ``` eht0网卡名,具体通过ifconfig命令查看。如果找不到ifconfig命令通过```yum -y install net-tools```安装 该命令是在eth0上创建一个虚拟网卡地址为192.168.150.100,该地址作为VIP。 ### 修改内核 在RIP服务器上 禁止MAC地址通告 ``` echo 1 > /proc/sys/net/ipv4/conf/eth0/arp_ignore echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore echo 2 > /proc/sys/net/ipv4/conf/eth0/arp_announce echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce ``` - arp_ignore: 定义接收到ARP请求时的响应级别; - 0:只要本地配置的有相应地址,就给予响应; - 1:仅在请求的目标(MAC)地址配置请求到达的接口上的时候,才给予响应; - arp_announce:定义将自己地址向外通告时的通告级别; - 0:将本地任何接口上的任何地址向外通告; - 1:试图仅向目标网络通告与其网络匹配的地址; - 2:仅向与本地接口上地址匹配的网络进行通告; 设置隐藏的VIP ``` ifconfig lo:3 192.168.150.100 netmask 255.255.255.255 ``` 在回环接口上创建VIP,回环接口是内核虚拟出来的,不会通过网卡,永远也发不出去,掩码要设置为255.255.255.255,如果设置成255.255.255.0,所有192.168.150的网段都会走回环,不走eth0导致数据出不去。 ### LVS服务配置 VIP上 ``` yum install ipvsadm ipvsadm -A -t 192.168.150.100:80 -s rr ipvsadm -a -t 192.168.150.100:80 -r 192.168.150.12 -g -w 1 ipvsadm -a -t 192.168.150.100:80 -r 192.168.150.13 -g -w 1 ipvsadm -ln ``` \-A设置VIP,-a设置转发的RIP ``` ipvsadm -A|E|D -t|u|f 192.168.150.100:80 -s rr|wrr|dh ``` - t:TCP协议的集群 - u: UDP协议的集群 - f:FWM: 防火墙标记 四种静态调度方法 - rr:轮询 - wrr:weight,加权轮询 - dh:Destination hashing:目标地址散列 - sh:source hashing,源地址散列 动态调度方法 - lc: 最少连接 - wlc: 加权最少连接 - sed: 最短期望延迟 - nq: never queue永不排队(改进的sed) - LBLC: 基于本地的最少连接 - LBLCR: 基于本地的带复制功能的最少连接 ``` -a -t|u|f service-address -r server-address [-g|i|m] [-w weight] ``` - -t|u|f service-address:事先定义好的某集群服务通过-A定义 - \[-g|i|m\]: LVS类型 - -g: DR - -i: TUN - -m: NAT - \[-w weight\]: 定义服务器权重 - 修改:-e - 删除:-d -t|u|f service-address -r server-address - 查看 - -L|l - -n: 数字格式显示主机地址和端口 - --stats:统计数据 - --rate: 速率 - --timeout: 显示tcp、tcpfin和udp的会话超时时长 - -:c 显示当前的ipvs连接状况 - 删除所有集群服务 - -C:清空ipvs规则 - 保存规则 - -S # ipvsadm -S > /path/to/somefile - 载入此前的规则: - -R # ipvsadm -R < /path/form/somefile 查看偷窥记录本 ``` ipvsadm -lnc ``` ``` TCP 00:57 FIN_WAIT 192.168.150.1:51587 192.168.150.100:80 192.168.150.12:80 FIN_WAIT: 连接过,偷窥了所有的包 SYN_RECV: 基本上lvs都记录了,证明lvs没事,一定是后边网络层出问题 ``` ## 高可用 keepalived 多台VIP做一主多备,我们用两台做实验,先在两台安装keepalived ``` yum install keepalived ipvsadm -y ``` 虽然keepalived会自带LVS的配置项,但是我们有可能会用到面板操作,所以依然安装ipvsadm。 ### 配置 ``` cd /etc/keepalived/ cp keepalived.conf keepalived.conf.bak vi keepalived.conf ``` vrrp:虚拟路由冗余协议! ``` vrrp_instance VI_1 { state MASTER // MASTER表示主节点 其它节点设置BACKUP nterface eth0 virtual_router_id 51 priority 100 //权重 抢主的时候和主机恢复抢回ip时用到 备用机要低于主机 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.150.100/24 dev eth0 label eth0:3 } } virtual_server 192.168.150.100 80 { delay_loop 6 lb_algo rr lb_kind DR nat_mask 255.255.255.0 persistence_timeout 0 protocol TCP real_server 192.168.150.12 80 { weight 1 HTTP_GET { url { path / status_code 200 } connect_timeout 3 nb_get_retry 3 delay_before_retry 3 } } real_server 192.168.150.13 80 { weight 1 HTTP_GET { url { path / status_code 200 } connect_timeout 3 nb_get_retry 3 delay_before_retry 3 } } ``` 拷贝配置文件到另一台主机,并修改state与权重 ``` scp ./keepalived.conf root@node04:`pwd` ``` [1]: https://www.princelei.club/usr/uploads/2019/12/2168911953.png [2]: https://www.princelei.club/usr/uploads/2019/12/3781340306.png [3]: https://www.princelei.club/usr/uploads/2019/12/2065447728.png [4]: https://www.princelei.club/usr/uploads/2019/12/2850902227.png [5]: https://www.princelei.club/usr/uploads/2019/12/381400295.png [6]: https://www.princelei.club/usr/uploads/2019/12/1713207527.png Last modification:June 11th, 2020 at 06:11 pm © 允许规范转载
?总结与建议类?