Somos un proveedor de servicios gestionados que ejecuta una red de pequeño tamaño en un solo centro de datos en Sydney. Recientemente hemos implementado un nuevo POP entre estados en Melbourne (ambos están en la costa este de Australia), y por primera vez tengo que enfrentar desafíos del mundo real en términos de ingeniería de tráfico. Mi esperanza es que pueda obtener alguna guía aquí sobre cómo obtener cierto nivel de control sobre mis rutas de iBGP.
Es probable que publique algunas preguntas interrelacionadas, pero en este caso me preocupa específicamente la ingeniería de tráfico interno. Me resulta sorprendentemente difícil descubrir cómo hacer que iBGP tome decisiones de enrutamiento óptimas.
El objetivo principal para mí es la necesidad de encontrar una manera de darle a iBGP algún concepto de límite y distancia por POP. Entonces, puedo distinguir entre un POP que está en la misma ciudad, uno que es interestatal y uno que está en la costa este y oeste. Luego optimice el enrutamiento entrante / saliente basado en esto.
Sé que habrá muchos escenarios caso por caso, pero espero poder desarrollar una estrategia de enrutamiento iBGP que funcione tal vez el 80% del tiempo y el resto tendría que lidiar con casos especiales especiales en el config.
Contexto
- Acabamos de comprar 4x ASR 1001-X para que actúen como nuestros dispositivos de borde en cada POP (2 veces por POP, pero debido a las limitaciones de hardware de conmutación, solo me estoy centrando en implementar 1 dispositivo de borde en Melbourne por ahora)
- También utilizamos Juniper para cambiar de hardware. EX4500 como nuestros "interruptores principales" y EX4200 en la capa de acceso.
- Ahora tenemos 2x proveedores de tránsito. Solo nos interconectamos con cada proveedor en un estado cada uno.
- AS 1000 es un agregador y utiliza AS 4000 como una de sus principales fuentes en Sydney.
- Esto plantea un desafío, ya que todas las rutas recibidas por AS 1000 suelen ser más largas en 1 que las que recibimos de AS 4000.
- Estoy usando Ansible para generar configuraciones de IOS usando plantillas Jinja2. Por lo tanto, no es un problema generar mucha lógica de mapa de ruta por pares iBGP para hacer las cosas.
Mis metas
Esencialmente, quiero poder lograr un enrutamiento óptimo entre los POP a medida que los implementamos. Pero en este momento no puedo lograr ningún nivel de control sobre cómo iBGP está eligiendo sus caminos.
Mi diseño actual
- Actualmente tengo 2x ASR1K que actúan como enrutadores de borde con tablas completas en Sydney, y uno en Melbourne.
- Ambos POP utilizan diferentes proveedores de tránsito.
- Tenemos un circuito punto a punto entre los dos POP que termina en ambos lados por los dispositivos de borde en las subinterfaces dot1q.
- Ejecutamos OSPF sobre este enlace entre todos los dispositivos de borde, y el costo del enlace aumenta, por lo que esta es la ruta OSPF de menor preferencia.
- Tenemos un solo área 0 de OSPF en ambos POP.
- Los dispositivos de borde son más un núcleo / borde convergente: nuestros interruptores de núcleo no hacen mucho L3 ya que no pueden manejar una tabla completa.
- En cada POP, los ASR1K actúan como reflectores de ruta para los otros dispositivos BGP en ese POP: cortafuegos, conmutadores centrales, LNS, etc.
- Cada uno tiene su propia ID de clúster, no por POP. Buscando cambiar esto a por POP.
- Cada ASR1K origina una ruta predeterminada para clientes de reflector de ruta a través de BGP.
- Todos los ASR1K están en una malla iBGP.
- Todos los tránsitos tienen la misma preferencia local en todos los sitios.
Ejemplo de enrutamiento subóptimo
- Si tengo mis tránsitos de Melbourne y Sydney en línea, el enrutamiento de salida funciona bien. El tráfico de Sydney sale por Sydney y Melbourne sale por Melbourne.
- El problema es que solo al deshabilitar mi tránsito primario de Sydney, ahora se prefiere automáticamente mi tránsito de Melbourne. En lugar de mi tránsito secundario de Sydney a través del enrutador BDR02 en Sydney.
- Así que termino con un escenario a menudo en el que el tráfico rebotará a Melbourne sobre nuestra red de retorno, saldré en Melbourne y luego regresaré a Sydney. La ruta en la que incurría <1 ms ahora es de unos 30 ms.
Para empeorar las cosas, en este escenario particular no puedo entender por qué se prefiere Melbourne.
- El peso es idéntico
- Pref local es idéntico
- AS Path tiene la misma longitud
- Ninguno de los dos caminos es de origen propio.
- Ambos tienen IGP como origen.
- Ambos tienen métrica (MED?) De 0.
- Ambas son rutas iBGP desde la perspectiva de este enrutador.
- Indicador de IGP Pensé que se correlaciona con el costo del enlace OSPF ya que estamos usando OSPF como nuestro IGP.
- He confirmado que el ancho de banda de referencia 100G está configurado en todos los dispositivos OSPF.
EDIT: 30/01: Creo que estoy equivocado acerca de cómo se calcula el costo de IGP y tal vez actualmente son los mismos. Todas mis rutas OSPF son de tipo E2. Si los costos de IGP son los mismos, entonces supongo que tiene sentido que la mejor selección de ruta se realice en función de RID, que en este caso el RID del MEL BDR sería menor que SYD.
He establecido el costo del enlace OSPF entre Sydney a 15,000 mucho más alto que el predeterminado. He calculado que esto funciona de manera confiable con nuestro ancho de banda de referencia de 100 Gbps.
En términos de costos de enlace OSPF, estas son las preferencias OSPF de cada próximo salto de las rutas BGP:
bdr-01-syd#sh ip route x.x.201.73 (AS 4000 next hop)
Routing entry for x.x.201.72/30
Known via "ospf 1", distance 110, metric 20, type extern 2, forward metric 15000
Last update from x.x.13.51 on Port-channel1.1125, 14:57:17 ago
Routing Descriptor Blocks:
* x.x.13.51, from x.x.13.66, 14:57:17 ago, via Port-channel1.1125
Route metric is 20, traffic share count is 1
bdr-01-syd#
bdr-01-syd#sh ip route x.x.31.5 (AS 1000 next hop)
Routing entry for x.x.31.4/30
Known via "ospf 1", distance 110, metric 20, type extern 2, forward metric 5
Last update from x.x.216.67 on Port-channel1.36, 1d00h ago
Routing Descriptor Blocks:
* x.x.216.67, from x.x.216.163, 1d12h ago, via Port-channel1.36
Route metric is 20, traffic share count is 1
bdr-01-syd#
x.x.201.73 is the next hop to 139.130.4.4 via the Melbourne path.
x.x.13.51 is the other end of the inter-state Point to Point. x.x.13.66 is BDR-01-MEL.
x.x.31.5 is the next hop to 139.130.4.4 via the Secondary Sydney transit in the same POP as the primary transit - via BDR-02-SYD.
x.x.216.67 is the local OSPF VLAN for the Sydney POP that both BDR01 and BDR02 are in.
x.x.216.163 is the BDR-02-SYD router.
En términos de estas opciones de OSPF, puedo ver que se recogió la "métrica de reenvío" más corta de OSPF. Pensé que BGP debería elegir el camino de Sydney basado en esto.
Puede ver en este rastro que saltamos inmediatamente a Melbourne a través de Backhaul porque el primer salto es de 13 ms: (139.130.4.4 está proyectado y tiene rutas en ambos estados).
bdr-01-syd#traceroute 139.130.4.4
Type escape sequence to abort.
Tracing the route to 139.130.4.4
VRF info: (vrf in name/id, vrf out name/id)
1 x.x.13.51 13 msec 13 msec 13 msec
2 x.x.201.73 14 msec 14 msec 14 msec
3 x.x.196.54 [AS 4000] [MPLS: Label 25049 Exp 0] 14 msec 14 msec 14 msec
4 x.x.196.51 [AS 4000] 14 msec 14 msec 14 msec
5 139.130.110.29 [AS 1221] 14 msec 15 msec 14 msec
6 203.50.11.113 [AS 1221] 16 msec 14 msec 16 msec
7 139.130.4.4 [AS 1221] 13 msec 14 msec 14 msec
bdr-01-syd#
bdr-01-syd#sh ip route 139.130.4.4
Routing entry for 139.130.0.0/16
Known via "bgp 5000", distance 200, metric 0
Tag 4000, type internal
Last update from x.x.201.73 06:06:14 ago
Routing Descriptor Blocks:
* x.x.201.73, from x.x.13.66, 06:06:14 ago
Route metric is 0, traffic share count is 1
AS Hops 2
Route tag 4000
MPLS label: none
bdr-01-syd#
bdr-01-syd#sh ip bgp regexp ^1000 1221$
BGP table version is 11307146, local router ID is x.x.216.161
Status codes: s suppressed, d damped, h history, * valid, > best, i - internal,
r RIB-failure, S Stale, m multipath, b backup-path, f RT-Filter,
x best-external, a additional-path, c RIB-compressed,
t secondary path,
Origin codes: i - IGP, e - EGP, ? - incomplete
RPKI validation codes: V valid, I invalid, N Not found
Network Next Hop Metric LocPrf Weight Path
...
* i 139.130.0.0 x.x.31.5 0 100 0 1000 1221 i
...
Versus the path via AS 4000:
bdr-01-syd#sh ip bgp regexp ^4000 1221$
*>i 138.130.0.0 x.x.201.73 0 100 0 4000 1221 i
bdr-01-syd#
En esta salida, tanto el tránsito secundario de Sydney es una ruta válida, como también lo es el tránsito de Melbourne. Melbourne es elegido como el mejor.
bdr-01-syd#sh ip bgp 139.130.4.4
BGP routing table entry for 139.130.0.0/16, version 10794227
Paths: (2 available, best #2, table default)
Advertised to update-groups:
66
Refresh Epoch 1
1000 1221, (received & used)
x.x.31.5 (metric 20) from x.x.216.163 (x.x.216.163)
Origin IGP, metric 0, localpref 100, valid, internal
Community: 1000:65110 5000:1000 5000:1001 5000:1002
rx pathid: 0, tx pathid: 0
Refresh Epoch 2
4000 1221, (received & used)
x.x.201.73 (metric 20) from x.x.13.66 (x.x.13.66)
Origin IGP, metric 0, localpref 100, valid, internal, best
Community: 4000:5307 4000:6100 4000:53073 5000:1000 5000:1030 5000:1031
rx pathid: 0, tx pathid: 0x0
bdr-01-syd#
Lo que he intentado
Traté de agregar un costo de enlace OSPF de 15,000 que calculé como una cifra segura basada en mi ancho de banda de referencia de 100 Gbps como siempre el costo OSPF menos preferido. Pensé que esto contaría como "costo de IGP" y, sin embargo, BGP sigue prefiriendo el camino de Melbourne por alguna razón.
Después de que esto no parecía tener ningún impacto, mi plan principal era usar AS PATH antes de iBGP. El plan era que tendría grupos de pares por POP. Y en mi plantilla designaría cuántos pretendientes hacer, en función de qué tan separados estuvieran los dos COP. Pensé que este sería un tipo de objetivo bastante común.
Por ejemplo:
- 0 antecede si intra-POP
- 1 anteponer si POP dentro del estado
- 2 antecede si POP entre estados
- 3 antecede si POP costa este-oeste
Pensé que esto funcionaría perfectamente, sería una solución bastante elegante y es exactamente el tipo de solución que espero obtener. Escribí las configuraciones en un par de horas y las implementé. Pero me rasqué la cabeza hasta que me di cuenta de que iBGP no es compatible con la ruta previa de AS.
- https://routerjockey.com/2011/02/28/bgp-essentials-the-art-of-path-manipulation/
- https://lists.gt.net/nsp/juniper/3870
- http://blog.ipspace.net/2008/02/bgp-essentials-as-path-prepending.html
Incluso si pudiera hacer que esto funcione, parece que nunca sería una solución compatible.
Lo que estoy considerando
- El último enlace @ ipspace.net menciona que puede usar local-pref ya que persiste dentro de un AS. Pero ya he trazado una política de preferencia local para preferir rutas de clientes aguas abajo, IXes, lo habitual ... Parece que usar localpref para esto no se combinaría bien. ¡Y Ivan no lo sugiere!
- Pensé en usar BGP Confederations, pero esto parece mucho trabajo extra para nuestra pequeña red. Y también leí que de todos modos no agrega saltos de ruta AS entre ASes confederados. Así que probablemente terminaría en el mismo lugar.
- Consideraría usar MPLS (¿creo que MPLS TE?) Pero soy muy ecológico cuando se trata de MPLS y ya tengo muchos desafíos por delante. Por lo tanto, me gustaría evitar la complejidad adicional, a menos que sea una buena solución a mi problema.
Agregaré más detalles mañana. Por ahora, aquí hay un diagrama que muestra nuestra configuración actual.