Cela fait longtemps que je voulais écrire un article sur Segment Routing. Plutôt que de faire un article théorique j’ai décidé de faire plusieurs articles qui vont vous montrer en pratique comment mettre en oeuvre cette technologie et les bénéfices associés. Même si je reviendrai sur la théorie, je vous recommande de jeter un oeil à toutes les ressources disponibles sur le site www.segment-routing.net qui est la référence pour cette technologie. Dans les articles à venir nous parlerons des usages de Segment Routing pour améliorer la disponibilité des réseaux, permettre une ingénierie de trafic simplifiée, offrir des chemins à faible latence… Dans ce premier article je vais commencer par les fondations de cette superbe technologie.
SR pour Segment Routing… ou Source Routing ?
Pour bien comprendre Segment Routing, vous pouvez repenser à la dernière fois que vous avez enregistré votre bagage avant de prendre l’avion. Afin de s’assurer que votre bagage prendra bien le ou les bons vols pour vous suivre, pensez-vous que les différents aéroports sont appelés et informés de l’arrivée de votre bagage avec une description de ce dernier et des instructions précises de ce qu’il faut en faire? Vous pouvez imaginer la complexité qu’aurait un tel modèle, notamment du fait du nombre de bagages à gérer. Au lieu de cela, au moment de l’enregistrement, on va simplement coller une étiquette sur votre bagage qui liste les différentes étapes. Chaque aéroport va simplement être capable de lire cette étiquette et réaliser les actions qui y sont listées. Le modèle fonctionne bien car il est relativement simple et indépendant de la quantité de bagages à acheminer, du nombre de vols ou d’aéroports au total. Chacun va s’occuper de réaliser les actions qui sont mentionnées sur chaque bagage. Et si tous font correctement leur travail alors vous retrouvez votre bagage sur le tapis après votre dernier atterrissage.
Avec Segment Routing c’est pareil, mais pour vos paquets sur le réseau. Pour contrôler finement l’acheminement d’un paquet, on va lui apposer en entrée du réseau une étiquette qui va contenir un ensemble d’instructions qui seront exécutées successivement. Si l’on veut par exemple forcer le passage d’un paquet par les routeur R1 puis R2, on va simplement rajouter ces 2 instructions. Une fois le paquet arrivé à R1, la première instruction va être validée et on va exécuter la suivante (peu importe d’ailleurs que le paquet soit déjà passé par R2 avant de joindre R1).
La grande force de Segment Routing est que les états sont codés dans le paquet, et non dans le réseau. Cela va permettre de s’adapter au facteur d’échelle et gérer simplement des problématiques complexes comme le traffic engineering qui jusque là donnaient pas mal de fil à retordre…
Comment coder ces instructions ?
Une des grandes forces de Segment Routing a été de ne pas créer un nouveau protocole pour le plan de données. Segment Routing va s’appuyer sur des protocoles existants pour transporter les instructions codées. 2 méthodes existent:
- MPLS – on parle de SR-MPLS. On va apposer un ensemble de labels MPLS qui correspondront chacun à une instruction.
- IPv6 – on parle de SRv6. On va coder nos instructions au sein de l’adresse IPv6. 128 bits ca laisse un peu de place pour pouvoir rajouter un peu d’information!
Je vais principalement m’appuyer sur SR-MPLS dans la suite de mes articles et de mes tests. Vons garderez en tête que les principes sont les mêmes pour SRv6. Je ferai un article dédié sur SRv6 dans lequel j’expliquerai les principaux bénéfices d’utiliser IPv6 comme plan de données.
Pour reprendre l’exemple précédent (routage d’un paquet via R1 puis R2), le routeur en entrée du réseau va apposer 2 labels MPLS. Le premier label ordonnera de router le paquet par R1, le second par R2. Les routeurs vont d’abord exécuter les instructions du premier label, à savoir router le paquet vers R1. Une fois que c’est fait, le label est retiré (ou “poppé”) puis on s’occupe d’exécuter le second, à savoir router le paquet vers R2. Une fois que c’est fait, on retire ce label puis le paquet initial va pouvoir depuis R2 rejoindre sa destination. En SR-MPLS, on va suivre les règles ancestrales du forwarding de labels MPLS, à savoir que l’on va faire du PHP (Penultimate Hop Popping). Le routeur juste avant R1, sachant qu’il est le dernier avant d’atteindre la destination indiquée sur le label, va le retirer. C’est ainsi le label correspondant à R2 qui est directement présenté à R1, permettant d’optimiser ainsi le traitement des labels et éviter qu’un routeur ne doive en retirer trop à la fois.
Tour d’horizon du lab
Sur ce lab j’ai mis les moyens. J’ai créé un lab constitué exclusivement de routeurs physiques, en combinant plusieurs types de Catalyst 8500. Je rappelle ici que les routeurs Catalyst 8500 sont globalement les successeurs des ASR1000 (et des Cisco 7200 pour les plus vieux!)
Tous mes liens sont à 10Gbps à l’exception du lien R2-R4 à 100Gbps. Les générateurs de latence seront utilisés ultérieurement. J’ai également un générateur de paquets Spirent sous la main pour stresser tout ce beau monde.
Les Node SID (Segment Identifier)
Dans l’architecture Segment Routing, une “instruction” (pour reprendre le jargon utilisé en introduction) est aussi appelée SID, comme Segment IDentifier. Pour permettre de contrôler par quel noeud du réseau on veut router des paquets, on va définir un Node SID sur chaque routeur. Ce Node SID va être associé à une adresse IP de l’équipement (IPv4 dans les tests à venir). Evidemment on va associer les Node SIDs à des adresses IP de loopback pour garder une indépendance vis-à-vis de l’état de chaque interface du réseau.
Pour vous épargner un mal de tête, je vais utiliser des règles assez simples:
- R1 – adresse Loopback0 10.0.0.1/32 – Node SID 1
- R2 – adresse Loopback0 10.0.0.2/32 – Node SID 2
- …
Voici donc ci-dessous la configuration relative à R3 (interface Loopback0 et Segment-Routing)
interface Loopback0 ip address 10.0.0.3 255.255.255.255 ! segment-routing mpls ! global-block 16000 23999 ! connected-prefix-sid-map address-family ipv4 10.0.0.3/32 index 3 range 1 exit-address-family
Vous aurez noté la commande “global-block 16000 23999” qui est capitale sur IOS-XE. Cela permet de définir les labels MPLS qui vont être utilisés par Segment-Routing. Le Node SID 3 dans mon lab va être associé au label MPLS 16003.
Vous avez peut-être aussi été intrigué par la commande “range 1”. Ici on va simplement définir un seul SID pour une seule IP. Cette commande nous permet par exemple de définir avec une seule commande 200 SIDs qui correspondraient à 200 adresses IP consécutives.
La distribution des SIDs
Une fois chaque routeur configuré avec son Node SID, il faut pouvoir annoncer ces identifiants sur le réseau. Il faut par exemple que R4 sache comment joindre le Node SID 3 (qui correspond pour rappel à la loopback 0 de R3). Avec Segment Routing on va faire très simple, c’est le protocole de routage (par exemple IS-IS ou OSPF) qui va nous permettre d’annoncer directement les Node SIDs. Pas besoin d’un protocole dédié comme LDP. On oubliera donc les problématiques de synchronisation de l’IGP et de LDP!
Dans mon lab j’utilise integrated IS-IS pour échanger les Node-SIDs directement avec les adresses IP. Par exemple sur R3:
router isis 1 net 49.0000.0000.0003.00 metric-style wide segment-routing mpls passive-interface Loopback0
J’active ensuite IS-IS sur mes interfaces. C’est l’adjacence IS-IS pour segment-routing qui va activer nativement MPLS. Inutile d’activer “mpls ip”, cela aurait l’effet d’activer en plus LDP ce qui n’est pas souhaitable. Voici par exemple la configuration d’une interface.
interface TenGigabitEthernet0/1/3 description R4 mtu 9100 ip address 10.0.1.2 255.255.255.254 ip mtu 9000 ip router isis 1 isis network point-to-point
Je peux vérifier que Segment-Routing est bien activé pour IS-IS.
R3#sh isis segment-routing ISIS protocol is registered with MFI ISIS MFI Client ID:0x63 Tag 1 - Segment-Routing: SR State:SR_ENABLED Number of SRGB:1 SRGB Start:16000, Range:8000, srgb_handle:0x70D8B00EA7F8, srgb_state: created ...
Une fois que j’ai configuré tous mes routeurs, je peux voir sur R3 la liste de tous les Node SIDs du réseau et le protocole (ainsi que le noeud) qui les a annoncés. Je suis contraint de poster ici une capture d’écran, car il m’est assez compliqué de gérer les indentations sur ce blog. J’espère que ca restera tout aussi lisible.
Cela se traduit dans une programmation immédiate de la MPLS forwarding table. Regardons ci-dessous sur R3 les actions à mener pour le label 16004 (qui correspond au Node SID 4 de R4)
On voit qu’à réception d’un paquet avec le label 16004, le routeur R3 va “popper” le label et l’envoyer sur l’interface Te1/0/3 qui est l’interface vers R4. On applique bien la règle du Penultimate Hop Popping (aka PHP) de MPLS.
Regardons maintenant comment R14 va gérer le label 16001 (correspondant au Node SID de R1).
R14 dispose localement de 2 chemins avec la même métrique IS-IS pour rejoindre R1 comme nous pouvons le confirmer ci-dessous. Aussi R14 va considérer ces 2 interfaces Te0/0/0 (interface vers R12) et Te0/0/1 (interface vers R13). On parle ici d’ECMP (Equal Cost Mulipath): les flux avec le label 16001 vont être répartis sur les 2 liens disponibles. Il est intéressant aussi de noter que les paquets sont transmis en sortie avec le même label 16001. Contrairement à la technologie MPLS qui conférait jusque là au label une signification purement local, ici le label correspondant à un Node SID est le même partout. Cela va considérablement aider à comprendre la technologie et les séances inévitables de troubleshooting.
Non seulement les labels Segment-Routing sont installés dans la LIB (Label Information base – ou MPLS forwarding table), mais également les routes pointent vers ces labels. Si nous regardons maintenant la FIB (Forwarding Information Base – ou table CEF Cisco Express Forwarding) pour joindre la loopback de R1, on voit bien que le label correspondant au Node SID de R1 (16001) est appliqué, quelque soit le cNouhemin utilisé.
R14#sh ip cef 10.0.0.1/32
10.0.0.1/32
nexthop 10.0.1.16 TenGigabitEthernet0/0/0 label [16001|16001](ptr:0x79E6D01EC358)
nexthop 10.0.1.18 TenGigabitEthernet0/0/1 label [16001|16001](ptr:0x79E6D01EBB78)
Comme pour un réseau MPLS classique, dès qu’une route aura pour next-hop une adresse IP correspondant à un Node SID, le label correspondant sera automatiquement appliqué. Par exemple R14 reçoit la route BGP 10.0.104.0/24 ayant pour next-hop BGP la Loopback0 de R4 (10.0.0.4).
R14#sh ip route 10.0.104.0 Routing entry for 10.0.104.0/24 Known via "bgp 65001", distance 200, metric 0, type internal Last update from 10.0.0.4 1w3d ago Routing Descriptor Blocks: * 10.0.0.4, from 10.0.0.1, 1w3d ago opaque_ptr 0x79E6D034DCB0 Route metric is 0, traffic share count is 1 AS Hops 0 MPLS label: none
Aussi la CEF va naturellement indiquer l’apposition du label 16004 (correspondant au Node SID de R4) pour ce préfixe.
R14#sh ip cef 10.0.104.0 10.0.104.0/24 nexthop 10.0.1.16 TenGigabitEthernet0/0/0 label [16004|16004](ptr:0x79E6D01EA330)-(local:16004)
Résumé
Dans ce premier article nous avons vu les principes de base de Segment Routing. Je vous ai montré comment mettre en oeuvre SR-MPLS simplement et comment distribuer les Node SIDs sur le réseau. Nous verrons par la suite comment nous allons pouvoir utiliser tout cela pour optimiser notre réseau.
1 commentaires
Très bien expliqué. L’utilisation des exemples courants rend la chose plus digeste