写点什么

一次 MTU 问题导致的 RDS 访问故障

  • 2022-11-28
    北京
  • 本文字数:1858 字

    阅读完需:约 6 分钟

一次MTU问题导致的RDS访问故障

导语

VPN 是一种通过公网连接两个或多个私网站点的专用网络,使得这些站点仿佛是通过专线连接在一起。IPSec 是一套协议框架,用于保证数据传输的私密性,完整性,真实性。但是 VPN 网络经常会带来一些连通性上的问题,通常与 MTU 设置的不合理有关。本文通过一个实际案例,来具体分析解决这个问题。

作者:陆信宇

一、环境拓扑


1.链路中,各个设备接口的 MTU 为 1450

MTU 是数据链路层的概念,限制的是数据链路层 payload 的大小,即上层协议大小(包括上层协议头),例如设置主机接口 mtu 为 1450。则在一个 TCP 报文中,1450 = 20 字节 IP 头 + 20 字节 TCP 头 + 1410TCP 数据。

2.RDS 为京东智联云云数据库实例,实例中创建有 400 个数据库。

3.SH_MariaDB_VM 是一台上海地域的云主机,部署了 mariadb 服务,数据和 RDS 实例相同。

4.BJ_VPNGW 和 SH_VPNGW 分别是北京 VPC 和上海 VPC 的 vpn 网关

5.bj_client 所在子网和 RDS 所在子网通信时,下一跳为各自所在地域的 vpn 网关


二、现象描述


  1. bj_client 通过 BJ_VPNGW 连接 RDS。执行 show databases 时,一直卡住无返回。

  2. bj_client 通过 BJ_VPNGW 连接 SH_MariaDB_VM。执行 show databases 正常,没有卡住的现象。


三、排查过程


  1. bj_client 可以 ping 通 RDS,telnet RDS 3306 端口正常,使用 mysql 客户端也可以正常连接。

  2. 在 BJ_VPNGW 和 SH_VPNGW 上抓包分析。发现 RDS 回包正常到达 SH_VPNGW,但是没有到达 BJ_VPNGW。数据包在 SH_VPNGW 被丢弃。怀疑是 MTU 问题,导致丢包。

  3. 继续抓包分析 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。

  4. 调整 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 网关丢弃,进入死循环。


五、解决方案


根据以上分析,有三种解决方法。

  1. 调小服务端或者客户端 mtu,让两端在建立三次握手协商 mss 时,以更小的 mss 收发数据。可以设置为 ping 探测的路径 MTU 值。

  2. 在 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)

  3. 保证 icmp error 报文可达


六、其他

1 什么是 MTU

MTU 是数据链路层的概念,限制的是数据链路层 payload 的大小,即上层协议大小(包括上层协议头)

例如设置主机接口 mtu 为 1450。则在一个 TCP 报文中,1450 = 20 字节 IP 头 + 20 字节 TCP 头 + 1410TCP 数据。

2 什么是 MSS

MSS 最大报文段,是 TCP 中一个选项,用于在 TCP 连接建立时,收发双方协商通信时每一个报文段所能承载的最大数据长度(注意不包含 TCP 头部大小)

3 如何探测路径 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 表示不允许分片。

4 如何查看 MTU

Linux: ifconfig


windows: netsh interface ipv4 show subinterfaces


5 如何设置 MTU

Linux: ifconfig eth0 mtu xxx

windows: netsh interface ipv4 set subinterface "WLAN" mtu=1450 store=persistent

发布于: 刚刚阅读数: 5
用户头像

拥抱技术,与开发者携手创造未来! 2018-11-20 加入

我们将持续为人工智能、大数据、云计算、物联网等相关领域的开发者,提供技术干货、行业技术内容、技术落地实践等文章内容。京东云开发者社区官方网站【https://developer.jdcloud.com/】,欢迎大家来玩

评论

发布
暂无评论
一次MTU问题导致的RDS访问故障_数据库_京东科技开发者_InfoQ写作社区