Résoudre la fragmentation du réseau avec MTU


  • FrançaisFrançais



  • Lors de la mise en œuvre des charges de travail OpenStack, un problème courant est la fragmentation sur l’ensemble du réseau, entraînant des problèmes de performances imprévus. La fragmentation est normalement difficile à résoudre car les réseaux peuvent devenir complexes, de sorte que le chemin des paquets peut être difficile à tracer ou à prévoir.

    OpenStack lance la configuration de la carte d’interface réseau (NIC) lors de la configuration initiale du cluster ou lorsque de nouveaux nœuds sont ajoutés. La configuration de l’unité de transfert de message (MTU) est également générée à ce stade. La modification de la configuration après le déploiement du cluster n’est pas recommandée. Normalement, l’intégrateur système s’attend à ce que le chemin de bout en bout soit correctement configuré avant de déployer et de configurer le réseau pour la pile afin d’éviter les changements constants de MTU uniquement pour les tests.

    Les réseaux de neutrons sont créés après le déploiement de l’OSP. Cela permet aux administrateurs de créer des réseaux de 1 500 MTU pour les instances. Cependant, le nœud de calcul lui-même est toujours défini sur le MTU, de sorte qu’une fragmentation peut toujours se produire. Dans les charges de travail de télécommunications, par exemple, la valeur MTU la plus courante pour toutes les instances est 9 000. Il est donc facile de provoquer par inadvertance une fragmentation après la création de réseaux et d’instances.

    Cadres géants

    Voici un exemple d’instance (déployée dans OSP 16.1.5) configurée avec des trames jumbo (8996), mais vous pouvez voir que le chemin réseau n’a pas également de trames jumbo configurées. Cela provoque une fragmentation car les paquets système utilisent 8996 comme MTU.

    $ ping 10.169.252.1 -M do -s 8968
    PING 10.169.252.1 (10.169.252.1) 8968(8996) bytes of data.

    --- 10.169.252.1 ping statistics ---
    7 packets transmitted, 0 received, 100% packet loss, time 5999ms

    Cela montre 100 % de perte de paquets lorsqu’aucune fragmentation n’est autorisée. La sortie identifie efficacement le problème et révèle un problème avec le MTU dans le chemin du réseau. Si vous autorisez la fragmentation, vous pouvez voir qu’il y a un ping réussi.

    $ ping 10.169.252.1 -M dont -s 8968
    PING 10.169.252.1 (10.169.252.1) 8968(8996) bytes of data.
    8976 bytes from 10.169.252.1: icmp_seq=1 ttl=255 time=3.66 ms
    8976 bytes from 10.169.252.1: icmp_seq=2 ttl=255 time=2.94 ms
    8976 bytes from 10.169.252.1: icmp_seq=3 ttl=255 time=2.88 ms
    8976 bytes from 10.169.252.1: icmp_seq=4 ttl=255 time=2.56 ms
    8976 bytes from 10.169.252.1: icmp_seq=5 ttl=255 time=2.91 ms

    --- 10.169.252.1 ping statistics ---
    5 packets transmitted, 5 received, 0% packet loss, time 4005ms
    rtt min/avg/max/mdev = 2.561/2.992/3.663/0.368 m

    Une fois le problème confirmé, vous devrez peut-être attendre que l’équipe réseau résolve le problème. En attendant, la fragmentation existe et impacte votre système. Vous ne devriez pas mettre à jour la pile pour vérifier si le problème a été résolu, donc dans cet article, je partage un moyen sûr de réduire le MTU de bout en bout à l’intérieur du nœud de calcul.

    Réglage du MTU

    Étape 1 : Identifiez l’hyperviseur sur lequel votre instance s’exécute

    Tout d’abord, vous devez obtenir des informations sur votre instance. Faites cela depuis l’Overcloud en utilisant le openstack commander:

    (overcloud)[director]$ openstack server \
    show 2795221e-f0f7-4518-a5c5-85977357eeec \
    -f json
    {
      "OS-DCF:diskConfig": "MANUAL",
      "OS-EXT-AZ:availability_zone": "srvrhpb510-compute-2",
      "OS-EXT-SRV-ATTR:host": "srvrhpb510-compute-2.localdomain",
      "OS-EXT-SRV-ATTR:hostname": "server-2",
      "OS-EXT-SRV-ATTR:hypervisor_hostname": "srvrhpb510-compute-2.localdomain",
      "OS-EXT-SRV-ATTR:instance_name": "instance-00000248",
      "OS-EXT-SRV-ATTR:kernel_id": "",
      "OS-EXT-SRV-ATTR:launch_index": 0,
      "OS-EXT-SRV-ATTR:ramdisk_id": "",
      "OS-EXT-SRV-ATTR:reservation_id": "r-ms2ep00g",
      "OS-EXT-SRV-ATTR:root_device_name": "/dev/vda",
      "OS-EXT-SRV-ATTR:user_data": null,
      "OS-EXT-STS:power_state": "Running",
      "OS-EXT-STS:task_state": null,
      "OS-EXT-STS:vm_state": "active",
      "OS-SRV-USG:launched_at": "2021-12-16T18:57:24.000000",
      <...>
      "volumes_attached": ""
    }

    Étape 2 : Connectez-vous à l’hyperviseur et videz le XML de l’instance

    Ensuite, vous avez besoin d’un vidage du XML (en utilisant le virsh dumpxml command) qui définit votre instance. Vous pouvez donc le filtrer à l’étape suivante, rediriger la sortie dans un fichier :

    [compute2]$ sudo podman \
    exec -it nova_libvirt bash

    (pod)[compute2]# virsh \
    list --all
     Id   Name                State
    -----------------------------------
     6    instance-00000245   running
     7    instance-00000248   running

    (pod)[compute2]# virsh dumpxml instance-00000245 | tee inst245.xml
    <domain type='kvm' id='6'>
      <name>instance-00000245</name>
      <uuid>1718c7d4-520a-4366-973d-d421555295b0</uuid>
      <metadata>
        <nova:instance xmlns:nova="http://openstack.org/xmlns/libvirt/nova/1.0">
          <nova:package version="20.4.1-1.20201114041747.el8ost"/>
          <nova:name>server-1</nova:name>
          <nova:creationTime>2021-12-16 18:57:03</nova:creationTime>
    [...]
    </domain>

    Étape 3 : Examiner la sortie XML

    Une fois que vous avez la sortie XML, utilisez votre pager ou éditeur de texte préféré pour obtenir les informations d’interface réseau pour l’instance.

    <interface type='bridge'>
          <mac address='fa:16:3e:f7:15:db'/>
          <source bridge='br-int'/>
          <virtualport type='openvswitch'>
            <parameters interfaceid='da128923-84c7-435e-9ec1-5a000ecdc163'/>
          </virtualport>
          <target dev='tap123'/>
          <model type='virtio'/>
          <driver name='vhost' rx_queue_size='1024'/>
          <mtu size='8996'/>
          <alias name='net0'/>
          <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
        </interface>

    À partir de cette sortie, filtrez le pont source (sur le nœud de calcul) et le périphérique cible (l’interface physique dans le nœud de calcul).

    Cette sortie peut changer en fonction du type de pare-feu que vous utilisez ou si vous utilisez des groupes de sécurité où le flux est un peu différent, mais toutes les interfaces hôtes sont affichées et les étapes suivantes s’appliquent à toutes.

    Étape 4 : Regardez l’appareil cible

    Dans ce cas, tap123 sur le nœud de calcul se trouve le périphérique cible, alors examinez-le avec la commande ip :

    [compute2]$ ip addr show tap123

    tap123: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 8996
            inet6 fe80::fc16:3eff:fef7:15db  prefixlen 64  scopeid 0x20<link>
            ether fe:16:3e:f7:15:db  txqueuelen 10000  (Ethernet)
           [...]

    Vous pouvez voir que le MTU est 8996, comme prévu. Vous pouvez également trouver l’adresse MAC (fe:16:3e:f7:15:db), de sorte que vous pouvez éventuellement confirmer le port à l’aide des commandes de port OpenStack.

    Vous pouvez également vérifier que cette interface se trouve dans le pont br-int :

    Bridge br-int
           [...]
            Port tap123
                tag: 1
                Interface tap123

    C’est également comme prévu, car cela autorise le trafic sud et nord pour cette instance en utilisant le réseau externe.

    Étape 5 : Modifier le MTU

    Appliquez un changement de MTU commun sur l’hôte spécifiquement pour votre interface cible (tap123 dans cet exemple).

    [compute2]$ sudo ifconfig tap123 mtu 1500
    [compute2]$ ip addr show tap123 | grep mtu
    tap123: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500

    Étape 6 : Répétez

    Répétez maintenant la procédure à l’intérieur de l’instance pour déplacer le mtu de 8996 à 1500. Cela couvre la partie hyperviseur, car neutron est toujours configuré avec des trames jumbo.

    [localhost]$ sudo ip link set dev eth0 mtu 1500
    [localhost]$ ip addr show eth0
    eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
            inet 10.169.252.186  netmask 255.255.255.255  broadcast 0.0.0.0
            inet6 fe80::f816:3eff:fef7:15db  prefixlen 64  scopeid 0x20<link>
            ether fa:16:3e:f7:15:db  txqueuelen 1000  (Ethernet)
            RX packets 1226  bytes 242462 (236.7 KiB)
            RX errors 0  dropped 0  overruns 0  frame 0
            TX packets 401  bytes 292332 (285.4 KiB)
            TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

    Validation

    Maintenant, le chemin à l’intérieur du réseau local a un MTU de 1500. Si vous essayez d’envoyer un paquet plus grand que cela, une erreur devrait s’afficher :

    [localhost]$ ping 10.169.252.1 -M do -s 1500
    PING 10.169.252.1 (10.169.252.1) 1500(1528) 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

    --- 10.169.252.1 ping statistics ---
    4 packets transmitted, 0 received, +4 errors, 100% packet loss, time 3000ms

    Ce ping ajoute 28 octets à l’en-tête, tentant d’envoyer une charge utile de 1 500 octets + 28 octets. Le système ne peut pas l’envoyer car il dépasse le MTU. Une fois que vous avez réduit la charge utile à 1472, vous pouvez envoyer avec succès le ping dans une seule trame.

    [localhost]$ ping 10.169.252.1 -M do -s 1472
    PING 10.169.252.1 (10.169.252.1) 1472(1500) bytes of data.
    1480 bytes from 10.169.252.1: icmp_seq=1 ttl=255 time=1.37 ms
    1480 bytes from 10.169.252.1: icmp_seq=2 ttl=255 time=1.11 ms
    1480 bytes from 10.169.252.1: icmp_seq=3 ttl=255 time=1.02 ms
    1480 bytes from 10.169.252.1: icmp_seq=4 ttl=255 time=1.12 ms

    --- 10.169.252.1 ping statistics ---
    4 packets transmitted, 4 received, 0% packet loss, time 3004ms
    rtt min/avg/max/mdev = 1.024/1.160/1.378/0.131 ms

    Voici comment mettre fin aux problèmes de fragmentation lorsque la plate-forme envoie des paquets de 9 000 octets au réseau, mais que la fragmentation se produit toujours dans certains composants du réseau. Vous avez maintenant résolu les problèmes de retransmission, la perte de paquets, la gigue, la latence et d’autres problèmes connexes.

    Lorsque l’équipe réseau résout les problèmes de réseau, vous pouvez rétablir les commandes MTU à la valeur précédente. C’est ainsi que vous résolvez les problèmes de réseau sans avoir à redéployer la pile.

    Simulation de bout en bout

    Voici comment simuler le problème dans un scénario de bout en bout pour voir comment cela fonctionne. Au lieu d’envoyer un ping à la passerelle, vous pouvez envoyer un ping à une deuxième instance. Vous devez observer comment une incompatibilité de MTU provoque des problèmes, en particulier lorsqu’une application marque des paquets comme non fragmentés.

    Supposons que vos serveurs aient les spécifications suivantes :

    Serveur 1 :
    Nom d’hôte : serveur1
    IP : 10.169.252.186/24
    MTU : 1500

    Serveur 2 :
    Nom d’hôte : serveur2
    IP : 10.169.252.184/24
    MTU : 8996

    Se connecter à serveur1 et envoyer un ping à serveur2:

    [server1]$ ping 10.169.252.184
    PING 10.169.252.184 (10.169.252.184) 56(84) bytes of data.
    64 bytes from 10.169.252.184: icmp_seq=1 ttl=64 time=0.503 ms
    64 bytes from 10.169.252.184: icmp_seq=2 ttl=64 time=0.193 ms
    64 bytes from 10.169.252.184: icmp_seq=3 ttl=64 time=0.213 ms

    --- 10.169.252.184 ping statistics ---
    3 packets transmitted, 3 received, 0% packet loss, time 2000ms
    rtt min/avg/max/mdev = 0.193/0.303/0.503/0.141 ms

    Se connecter à serveur1 et envoyer un ping à serveur2 sans fragmentation avec un MTU de 1500 :

    [server1]$ ping 10.169.252.184 -M do -s 1472
    PING 10.169.252.184 (10.169.252.184) 1472(1500) bytes of data.
    1480 bytes from 10.169.252.184: icmp_seq=1 ttl=64 time=0.512 ms
    1480 bytes from 10.169.252.184: icmp_seq=2 ttl=64 time=0.293 ms
    1480 bytes from 10.169.252.184: icmp_seq=3 ttl=64 time=0.230 ms
    1480 bytes from 10.169.252.184: icmp_seq=4 ttl=64 time=0.268 ms
    1480 bytes from 10.169.252.184: icmp_seq=5 ttl=64 time=0.230 ms
    1480 bytes from 10.169.252.184: icmp_seq=6 ttl=64 time=0.208 ms
    1480 bytes from 10.169.252.184: icmp_seq=7 ttl=64 time=0.219 ms
    1480 bytes from 10.169.252.184: icmp_seq=8 ttl=64 time=0.229 ms
    1480 bytes from 10.169.252.184: icmp_seq=9 ttl=64 time=0.228 ms

    --- 10.169.252.184 ping statistics ---
    9 packets transmitted, 9 received, 0% packet loss, time 8010ms
    rtt min/avg/max/mdev = 0.208/0.268/0.512/0.091 ms

    Le MTU de serveur1 est de 1500, et serveur2 a une taille MTU supérieure à cela, donc une application s’exécutant sur serveur1 envoyer des paquets à serveur2 n’a pas de problèmes de fragmentation. Ce qui se passe si serveur2L’application de est également définie sur Non-Fragment, mais utilise un MTU de 9000 ?

    [localhost]$ ping 10.169.252.186 -M do -s 8968
    PING 10.169.252.186 (10.169.252.186) 8968(8996) bytes of data.

    --- 10.169.252.186 ping statistics ---
    10 packets transmitted, 0 received, 100% packet loss, time 8999ms

    La fragmentation se produit et les paquets envoyés ont été perdus.

    Pour corriger cela, répétez le correctif MTU afin que les deux serveurs aient le même MTU. À titre de test, revenez serveur1:

    [compute2]$ sudo ip link set dev tap123 mtu 8996
    [compute2]$ ip addr show tap123 | grep mtu
    tap123: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 8996

    [server1]$ sudo ip link set dev eth0 mtu 8996
    [server1]$ ip addr show eth0 | grep mtu
    eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 8996
    [...]

    Répétez maintenant le ping de charge utile de 9 000 octets sans fragmentation autorisée :

    [server2]$ ping 10.169.252.186 -M do -s 8968
    PING 10.169.252.186 (10.169.252.186) 8968(8996) bytes of data.
    8976 bytes from 10.169.252.186: icmp_seq=1 ttl=64 time=1.60 ms
    8976 bytes from 10.169.252.186: icmp_seq=2 ttl=64 time=0.260 ms
    8976 bytes from 10.169.252.186: icmp_seq=3 ttl=64 time=0.257 ms
    8976 bytes from 10.169.252.186: icmp_seq=4 ttl=64 time=0.210 ms
    8976 bytes from 10.169.252.186: icmp_seq=5 ttl=64 time=0.249 ms
    8976 bytes from 10.169.252.186: icmp_seq=6 ttl=64 time=0.250 ms

    --- 10.169.252.186 ping statistics ---
    6 packets transmitted, 6 received, 0% packet loss, time 5001ms
    rtt min/avg/max/mdev = 0.210/0.472/1.607/0.507 ms

    Dépannage de la MTU

    Il s’agit d’une solution de contournement simple pour aider les administrateurs réseau à résoudre les problèmes de MTU sans avoir besoin d’une mise à jour de la pile pour déplacer les MTU d’avant en arrière. Toutes ces configurations MTU sont également temporaires. Un redémarrage de l’instance ou du système entraîne le retour de toutes les interfaces à la valeur d’origine (et configurée).

    Cela ne prend également que quelques minutes à exécuter, donc j’espère que vous trouverez cela utile.

    Source

    N'oubliez pas de voter pour cet article !
    1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
    Loading...

    La Rédaction

    L'équipe rédactionnnelle du site

    Pour contacter personnellement le taulier :

    Laisser un commentaire

    Votre adresse e-mail ne sera pas publiée.