为 Azure 中的虚拟机配置最大传输单元 (MTU)

最大传输单元 (MTU) 是一种度量值,表示网络设备或接口传输的最大以太网帧(数据包)。 如果数据包超过设备接受的最大大小,数据包会碎片化为多个较小的数据包,然后在目标处重新组装。

碎片化和重新组合可能会引入性能和排序问题,带来不理想的体验。 为解决方案优化 MTU 可以通过减少发送数据集所需的数据包总数来提供网络带宽性能优势。 配置更大的 MTU 大小可能会提高网络吞吐量,因为它会减少发送数据集所需的数据包数和标头开销。

MTU 是虚拟机操作系统中的可配置设置。 Azure 中的默认值 MTU 设置为 1500 字节。

Azure 中的 VM 只能为留在虚拟网络中的流量支持大于 1,500 字节的 MTU。

下表显示了 Azure 中可用的 Azure 网络接口支持的最大 MTU 大小:

操作系统 网络接口 虚拟网络间流量的最大 MTU
Windows Server Mellanox Cx-3、Cx-4、Cx-5 3900
使用 Set-NetAdapterAdvancedProperty 设置 MTU 值时,请使用值 4088 若要持久保留重新启动,还必须使用 Set-NetIPInterface 设置 Test-Connection 返回的值。
Windows Server (预览版)Azure 网络适配器 MANA 9000
使用 Set-NetAdapterAdvancedProperty 设置 MTU 值时,请使用值 9014若要持久保留重新启动,还必须使用 Set-NetIPInterface 设置 Test-Connection 返回的值。
Linux Mellanox Cx-3、Cx-4、Cx-5 3900
Linux (预览版)Azure 网络适配器 9000

先决条件

  • 具有活动订阅的 Azure 帐户。 创建帐户

  • Azure 中同一虚拟网络中的两个 Linux 虚拟机。 有关创建 Linux 虚拟机的详细信息,请参阅在 Azure 门户中创建 Linux 虚拟机。 要完成本文,对虚拟机的远程访问是必需的。 有关安全地连接到 Azure 虚拟机的详细信息,请参阅什么是 Azure Bastion?

    • 在本文中,虚拟机命名为 vm-1vm-2。 将这些值替换为你自己的值。

资源示例

以下资源用作本文中的示例。 将这些值替换为你自己的值。

资源 名称 IP 地址
虚拟机 1 vm-1 10.0.0.4
虚拟机 2 vm-2 10.0.0.5

预防措施

  • Azure 中的虚拟机只能为留在虚拟网络中的流量支持大于 1,500 字节的 MTU。 虚拟网络内 VM 到 VM 流量之外的方案不支持更大的 MTU。 可能不支持遍历网关、对等互连或流向 Internet 的流量。 配置更大的 MTU 可能会导致碎片化并降低性能。 对于使用这些方案的流量,请使用默认的 1,500 字节 MTU 进行测试,以确保在整个网络路径中支持更大的 MTU。

  • 最佳 MTU 特定于操作系统、网络和应用程序。 最大支持的 MTU 可能不适合你的用例。

  • 在广泛应用或向关键环境应用之前,请先测试非关键环境中的 MTU 设置更改。

路径 MTU 发现

请务必了解你的应用程序或计算机使用的网络路径支持的 MTU。 路径 MTU 发现是一种找出源地址和目标地址之间支持的最大 MTU 的方法。 使用比源地址和目标地址之间支持的 MTU 更大的值会导致碎片化,这可能会对性能产生负面影响。

在本文中,使用的示例测试了两个虚拟机之间的 MTU 路径。 可以从虚拟机向任何可路由的目标执行后续测试。

使用以下步骤在源和目标虚拟机上设置更大的 MTU 大小。 使用适用于 Linux 的 shell 脚本或适用于 Windows 的 PowerShell 验证路径 MTU。 如果不支持较大的 MTU,则路径 MTU 发现测试中显示的结果会与源或目标虚拟机接口上配置的设置不同。

