Sistema de xestión de configuración de rede de filtrado Qrator

Sistema de xestión de configuración de rede de filtrado Qrator

TL, RD: Descrición da arquitectura cliente-servidor do noso sistema de xestión de configuración de rede interna, QControl. Está baseado nun protocolo de transporte de dúas capas que funciona con mensaxes empaquetadas en gzip sen descompresión entre os puntos finais. Os routers e puntos finais distribuídos reciben actualizacións de configuración e o propio protocolo permite a instalación de relés intermedios localizados. O sistema está construído sobre o principio copia de seguridade diferencial ("recente-estable", explicado a continuación) e usa a linguaxe de consulta JMESpath xunto co motor de modelos Jinja para renderizar ficheiros de configuración.

Qrator Labs opera unha rede de mitigación de ataques distribuída globalmente. A nosa rede funciona co principio anycast e as subredes anúncianse a través de BGP. Ao ser unha rede anycast BGP situada fisicamente en varias rexións da Terra, podemos procesar e filtrar o tráfico ilexítimo máis preto do núcleo de Internet: operadores de nivel 1.

Por outra banda, ser unha rede distribuída xeograficamente non é doado. A comunicación entre os puntos de presenza da rede é fundamental para que o fornecedor de servizos de seguridade teña unha configuración coherente de todos os nodos da rede, actualizándoos de forma oportuna. Polo tanto, para ofrecer o maior nivel posible de servizo básico ao consumidor, necesitabamos atopar un xeito de sincronizar de forma fiable os datos de configuración entre os continentes.

No principio estaba a Palabra. Converteuse rapidamente nun protocolo de comunicacións que precisa dunha actualización.


A pedra angular da existencia de QControl, e ao mesmo tempo a principal razón para gastar unha cantidade importante de tempo e recursos na construción deste tipo de protocolos, é a necesidade de obter unha única fonte de configuración autorizada e, en definitiva, sincronizar os nosos puntos de presenza. con. O almacenamento en si foi só un dos varios requisitos durante o desenvolvemento de QControl. Ademais, tamén necesitabamos integracións cos servizos existentes e previstos en puntos de presenza (POP), métodos intelixentes (e personalizables) para a validación de datos, así como control de acceso. Ademais disto, tamén queriamos controlar un sistema deste tipo usando comandos en lugar de facer modificacións nos ficheiros. Antes de QControl, os datos enviábanse aos puntos de presenza case manualmente. Se un dos puntos de presenza non estivese dispoñible e esquecémonos de actualizalo máis tarde, a configuración acabaría sen sincronía e teriamos que perder o tempo poñéndoa de novo en marcha.

Como resultado, elaboramos o seguinte esquema:
Sistema de xestión de configuración de rede de filtrado Qrator
O servidor de configuración é responsable da validación e almacenamento dos datos; o enrutador ten varios puntos finais que reciben e transmiten actualizacións de configuración dos clientes e equipos de soporte ao servidor e do servidor aos puntos de presenza.

A calidade da conexión a Internet aínda varía moito en todo o mundo; para ilustrar este punto, vexamos un sinxelo MTR desde Praga, República Checa ata Singapur e Hong Kong.

Sistema de xestión de configuración de rede de filtrado Qrator
MTR de Praga a Singapur

Sistema de xestión de configuración de rede de filtrado Qrator
O mesmo para Hong Kong

A alta latencia significa menor velocidade. Ademais, hai perda de paquetes. O ancho da canle non compensa este problema, que sempre hai que ter en conta á hora de construír sistemas descentralizados.

A configuración completa dun punto de presenza é unha cantidade importante de datos que deben enviarse a moitos destinatarios mediante conexións pouco fiables. Afortunadamente, aínda que a configuración cambia constantemente, ocorre en pequenos incrementos.

Deseño recente-estable

Podemos dicir que construír unha rede distribuída baseada no principio de actualizacións incrementais é unha solución bastante obvia. Pero hai moitos problemas coas diferenzas. Necesitamos gardar todas as diferenzas entre os puntos de referencia e tamén poder reenvialas por se alguén perdeu parte dos datos. Cada destino debe aplicalos nunha secuencia estrictamente especificada. Normalmente, no caso de varios destinos, tal operación pode levar moito tempo. O receptor tamén debe poder solicitar as pezas que faltan e, por suposto, a parte central debe responder a tal solicitude correctamente, enviando só os datos que faltan.

Como resultado, chegamos a unha solución bastante interesante: só temos unha capa de referencia, fixa, chamémoslle estable, e só unha diferenza: recente. Cada recente baséase no último estable xerado e é suficiente para reconstruír os datos de configuración. En canto o novo recente chega ao seu destino, o vello xa non é necesario.

Todo o que queda é enviar unha configuración estable e fresca de cando en vez, por exemplo porque o recente se fixo demasiado grande. O que tamén é importante aquí é que enviamos todas estas actualizacións nun modo de emisión/multicast, sen preocuparnos polos destinatarios individuais e a súa capacidade para reunir datos. Unha vez que estamos seguros de que todos teñen o estable correcto, só enviamos os novos recentes. Paga a pena aclarar que isto funciona? Obras. Stable almacénase na caché no servidor de configuración e nos destinatarios, créase recente segundo sexa necesario.

