BCC(XDP/BPF)を使用したUDPロードバランサープロトタイプ
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.
EG: sudo python3 -m sbulb eth0 -vs 10.188.7.99 -rs 10.188.100.163 10.188.100.230 -p 5683 5684
このロードバランサーは、IPアドレスのみを変更するため、レイヤー4 NATロードバランサーと見なすことができます。
イングレストラフィックの場合:
clientip:port/realserverip Associationがある場合は検索します。出力トラフィックの場合:
clientip:port/realserverip Associationがある場合は検索します。この協会は、可能な限り大きなLRUマップであることを保持します。つまり、LRUマップがいっぱいで新しいアソシエーションを作成する必要がある場合にのみ、最古の関連付けが削除されます。
使用されるアルゴリズムは、単純なラウンドロビンです。
クラスターでは、一般的には、各サーバーインスタンス間で状態を共有することですが、一部の状態は共有できません...
たとえば、DTLS接続を共有できないサーバーのクラスターなど、この場合、特定のクライアントから同じサーバーにパケットを送信して、ハンドシェイクの数を制限する必要があります。
そのためには、クライアントとサーバーの間に長寿命の関連性を作成する必要がありますが、UDPロードバランサーのほとんどは、エフェミア関連を持つためにThougthです。ほとんどの場合、この協会の寿命を構成でき、大きな価値を設定できますが、LRUマップのおかげで、できる限り協会を維持できます。
もう1つのポイントは、サーバー開始通信です。クライアントによって通信が開始されたかのように、サーバーからの通信を開始できるようにしたいと考えています。同じ関連付けテーブルが使用されます。
これは単純な負荷バランサーであるため、いくつかの制限があります。
あなたが必要です:
SBULBはSD_Notify(3)メカニズムをサポートしていますが、SystemDまたはSystemDライブラリを実行する必要はありません。これにより、sbulbが接続を受け入れる準備ができたらSystemDに通知することができます。この機能を使用するには、次のようなサービスを書くことができます。
[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
それについてのwikiページをご覧ください。
ユニットテストを開始するには:
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
テストには、BCC V0.14(Python3-BPFCC)とSCAPY(Python3-Scapy)が必要です。
なぜXDP/BPF?カーネルコミュニティがIPTABLEをBPFに置き換えるのはなぜですか?
XDP/BPFについて読む:BPFに飛び込む:読書資料のリスト。
インスピレーション:
ドキュメント:
論文 :