Shell 脚本在 Azure 示例库中可用。 从以下链接下载适用于 Linux 的脚本,并保存到 vm-1vm-2

使用以下步骤更改 Linux 虚拟机上的 MTU 大小:

  1. 登录到 vm-1

  2. 使用 ip 命令显示当前网络接口及其 MTU 设置,记录后续步骤的 IP 地址。 在此示例中,IP 地址为 10.0.0.4,以太网接口为 eth0

    ip address show
    
    azureuser@vm-1:~$ ip address show
    1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
        link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
        inet 127.0.0.1/8 scope host lo
           valid_lft forever preferred_lft forever
        inet6 ::1/128 scope host 
           valid_lft forever preferred_lft forever
    2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
        link/ether 00:0d:3a:c5:f3:14 brd ff:ff:ff:ff:ff:ff
        inet 10.0.0.4/24 metric 100 brd 10.0.0.255 scope global eth0
           valid_lft forever preferred_lft forever
        inet6 fe80::20d:3aff:fec5:f314/64 scope link 
           valid_lft forever preferred_lft forever
    3: enP46433s1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq master eth0 state UP group default qlen 1000
        link/ether 00:0d:3a:c5:f3:14 brd ff:ff:ff:ff:ff:ff
        altname enP46433p0s2
        inet6 fe80::20d:3aff:fec5:f314/64 scope link 
           valid_lft forever preferred_lft forever
    
  3. vm-1 上的 MTU 值设置为网络接口支持的最高值。 在此示例中,网络接口的名称为 eth0。 将此值替换为你的值。

    • 对于 Mellanox 适配器,请使用以下示例将 MTU 值设置为 3900
    echo '3900' | sudo tee /sys/class/net/eth0/mtu || echo "failed: $?"
    
    • 对于 Azure 网络适配器,请使用以下示例将 MTU 值设置为 9000
    echo '9000' | sudo tee /sys/class/net/eth0/mtu || echo "failed: $?"
    

    重要

    在重新启动期间,在前面的步骤中所做的 MTU 更改不会保留。 若要永久更改,请参阅适用于你的 Linux 发行版的相应文档。

  4. 使用 ip 命令验证 MTU 设置是否应用于网络接口:

    ip address show
    
    azureuser@vm-1:~$ ip address show
    1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
        link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
        inet 127.0.0.1/8 scope host lo
           valid_lft forever preferred_lft forever
        inet6 ::1/128 scope host 
           valid_lft forever preferred_lft forever
    2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 3900 qdisc mq state UP group default qlen 1000
        link/ether 00:0d:3a:c5:f3:14 brd ff:ff:ff:ff:ff:ff
        inet 10.0.0.4/24 metric 100 brd 10.0.0.255 scope global eth0
           valid_lft forever preferred_lft forever
        inet6 fe80::20d:3aff:fec5:f314/64 scope link 
           valid_lft forever preferred_lft forever
    3: enP46433s1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 3900 qdisc mq master eth0 state UP group default qlen 1000
        link/ether 00:0d:3a:c5:f3:14 brd ff:ff:ff:ff:ff:ff
        altname enP46433p0s2
        inet6 fe80::20d:3aff:fec5:f314/64 scope link 
           valid_lft forever preferred_lft forever
    
  5. 登录到 vm-2 以重复前面的步骤,将 MTU 值设置为网络接口支持的最高值。

  6. 登录到 vm-1

  7. 使用以下示例执行 Linux shell 脚本来测试可用于特定网络路径的最大 MTU 大小。 将目标主机的值替换为 vm-2 的 IP 地址。

    ./GetPathMtu.sh 10.0.0.5
    
  8. 输出类似于以下示例。 如果脚本的输出未在网络接口上显示设置,则表示未正确设置 MTU 大小。 或者,这可能意味着路径上的网络设备仅支持 GetPathMTU 脚本返回的 MTU 大小。

    azureuser@vm-1:~/GetPathMTU$ ./GetPathMtu.sh 10.0.0.5
    destination: 10.0.0.5
    startSendBufferSize: 1200
    interfaceName: Default interface
    Test started ....................................................................................................................................................................................................
    3900
    
  9. 使用 PING 验证网络接口上的 MTU 大小。 对于 Linux,请使用 -M、-s 和 -c 标志。 -M 选项指示 ping 不要分片,-s 设置数据包大小,-c 设置要发送的 ping 数。 若要确定数据包大小,请从 MTU 的设置 3900 中减去 28。

    ping 10.0.0.5 -c 10 -M do -s 3872
    
    azureuser@vm-1:~/GetPathMTU$ ping 10.0.0.5 -c 10 -M do -s 3872
    PING 10.0.0.5 (10.0.0.5) 3872(3900) bytes of data.
    3880 bytes from 10.0.0.5: icmp_seq=1 ttl=64 time=3.70 ms
    3880 bytes from 10.0.0.5: icmp_seq=2 ttl=64 time=1.08 ms
    3880 bytes from 10.0.0.5: icmp_seq=3 ttl=64 time=1.51 ms
    3880 bytes from 10.0.0.5: icmp_seq=4 ttl=64 time=1.25 ms
    3880 bytes from 10.0.0.5: icmp_seq=5 ttl=64 time=1.29 ms
    3880 bytes from 10.0.0.5: icmp_seq=6 ttl=64 time=1.05 ms
    3880 bytes from 10.0.0.5: icmp_seq=7 ttl=64 time=5.67 ms
    3880 bytes from 10.0.0.5: icmp_seq=8 ttl=64 time=1.92 ms
    3880 bytes from 10.0.0.5: icmp_seq=9 ttl=64 time=2.72 ms
    3880 bytes from 10.0.0.5: icmp_seq=10 ttl=64 time=1.20 ms
    
    --- 10.0.0.5 ping statistics ---
    10 packets transmitted, 10 received, 0% packet loss, time 9014ms
    rtt min/avg/max/mdev = 1.051/2.138/5.666/1.426 ms
    

    表示源和目标之间的设置不匹配,在输出中显示为错误消息。 在这种情况下,MTU 未在源网络接口上设置。

    azureuser@vm-1:~/GetPathMTU$ ping 10.0.0.5 -c 10 -M do -s 3872
    PING 10.0.0.5 (10.0.0.5) 3872(3900) bytes of data.
    ping: local error: message too long, mtu=1500
    ping: local error: message too long, mtu=1500
    ping: local error: message too long, mtu=1500
    ping: local error: message too long, mtu=1500
    ping: local error: message too long, mtu=1500
    ping: local error: message too long, mtu=1500
    ping: local error: message too long, mtu=1500
    ping: local error: message too long, mtu=1500
    ping: local error: message too long, mtu=1500
    ping: local error: message too long, mtu=1500
    
    --- 10.0.0.5 ping statistics ---
    10 packets transmitted, 0 received, +10 errors, 100% packet loss, time 9248ms
    
  10. 登录到 vm-2

  11. 使用以下示例运行 Linux shell 脚本来测试可用于特定网络路径的最大 MTU 大小:

    ./GetPathMtu.sh 10.0.0.4
    
  12. 输出类似于以下示例。 如果脚本的输出未在网络接口上显示设置,则表示未正确设置 MTU 大小。 或者,这可能意味着路径上的网络设备仅支持 GetPathMTU 脚本返回的 MTU 大小。

    azureuser@vm-1:~/GetPathMTU$ ./GetPathMtu.sh 10.0.0.4
    destination: 10.0.0.4
    startSendBufferSize: 1200
    interfaceName: Default interface
    Test started ....................................................................................................................................................................................................
    3900
    
  13. 使用 PING 验证网络接口上的 MTU 大小。 对于 Linux,请使用 -M、-s 和 -c 标志。 -M 选项指示 ping 不要分片,-s 设置数据包大小,-c 设置要发送的 ping 数。 若要确定数据包大小,请从 MTU 的设置 3900 中减去 28。

    ping 10.0.0.4 -c 10 -M do -s 3872
    
    azureuser@vm-2:~/GetPathMTU$ ping 10.0.0.4 -c 10 -M do -s 3872
    PING 10.0.0.4 (10.0.0.4) 3872(3900) bytes of data.
    3880 bytes from 10.0.0.4: icmp_seq=1 ttl=64 time=3.70 ms
    3880 bytes from 10.0.0.4: icmp_seq=2 ttl=64 time=1.08 ms
    3880 bytes from 10.0.0.4: icmp_seq=3 ttl=64 time=1.51 ms
    3880 bytes from 10.0.0.4: icmp_seq=4 ttl=64 time=1.25 ms
    3880 bytes from 10.0.0.4: icmp_seq=5 ttl=64 time=1.29 ms
    3880 bytes from 10.0.0.4: icmp_seq=6 ttl=64 time=1.05 ms
    3880 bytes from 10.0.0.4: icmp_seq=7 ttl=64 time=5.67 ms
    3880 bytes from 10.0.0.4: icmp_seq=8 ttl=64 time=1.92 ms
    3880 bytes from 10.0.0.4: icmp_seq=9 ttl=64 time=2.72 ms
    3880 bytes from 10.0.0.4: icmp_seq=10 ttl=64 time=1.20 ms
    
    --- 10.0.0.4 ping statistics ---
    10 packets transmitted, 10 received, 0% packet loss, time 9014ms
    rtt min/avg/max/mdev = 1.051/2.138/5.666/1.426 ms
    

    表示源和目标之间的设置不匹配,在输出中显示为错误消息。 在这种情况下,MTU 未在源网络接口上设置。

    azureuser@vm-2:~/GetPathMTU$ ping 10.0.0.4 -c 10 -M do -s 3872
    PING 10.0.0.4 (10.0.0.4) 3872(3900) bytes of data.
    ping: local error: message too long, mtu=1500
    ping: local error: message too long, mtu=1500
    ping: local error: message too long, mtu=1500
    ping: local error: message too long, mtu=1500
    ping: local error: message too long, mtu=1500
    ping: local error: message too long, mtu=1500
    ping: local error: message too long, mtu=1500
    ping: local error: message too long, mtu=1500
    ping: local error: message too long, mtu=1500
    ping: local error: message too long, mtu=1500
    
    --- 10.0.0.4 ping statistics ---
    10 packets transmitted, 0 received, +10 errors, 100% packet loss, time 9248ms
    