Arquitectura de transporte a dous niveis

Por que construímos o noso transporte en dous niveis? A resposta é bastante sinxela: queriamos desvincular o enrutamento da lóxica de alto nivel, inspirándonos no modelo OSI coas súas capas de transporte e aplicación. Usamos Thrift para o papel do protocolo de transporte e o formato de serialización msgpack para o formato de alto nivel das mensaxes de control. É por iso que o enrutador (que realiza multicast/broadcast/relay) non mira dentro de msgpack, non desempaqueta nin empaqueta o contido e só reenvía datos.

Thrift (do inglés - "thrift", pronunciado [θrift]) é unha linguaxe de descrición da interface que se usa para definir e crear servizos para diferentes linguaxes de programación. É un marco para chamadas de procedemento remoto (RPC). Combina unha canalización de software cun motor de xeración de código para desenvolver servizos que funcionen de forma máis ou menos eficiente e sinxela entre linguas.

Escollemos o marco Thrift debido ao RPC e ao soporte para moitos idiomas. Como é habitual, as partes fáciles foron o cliente e o servidor. Non obstante, o enrutador resultou ser unha porca difícil de romper, en parte debido á falta dunha solución preparada durante o noso desenvolvemento.

Sistema de xestión de configuración de rede de filtrado QratorHai outras opcións, como protobuf/gRPC, con todo, cando comezamos o noso proxecto, gRPC era bastante novo e non nos atrevimos a incorporalo.

Por suposto, puidemos (e de feito deberíamos) construír a nosa propia bicicleta. Sería máis doado crear un protocolo para o que necesitamos porque a arquitectura cliente-servidor é relativamente sinxela de implementar en comparación coa construción dun enrutador en Thrift. Dun xeito ou doutro, hai un prexuízo tradicional cara aos protocolos autoescritos e ás implementacións de bibliotecas populares (por unha boa razón); ademais, durante os debates sempre xorde a pregunta: "Como imos trasladar isto a outros idiomas?" Entón botamos inmediatamente a idea dunha bicicleta.

Msgpack é semellante a JSON, pero máis rápido e pequeno. É un formato de serialización de datos binarios que permite intercambiar datos entre varios idiomas.

No primeiro nivel temos Thrift coa información mínima necesaria para que o router reenvíe a mensaxe. No segundo nivel hai estruturas msgpack empaquetadas.

Escollemos msgpack porque é máis rápido e compacto en comparación con JSON. Pero o máis importante é que admite tipos de datos personalizados, o que nos permite usar funcións interesantes como pasar binarios en bruto ou obxectos especiais que indican a ausencia de datos, o que foi importante para o noso esquema "recente-estable".

JMESPath
JMESPath é unha linguaxe de consulta JSON.
Este é exactamente o que parece a descrición que obtemos da documentación oficial de JMESPath, pero, de feito, fai moito máis que iso. JMESPath permítelle buscar e filtrar subárbores nunha estrutura de árbore arbitraria e aplicar cambios aos datos sobre a marcha. Tamén permite engadir filtros especiais e procedementos de transformación de datos. Aínda que, por suposto, require un esforzo cerebral para comprender.

Jinja
Para algúns consumidores, necesitamos converter a configuración nun ficheiro, polo que usamos un motor de modelos e Jinja é a opción obvia. Coa súa axuda, xeramos un ficheiro de configuración a partir do modelo e dos datos recibidos no destino.

Para xerar un ficheiro de configuración, necesitamos unha solicitude JMESPath, un modelo para a localización do ficheiro no FS e un modelo para a propia configuración. Tamén é unha boa idea nesta fase aclarar os permisos dos ficheiros. Todo isto combinouse con éxito nun só ficheiro: antes do inicio do modelo de configuración, puxemos unha cabeceira en formato YAML que describe o resto.

Por exemplo:

---
selector: "[@][[email protected]._meta.version == `42`] | items([0].fft_config || `{}`)"
destination_filename: "fft/{{ match[0] }}.json"
file_mode: 0644
reload_daemons: [fft] ...
{{ dict(match[1]) | json(indent=2, sort_keys=True) }}

Para crear un ficheiro de configuración para un servizo novo, só engadimos un ficheiro modelo novo. Non se requiren cambios no código fonte nin no software nos puntos de presenza.

Que cambiou desde que QControl comezou a funcionar? O primeiro e máis importante é a entrega consistente e fiable de actualizacións de configuración a todos os nodos da rede. O segundo é recibir unha poderosa ferramenta para comprobar a configuración e facer cambios nela polo noso equipo de soporte, así como polos consumidores do servizo.

Puidemos facer todo isto usando o esquema de actualización recente-estable para simplificar a comunicación entre o servidor de configuración e os destinatarios da configuración. Usando un protocolo de dúas capas para admitir unha forma independente do contido de encamiñar datos. Integración satisfactoria dun motor de xeración de configuración baseado en Jinja nunha rede de filtrado distribuída. Este sistema admite unha ampla gama de métodos de configuración para os nosos periféricos distribuídos e heteroxéneos.

Grazas pola túa axuda para escribir o material. VolanDamrod, serenheit, NonN.

Versión en inglés publicación.

Fonte: www.habr.com

Engadir un comentario