一次MTU问题导致的RDS访问故障
导语
VPN是一种通过公网连接两个或多个私网站点的专用网络,使得这些站点仿佛是通过专线连接在一起。IPSec是一套协议框架,用于保证数据传输的私密性,完整性,真实性。但是VPN网络经常会带来一些连通性上的问题,通常与MTU设置的不合理有关。本文通过一个实际案例,来具体分析解决这个问题。
作者:陆信宇
一、环境拓扑
链路中,各个设备接口的MTU为1450
MTU是数据链路层的概念,限制的是数据链路层payload的大小,即上层协议大小(包括上层协议头),例如设置主机接口mtu为1450。则在一个TCP报文中,1450 = 20字节IP头 + 20字节TCP头 + 1410TCP数据。
RDS为京东智联云云数据库实例,实例中创建有400个数据库。
SH_MariaDB_VM是一台上海地域的云主机,部署了mariadb服务,数据和RDS实例相同。
BJ_VPNGW和SH_VPNGW分别是北京VPC和上海VPC的vpn网关
bj_client所在子网和RDS所在子网通信时,下一跳为各自所在地域的vpn网关
二、现象描述
bj_client通过BJ_VPNGW连接RDS。执行show databases时,一直卡住无返回。
bj_client通过BJ_VPNGW连接SH_MariaDB_VM。执行show databases正常,没有卡住的现象。
三、排查过程
bj_client可以ping通RDS,telnet RDS 3306端口正常,使用mysql客户端也可以正常连接。
在BJ_VPNGW和SH_VPNGW上抓包分析。发现RDS回包正常到达SH_VPNGW,但是没有到达BJ_VPNGW。数据包在SH_VPNGW被丢弃。怀疑是MTU问题,导致丢包。
继续抓包分析RDS和SH_MariaDB_VM回包的区别。发现SH_VPNGW都给RDS和SH_MariaDB_VM回了一个IMCP Error报文,报文中指定了
MTU next hop: 1374
。但是RDS的重传报文中,ip层的Total Length一直是1450。SH_MariaDB_VM在首次被丢包后,重传报文的Total Length为1374。判断ICMP Error报文没有被正常转发给RDS服务端。后核实RDS前面还有一层LB,该LB没有转发ICMP Error。调整bj_client接口mtu为1374之后,问题解决。
四、问题原因
由于bj_client、RDS、SH_MariaDB_VM的mtu都是1450,所以bj_client与RDS、SH_MariaDB_VM进行TCP三次握手时,协商的MSS大小为1410(MTU - 20B ip头 - 20B tcp头)。即后续发送的TCP报文的数据部分,最大不能超过1410字节,且IP头中DF置位,不允许报文分片。
bj_client连接RDS执行show databases命令。由于请求包较小,所以请求报文可以正常通过vpn网关到达RDS。RDS收到报文后开始响应。由于RDS中数据库很多,所以响应报文会拆分成多个进行发送,每个报文的TCP数据部分是1410字节。报文到达VPN网关后,VPN网关在原数据包基础上再次封装ESP、UDP、IP,封装之后的报文大小超过了VPN网关出接口的mtu值,又因为数据包不允许分片,导致VPN网关丢弃报文。VPN网关丢弃报文之后,会向RDS发送一个ICMP Error,指明mtu of next hop: 1374 ,告知RDS以1374为最大mtu发包。但是因为RDS实例前面还有一层LB,且这个LB不会转发ICMP Error报文,导致ICMP Error报文并没有到达真正的RDS服务端,最终导致RDS没有调整数据包大小就直接重传,数据包再次被vpn网关丢弃,进入死循环。
五、解决方案
根据以上分析,有三种解决方法。
调小服务端或者客户端mtu,让两端在建立三次握手协商mss时,以更小的mss收发数据。可以设置为ping探测的路径MTU值。
在VPN网关配置
iptables -t mangle -A FORWARD -o eth0 -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
。两端建立三次握手的报文到达vpn网关时,修改MSS值,使MSS自适应PMTU(Path MTU)保证icmp error报文可达
六、其他
什么是MTU
MTU是数据链路层的概念,限制的是数据链路层payload的大小,即上层协议大小(包括上层协议头)
例如设置主机接口mtu为1450。则在一个TCP报文中,1450 = 20字节IP头 + 20字节TCP头 + 1410TCP数据。
什么是MSS
MSS最大报文段,是TCP中一个选项,用于在TCP连接建立时,收发双方协商通信时每一个报文段所能承载的最大数据长度(注意不包含TCP头部大小)
如何探测路径MTU值
Linux主机中: 执行
ping x.x.x.x -s 1422 -M do
,x.x.x.x是目标地址,-s指明icmp报文的数据部分大小(不包含icmp 8字节头部)。-M do
表示不允许分片。多试几次,找到临界点。以mtu为1450为例,1450 = 20字节IP头 + 8字节icmp头 + 1422数据,则-s指定为1422可以正常通过Windows主机中: 执行
ping x.x.x.x -l 1472 -f
,x.x.x.x是目标地址,-l指明icmp报文的数据部分大小(不包含icmp 8字节头部)。-f表示不允许分片。如何查看MTU
Linux: ifconfig
windows: netsh interface ipv4 show subinterfaces
如何设置MTU
Linux: ifconfig eth0 mtu xxx
windows: netsh interface ipv4 set subinterface "WLAN" mtu=1450 store=persistent
一次MTU问题导致的RDS访问故障的更多相关文章
- ooofc.com域名备案问题导致无法正常访问临时解决方案
各位尊敬的easyradius用户: 由于临时收到ooofc.coom域名备案被删除的消息,之后ooofc.com就无法访问.导致用户无法访问控制台oa.ooofc.com,及用户中心user.ooo ...
- [svc]mount命令及解决因/etc/fstab错误导致系统不能启动故障
mount命令-手动挂载设备 格式: mount [options] [-t fstype] [-o option] 设备 挂载点 mount -n -o remount,rw / - Mount t ...
- Linux索引节点(Inode:no space for device)用满导致的一次故障
问题描写叙述 在storm測试环境集群上上nimbus和supervisor自己主动挂调.重新启动时显示no space for device,也不能创建,加入文件及文件夹,df -h查看 ilesy ...
- 【故障公告】再次遭遇SQL语句执行超时引发网站首页访问故障
非常抱歉,昨天 18:40~19:10 再次遭遇上次遇到的 SQL 语句执行超时引发的网站首页访问故障,由此您带来麻烦,请您谅解. 上次故障详见故障公告,上次排查下来以为是 SQL Server 参数 ...
- 一次由于 MTU 设置不当导致的网络访问超时
转自:http://weibo.com/ttarticle/p/show?id=2309404140904511340923 API 服务正常,但是调用总是超时.api端日志显示,响应速度很快. ...
- 更改apache网站根目录导致localhost不能访问
使用xampp或wamp安装完集成环境后,更改apache的网站根目录会导致localhost,localhost/phpmyadmin访问不到. 解决方法: 打开apache的配置文件:“../ap ...
- 解决ASP.NET MVC AllowAnonymous属性无效导致无法匿名访问控制器的问题
在ASP.NET MVC项目中,一般都要使用身份验证和权限控制,但总有部分网页是可以匿名访问的.使用AllowAnonymous属性就可以指定需要匿名访问的控制器,从而跳过身份验证. 但是今天却遇到一 ...
- 路由器子网掩码设置不正确导致github无法访问
奇怪的现象,路由器子网掩码设置成255.0.0.0会导致电脑访问不到https://github.com/ 改成默认的255.255.255.0就正常了.
- 防火墙导致MySQL无法访问的问题解决案例
问题 数据库总是访问不了以致不得不反反复复的重启MySQL数据库. 但是重启的效果并不明显,重启10几分钟后问题依然出现.导致前端用户难以正常访问网站.另外他们还通过google,百度搜索,怀疑是数据 ...
- iis 故障导致网站无法访问
服务器使用两三个月突然,昨天无法访问,重启后正常,第二次发生这样的事情了,打开 C:\WINDOWS\system32\LogFiles\HTTPERR 下的 httperr1.txt 201 ...
随机推荐
- Python工具箱系列(四)
上期描述了如何在Windows下安装官方的Python3.8,本期描述如何安装Anaconda.建立Python环境这个话题,为何要大费周章.不厌其烦的叙述呢,主要的原因是: 所有的语言在设计时,都假 ...
- Openstack Neutron : LBaaS v2
目录 - LBaaS v2 - 负载均衡概念 - 服务器池 Pool - 监听器 Listener - L7 转发策略 l7 policy - 负载均衡算法 Algorithms - 健康监测 Mon ...
- Python数据科学手册-机器学习: 支持向量机
support vector machine SVM 是非常强大. 灵活的有监督学习算法, 可以用于分类和回归. 贝叶斯分类器,对每个类进行了随机分布的假设,用生成的模型估计 新数据点 的标签.是属于 ...
- Kubernetes实践技巧:升级为集群
高可用 前面我们课程中的集群是单 master 的集群,对于生产环境风险太大了,非常有必要做一个高可用的集群,这里的高可用主要是针对控制面板来说的,比如 kube-apiserver.etcd.kub ...
- gin项目部署到服务器并后台启动
前言 我们写好的gin项目想要部署在服务器上,我们应该怎么做呢,接下来我会详细的讲解一下部署教程. 1.首先我们要有一台虚拟机,虚拟机上安装好go框架. 2.将写好的项目上传到虚拟机上. 3.下载好项 ...
- python实现给定K个字符数组,从这k个字符数组中任意取一个字符串,按顺序拼接,列出所有可能的字符串组合结果!
题目描述:给定K个字符数组,从这k个字符数组中任意取一个字符串,按顺序拼接,列出所有可能的字符串组合结果! 样例: input:[["a","b"," ...
- Linux中CentOS 7版本安装JDK、Tomcat、MySQL、lezsz、maven软件详解
软件安装 在Linux系统中,安装软件的方式主要有四种,这四种安装方式的特点如下: 安装方式 特点 二进制发布包安装 软件已经针对具体平台编译打包发布,只要解压,修改配置即可 rpm安装 软件已经按照 ...
- String 定义一个字符串
String 定义一个字符串,要用双引号,多个字符串用+号连接 String S = "sjosajojoaf"; System.out.println(S);
- String简介
String:字符串,使用一对""引起来表示. 1.String声明为final的,不可被继承 2.String实现了Serializable接口:表示字符串是支持序列化的.实现了 ...
- spring boot+vue前后端项目的分离(我的第一个前后端分离项目)
文章目录 1.前端vue的搭建 2.后端项目的构建 pom文件中引入的jar包 yml文件用来配置连接数据库和端口的设置 application.property进行一些整合 controller层( ...