还原更改

若要还原本文中所做的更改,请使用以下步骤:

  1. 登录到 vm-1

  2. 使用以下示例将 MTU 值设置为默认值 1500

    echo '1500' | sudo tee /sys/class/net/eth0/mtu || echo "failed: $?"
    

    重要

    在重新启动期间,在前面的步骤中所做的 MTU 更改不会保留。 若要永久更改,请参阅适用于你的 Linux 发行版的相应文档。

  3. 使用 ip 命令验证 MTU 设置是否应用于网络接口:

    ip address show
    
    azureuser@vm-1:~$ ip address show
    1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
        link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
        inet 127.0.0.1/8 scope host lo
           valid_lft forever preferred_lft forever
        inet6 ::1/128 scope host 
           valid_lft forever preferred_lft forever
    2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
        link/ether 00:0d:3a:c5:f3:14 brd ff:ff:ff:ff:ff:ff
        inet 10.0.0.4/24 metric 100 brd 10.0.0.255 scope global eth0
           valid_lft forever preferred_lft forever
        inet6 fe80::20d:3aff:fec5:f314/64 scope link 
           valid_lft forever preferred_lft forever
    3: enP46433s1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq master eth0 state UP group default qlen 1000
        link/ether 00:0d:3a:c5:f3:14 brd ff:ff:ff:ff:ff:ff
        altname enP46433p0s2
        inet6 fe80::20d:3aff:fec5:f314/64 scope link 
           valid_lft forever preferred_lft forever
    
  4. 登录到 vm-2 以重复前面的步骤,将 MTU 值设置为默认值 1500