暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

MTU 导致故障总结一例

1916

故障现象


报错内容:

从 C 端ssh -vv ${$B_IP} 报 debug1:SSH2_MSG_KEXINIT sent

从 B 端 ssh -vv ${C_IP}  报 expecting SSH2_MSG_KEX_ECDH_REPLY

MTU 知识点


1. 为什么要有MTU?(Maximum Transmission Unit 最大传输单元

道路限高杆大家都不陌生,超高,就会限制通过,其实在计算机网络环境中,MTU就是链路上的限高杆,不同设备、不同链路也存在不同的MTU值,严格来说,虽然单个IP数据包可达65535Bytes,而在传输过程中,传输链路规定了单个数据包传输长度。当IP包长度超过此长度后,数据包将被切割为链路规定的小数据包,这个就是MTU值。


2. MTU是什么?它属于第几层?

以太网MTU是指没有以太网header和FCS的以太网payload部分,IEEE802规定了大小为0~1500字节,所以,二层以太网帧长应该为这个长度加上18Bytes(6B的目的地址、6B的源地址和2B的Length/Etype以及4B的FCS),这样大小应该<=1518bytes,注意二层以太网帧度抓包出来是14Bytes。

MTU其实属于2层的一个概念,它的目的是限定 MAC 帧中数据部分payload的大小的值,进而影响到第3层的整个IP封包的大小,这个大小包括三层IP封包的包头,而最终IP包是要放进MAC帧中的,以太网的MTU最大为1500Byte,所以 MTU = IP封包后的大小。


3. IP包头有多大?

默认情况下 IP包头大小是20字节。


4. ping使用的是什么协议?

ping使用的是ICMP协议,而ICMP协议包头是8字节,而ICMP是第4层的,基于IP协议工作的协议。

IP头的20字节 + ICMP的包头8字节 = 28个字节 ,28字节 + 实际的数据大小1472字节 =  MTU的1500bytes;

上图中证明了28个字节的存在。


MSS 知识点


MSS最大传输大小的缩写,是TCP协议里面的一个概念,MSS就是TCP数据包每次能够传输的最大数据分段,为了达到最佳的传输效能TCP协议在建立连接的时候通常要协商双方的MSS值,这个值TCP协议在实现的时候往往用MTU值代替(需要减去IP数据包包头的大小20Bytes和TCP数据段的包头20Bytes)所以往往MSS为1460,通讯双方会根据双方提供的MSS值得最小值确定为这次连接的最大MSS值。


MTU 实验


1. 构建一个MTU 不分片 的包截图实验

# 服务器A IP:100.73.18.152
# 服务器B IP:100.73.18.128
# 服务器A -->ping --> 服务器B
# 修改服务器 A (100.73.18.152) 的 MTU
echo "1550" > sys/class/net/eth0/mtu

#
 在 服务器 A 上面ping
ping -c 20 -s 1500 -M do 100.73.18.128

#
 在 服务器 A 上面 tcpdump -i eth0 icmp
tcpdump -i eth0 icmp -w a91.cap


2. 数据中可以看到如下不允许分片的情况


3. 正常数据包分析(注意mtu为1500)

# 服务器A IP:100.73.18.152
# 服务器B IP:100.73.18.128
# 服务器A -->ping --> 服务器B
# 修改服务器 A (100.73.18.152) 的 MTU
echo "1500" > sys/class/net/eth0/mtu

#
 在 服务器 A 上面ping
ping -c 2 -s 1500 100.73.18.128

#
 在 服务器 A 上面 tcpdump -i eth0 icmp
tcpdump -i eth0 icmp -w a92.cap


数据包图如下:

Dont't fragment 标注中的0代表允许分片操作,如果为1类似上面的,表示不想分片,那遇到链路中MTU值比数据包小的时候,数据包就会被中途的设备直接丢弃;

More fragments 设置为1, 代表后面还有更多的分片;

1514字节=14字节以太网二层帧 + 20字节三层IP包头 +8字节ICMP包头+1472字节数据包;


More fragments 设置为0 代表后面没有分片了

62字节= 14字节以太网二层帧 + 20字节三层IP包头 + 剩余28字节数据包;

28字节=总长1500字节数据包– 已经传输的1472字节数据包;


MTU 小结


1. 是否分片是谁决定的,是中间设备(路由器或交换机)还是收发端?

通过上面抓包,可以看到数据包里面写入一个叫做DF(don't fragment)的字段告诉其他路由器是否允许对此数据包进行分片操作,所以是否进行分片操作是由发送端决定的,不想分片设置为1,想分片设置为0,默认是分片的。


2. 数据包接收方怎么知道这是不是分片包?

数据包中More fragments 设置为1,代表后面还有分片需要传,如果为0后面没有片,分片

最后的数据包之所以为0,就说明它是最后一个,后续再也没有分片数据包了。


3. 数据包到达顺序不一致,接收方怎么正确重组数据包?

由于时延的问题导致数据包到达顺序有可能不一致,这个时候如何做呢?当数据包被分片时,中间设备会根据其IP包载荷计算每一个包的起始位置,称作分片偏移量,接收端会根据其偏移量来重组数据包,如果因为网络延迟,分片最后一个包先于其他数据包到达,接收端通过偏移量,在所有数据包收到后,对数据包进行重组。


4. 当不同流量来源的数据包到达接收方,分片数据包只存在IP包头+剩余数据,而缺少传输层包头,那接收方怎么判别数据包属于某个上层协议?

有了第3个问题中的offset偏移量后,当主机接收或者发送分片数据包时,它还会根据别外一个参数最终确认所有的分片是否源自同一个源数据包,并完成重组。这个参数为Identification(数据包ID),从同一个源发出的数据包,或者同一个目的接收多个来源的数据包时,数据包的ID不同,并且相同源和目的不是同一个流的包,ID也不相同,如上图。


您的关注是我写作的动力



文章推荐


讲讲 tcp_tw_recycle,tcp_tw_reuse

通俗易懂理解Kubernetes核心组件及原理

VxLAN 与 Bridge、Namespace基础

通俗易懂理解 MySQL B+树、数据存储、索引等知识

MySQL 事务

MySQL 锁


基础小知识


hping 命令使用小结

Linux 网卡 bonding 小知识

centos7 安装 bcc-tools 软件包

Centos7.6内核升级


专辑分享


kubeadm使用外部etcd部署kubernetes v1.17.3 高可用集群

第一篇  使用 Prometheus 监控 Kubernetes 集群理论篇

Ceph 基础篇 - 存储基础及架构介绍

文章转载自Linux点滴运维实践,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论