The Steel Load Balancer
A load-balancer forged in the fires of Sheffield
Prebuilt binaries for armv7
and amd64
exist in the releases page, or grab the source and go build
away 🤓
The slb automates a number of seperate tasks to provide the end user a simple to use load-balancing experience. It provides a simple API endpoint and will automatically create a load-balancer endpoint (IP address), which a user can easily add backend servers too.
Requirements
The requirements are very lightweight!!
- Linux host (running a 3.x+ kernel)
- Layer 2 network (for ARP)
- Layer 3 network (for BGP)
It supports both x86 and arm, and will run happily on a Raspberry pi!
Architecture
The Machine that is running slb will create an API endpoint on port 10001 that is used to create load-balancers, this API endpoint is used to create/update and delete load-balancer instances.
- In Layer2
slb
should be started with an IPAM range to create loadbalancers with - In layer3
slb
will use the Equinix Metal API to select an IP address.
This new load-balancer is then advertised to the outside world through either network mechanism. We can now use the API to add backend server:port
to this load-balancer instance at this point we will use IPVS to create a NAT based round-robin load-balancer instance.
The below example will create an slb
server that listens on port 10001 and will generate load-balancers in the ipamRange specified.
./slb server \
--arp \
--adapter eth0 \
--ipamRange 192.168.0.85-192.168.0.90
Example output
INFO[0000] Starting the Steel Load-Balancer
INFO[0000] API Server will be exposed on [0.0.0.0:10001]
INFO[0000] Enabled IPv4 Forwarding in the kernel
INFO[0000] Enabled Connection tracking in the kernel
The Auth token is required in order for API queries:
export PACKET_AUTH_TOKEN=""
Also required are the project and facility IDs so that Equinix Metal Elastic IPs are created in the correct facility/project.
./slb server \
--adapter lo \
--bgp \
--equinixMetal \
--project xxxx \
--facility xxxx
Example output
INFO[0000] Starting the Steel Load-Balancer
INFO[0000] API Server will be exposed on [0.0.0.0:10001]
INFO[0000] Enabled IPv4 Forwarding in the kernel
INFO[0000] Enabled IPv4 Virtual Server connection tracking in the kernel
INFO[0002] Querying BGP settings for [am6-c3.small.x86-01]
INFO[0002] Add a peer configuration for:169.254.255.1 Topic=Peer
INFO[0002] Add a peer configuration for:169.254.255.2 Topic=Peer
INFO[0007] Peer Up Key=169.254.255.1 State=BGP_FSM_OPENCONFIRM Topic=Peer
2021/11/12 13:40:02 conf:<local_as:65000 neighbor_address:"169.254.255.1" peer_as:65530 > state:<local_as:65000 neighbor_address:"169.254.255.1" peer_as:65530 session_state:ESTABLISHED router_id:"147.75.86.18" > transport:<local_address:"10.12.39.1" local_port:34481 remote_port:179 >
INFO[0008] Peer Up Key=169.254.255.2 State=BGP_FSM_OPENCONFIRM Topic=Peer
2021/11/12 13:40:03 conf:<local_as:65000 neighbor_address:"169.254.255.2" peer_as:65530 > state:<local_as:65000 neighbor_address:"169.254.255.2" peer_as:65530 session_state:ESTABLISHED router_id:"147.75.86.19" > transport:<local_address:"10.12.39.1" local_port:45091 remote_port:179 >
curl -X POST http://<host>:10001/loadbalancer -H 'Content-Type: application/json' -d '{"name":"test loadbalancer", "port": 6443}'
We can view this new loadbalancer through the API or on the cli where slb
is running!
curl -s http://<host>:10001/loadbalancers | jq
[
{
"uuid": "087fcb0f-8e07-4123-a32f-e8e83a281023",
"name": "test loadbalancer",
"eip": "147.75.84.41",
"port": 6443,
"backends": null
}
]
We can use the API to add a backend service to our load-balancer instance!
curl -X POST http://<host>:10001/loadbalancer/087fcb0f-8e07-4123-a32f-e8e83a281023/backend -d '{"ip":"10.80.96.25", "port": 6443}'
curl -s http://<node>:10001/loadbalancers | jq
[
{
"uuid": "087fcb0f-8e07-4123-a32f-e8e83a281023",
"name": "test loadbalancer",
"eip": "145.40.96.223",
"port": 6443,
"backends": [
{
"uuid": "779344ce-72ca-4aec-a1c0-d9c5c4d72419",
"ip": "10.80.96.25",
"port": 6443
}
]
}
]
On our slb node we can inspect in more detail our load-balancer setup
ipvsadm -ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 145.40.96.223:6443 rr
-> 10.80.96.25:6443 Masq 1 0 0
The following API call will delete the EIP, stop bgp and remove the IPVS service.
curl -X DELETE http://<node>:10001/loadbalancer/087fcb0f-8e07-4123-a32f-e8e83a281023