赞
踩
对于负载均衡的使用,相信大家都不陌生。常见的使用方法是在多台ECS上架设Web服务器后,前端配置负载均衡,将ECS作为后端Real Server,根据实际业务需求,配置TCP模式或HTTP/HTTPS模式提供服务。
本篇文章主要讨论的是负载均衡4层TCP模式下,一种罕见的部署访问模式导致的间断访问失败问题的处理过程。由此大家可以了解到:
1、4层TCP模式下负载均衡的工作原理
2、4层TCP模式下负载均衡访问部署的限制
3、4层TCP模式下负载均衡问题排查的常见思路
首先,我们先来温习一下4层负载均衡的工作原理,参考知识点“负载均衡技术原理浅析”。
https://help.aliyun.com/knowledge_detail/39444.html?spm=5176.7839438.2.6.nvWFZU
4层TCP的负载均衡,使用Full NAT的工作模式,负载均衡集群引入local address(内网IP地址)的概念。
首先,我们设定相关的术语:
在客户端访问负载均衡的过程中,报文源地址->目的地址会从CIP->VIP转换为LIP->RIP,同时相应的源端口也会改变。而 LIP和RIP均为IDC内网IP,可以跨VLAN通讯。IN/OUT的数据流全部经过LVS,为了保证带宽,采用万兆(10G)网卡。如下是FULLNAT转发模式,当前仅支持TCP协议。
如下图,对于运行该ECS的物理机NC,在NC的物理网卡和ECS虚拟网卡接口之间,有一个模块"SLB地址转换模块",专门用来实现LIP->RIP的包,转换为CIP->RIP,让Real Server可以获取到客户端的真实IP地址。
客户反馈其内网SLB在业务流量较大的情况下,某些固定的ECS客户端访问内网SLB出现无法连接的情况。但与此同时,其它ECS客户端访问SLB正常;而且问题ECS客户端直接访问SLB后端Real Server的业务也没有问题。
部署架构比较简单.
内网ECS <---> 内网SLB <--> 内网后端Real Server ECS
客户使用脚本,利用nmap或者nc每隔1秒访问负载均衡,尝试建立TCP连接,而后释放。
当该脚本打印出filter时,则出现连接失败。从客户端抓包来看,客户端发送的TCP SYN包没有得到SLB返回的SYN+ACK响应。
脚本如下:
- #!/bin/bash
- while true;do
- nmap -Pn -p 9999 192.168.1.1 | awk "\$1 ~ /9999/ {print \$2}" | grep "filter"
- sleep 1
- done
注: 9999是负载均衡的TCP监听端口,192.168.1.1是负载均衡的VIP地址。
由于负载均衡访问的链路过长,在处理负载均衡相关网络问题,我们可以根据整体网络链路,结合问题现象和对比测试,来定位问题发生的可能点。
一般而言,对于客户端访问量流量大的情况下才出现问题,我们会怀疑如下可能性:
为了准确定位问题,我们需要在问题情况下,进行必要的抓包对比分析。
注:为了保障客户数据的安全性,我们对所有IP地址进行隐藏
客户端内网CIP为:xxx.xxx.88.100, 内网SLB为xxx.xxx.23.111,内网Real Server为xxx.xxx.98.79
所以实际链路是
xxx.xxx.88.100(客户端ECS)<--> SLB:xxx.xxx.23.111 端口 18056 <--> 后端ECS: xxx.xxx.98.79 端口 8056
注:因为客户端有绕过SLB到RS的实际业务,所以在客户端,Real Server,Real Server所在NC抓包会发现大量8056端口的包。
注:此处的网络包分析使用微软Network Monitor工具,与Wireshark分析方法类似。
编号2268. 客户端源端口46690直接访问Real Server的8056端口的SYN包。
编号2270. 客户端源端口21521访问负载均衡VIP的18056端口的SYN包,后续没有得到响应 (这是我们重点关注的包)。
编号2271. 客户端源端口46696直接访问Real Server的8056端口的SYN包。
抓包条件tcp[13] & 2 == 2 and tcp port 8056,抓取网络包如下:
20:31:36.424279 proto: TCP (6), length: 52) xxx.xxx.88.100.46690 > xxx.xxx.98.79.8056: S, cksum 0xc894 (correct), 3791054471:3791054471(0) win 14600
20:31:36.424350 proto: TCP (6), length: 52) xxx.xxx.98.79.8056 > xxx.xxx.88.100.46690: S, cksum 0x6b50 (correct), 4256391041:4256391041(0) ack 3791054472 win 14600
如上两个包是客户端源端口46690的SYN包是直接访问Real Server的8056端口的三次握手交互。
20:31:36.436453 proto: TCP (6), length: 60) xxx.xxx.124.161.5004 > xxx.xxx.98.79.8056: S 3171571935:3171571935(0) win 14600
该网络包为负载均衡集群将客户端源端口21521访问SLB IP 18056端口的SYN包通过Full NAT模式转换后,通过Local IP xxx.xxx.124.161的源端口5004发给后端Real Server。
这说明负载均衡集群没有丢包,该SYN包到达了NC的物理网卡。
20:31:36.445127 proto: TCP (6), length: 52) xxx.xxx.88.100.46696 > xxx.xxx.98.79.8056: S, cksum 0x92d2 (correct), 2695912842:2695912842(0) win 14600
20:31:36.445194 proto: TCP (6), length: 52) xxx.xxx.98.79.8056 > xxx.xxx.88.100.46696: S, cksum 0x1e24 (correct), 2827406360:2827406360(0) ack 2695912843 win 14600
如上客户端源端口46696的SYN包是直接访问Real Server的8056端口。
可以看到客户端访问Real Server 源端口为46690以及46696的包,但是无法看到SLB LIP转发的SYN包,所以该网络包丢在NC的物理网卡和后端Real Server的虚拟化接口上。
通过引入NC虚拟化同学,我们确认该问题是由于TCP 会话冲突导致。因为客户端通过本地IP地址和随机源端口直接访问后端Real Server,而客户端访问负载均衡VIP的包会被负载均衡更改五元组后,经过NC的“SLB地址转换模块”后,以CIP->RIP的方式发给后端Real Server。
在流量大的情况下,通过SLB LIP过来的以CIP->RIP访问后端Real Server的包,会与之前客户端直接以CIP->RIP的包存在冲突,导致NC无法将访问负载均衡的网络包发到后端ECS,造成问题。
而该问题仅仅在内网客户端同时访问内网负载均衡和后端的内网Real Server的部署模式,以及大流量的情况下才会出现。
关于该问题,我们已经与负载均衡开发团队沟通,当前我们认为该方式不符合负载均衡的使用场景,建议客户避免该使用场景,后续会有相应的官方文档详细说明。
因此,请务必确保SLB使用模式的合理性,避免前端ECS同时访问SLB VIP以及直接后端ECS。在流量大的情况下,会出现会话冲突情况,导致通过SLB访问的会话出现无法访问的情况。
通过该案例的分析,作为阿里云售后支持团队,我们也希望客户了解到如下的一些排查建议。
在分析网络问题的过程中,抓包分析确实是最准确定位问题的方式。但是我们不建议未经分析,全链路抓包定位问题,这比较低效、而且耗时。
最好的方式是首先通过合理的对比测试,已有日志分析来排除可能原因,尽量的缩小问题范围,而后在必要的网络链路节点,通过合理的使用tcpdump的抓包条件,对比分析定位问题。
例如,该案例中,客户仅仅是TCP连接建立失败,但由于客户实际业务流量较大,抓取所有包分析明显不合理。使用tcpdump时,利用过滤条件"host 192.168.1.1 and tcp[13]&2==2", 仅仅抓取指定IP地址以及TCP三次握手建立连接的TCP SYN包和SYN+ACK包,这样包的量较少而且比较容易定位问题。
由于负载均衡集群的流量非常大,不建议在负载均衡抓包。一般而言,涉及到负载均衡的抓包有2种情况:
在上述情况下,我们建议如下4点抓包对比定位问题。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。