Un prototype de balancer UDP à l'aide de BCC (XDP / BPF)
usage: sbulb [-h] -vs VIRTUAL_SERVER
(-rs REAL_SERVER [REAL_SERVER ...] | -cfg CONFIG_FILE) -p PORT
[PORT ...] [-d {0,1,2,3,4}]
[-l {CRITICAL,ERROR,WARNING,INFO,DEBUG,TRACE}] [-mp MAX_PORTS]
[-mrs MAX_REALSERVERS] [-ma MAX_ASSOCIATIONS]
ifnet
positional arguments:
ifnet network interface to load balance (e.g. eth0)
optional arguments:
-h, --help show this help message and exit
-vs VIRTUAL_SERVER, --virtual_server VIRTUAL_SERVER
<Required> Virtual server address (e.g. 10.40.0.1)
-rs REAL_SERVER [REAL_SERVER ...], --real_server REAL_SERVER [REAL_SERVER ...]
<Required> Real server address(es) (e.g. 10.40.0.2 10.40.0.3)
-cfg CONFIG_FILE, --config_file CONFIG_FILE
<Required> a path to a file containing real server address(es).
File will be polled each second for modification and configuration
updated dynamically. A file content example :
[Real Servers]
10.0.0.4
10.0.0.2
10.0.0.6
-p PORT [PORT ...], --port PORT [PORT ...]
<Required> UDP port(s) to load balance
-d {0,1,2,3,4}, --debug {0,1,2,3,4}
Use to set bpf verbosity, 0 is minimal. (default: 0)
-l {CRITICAL,ERROR,WARNING,INFO,DEBUG,TRACE}, --loglevel {CRITICAL,ERROR,WARNING,INFO,DEBUG,TRACE}
Use to set logging verbosity. (default: ERROR)
-mp MAX_PORTS, --max_ports MAX_PORTS
Set the maximum number of port to load balance. (default: 16)
-mrs MAX_REALSERVERS, --max_realservers MAX_REALSERVERS
Set the maximum number of real servers. (default: 32)
-ma MAX_ASSOCIATIONS, --max_associations MAX_ASSOCIATIONS
Set the maximum number of associations. (default: 1048576)
This defined the maximum number of foreign peers supported at the same time.
Par exemple: sudo python3 -m sbulb eth0 -vs 10.188.7.99 -rs 10.188.100.163 10.188.100.230 -p 5683 5684
Cet équilibreur de charge peut être considéré comme un balancer NAT-4 NAT car il modifie uniquement l'adresse IP.
Pour le trafic entrant:
clientip:port/realserverip .Pour le trafic de sortie:
clientip:port/realserverip .Nous gardons cette association est une grande carte LRU aussi longtemps que possible, ce qui signifie que l'association la plus ancienne n'est supprimée que si la carte LRU est pleine et que la nouvelle association doit être créée.
L'algorithme utilisé est un simple rabat à la ronde.
Dans un cluster, la bonne pratique est généralement de partager des états entre chaque instance de serveur, mais parfois certains états ne peuvent pas être partagés ...
Par exemple, un groupe de serveurs qui ne peut pas partager la connexion DTLS, dans ce cas, vous souhaitez toujours envoyer des paquets d'un client donné au même serveur pour limiter le nombre de poignées de main.
Pour ce faire, vous devez créer une association à longue durée de vie entre le client et le serveur, mais la plupart des UDP Loadbalancer sont pour avoir une association Ephemere. La plupart du temps, cette durée de vie d'association peut être configurée et vous pouvez définir une grande valeur, mais ici grâce à la carte LRU, nous pouvons garder l'association aussi longtemps que possible.
L'autre point est la communication initiée au serveur . Nous voulons pouvoir lancer la communication à partir d'un serveur exactement comme si la communication avait été initiée par un client. Signifiant que la même table d'association est utilisée.
Il s'agit d'un simple balancer de charge et il a donc quelques limites:
Vous avez besoin:
SBULB prend en charge le mécanisme SD_notify (3), mais ne nécessite pas de bibliothèque SystemD ou aucune bibliothèque SystemD. Cela permet à SBULB de notifier SystemD lorsqu'il est prêt à accepter les connexions. Pour utiliser cette fonctionnalité, vous pouvez écrire un service comme ceci:
[Unit]
Description=UDP Load Balancer
Wants=network-online.target
[Service]
Type=notify
NotifyAccess=all
Environment=PYTHONUNBUFFERED=1
ExecStart=/usr/bin/python3 -m slulb args...
[Install]
WantedBy=multi-user.target
Voir notre page wiki à ce sujet.
Pour lancer des tests unitaires:
sudo python3 -m unittest # all tests
sudo python3 -m unittest sbulb.tests.IPv4TestCase # only 1 test case
sudo python3 -m unittest sbulb.tests.IPv4TestCase.test_lru # only 1 test
Les tests nécessitent BCC V0.14 (Python3-BPFCC) et SCAPY (Python3-Scapy).
Pourquoi XDP / BPF? Pourquoi la communauté du noyau remplace-t-elle les iptables par BPF ?.
Lisez à propos de XDP / BPF: Plongez dans BPF: une liste de matériel de lecture.
Inspirations:
Documents:
Thèse: