Files
ubicloud/model/load_balancers_vms.rb
Furkan Sahin b73b043623 Add Basic Load Balancing
This commit adds the basic Ubicloud load balancer. There are two main
parts of this commit:
1. Control plane implementation for VM <-> Load Balancer interactions.
2. Data plane implementation of the load balancer itself.

The first part involves managing the many-to-many entity relationship
between VMs and load balancers. This relationship is handled through
a join table called `load_balancers_vms`, which is automatically managed
by Sequel. Functions like `load_balancer.add_vm` create the intermediary
data in `DB[:load_balancers_vms]`.

The second part is more complex. The Ubicloud Load Balancer is
integrated into a VM's namespace. Each VM on a host has a dedicated
network namespace used for packet filtering, IPv4 NAT, and various
operational tasks. Our implementation uses nftables definitions within
the namespace. Based on packet descriptions and algorithms, we decide
whether to DNAT the packet to a neighboring VM or accept it on the
current one. We use private networking between VMs to transfer packets
when load balancing is required. Additionally, we support load balancing
for both IPv4 and IPv6. Customers can use the public IPv4 address of any
VM being load balanced. If there is only one VM, we perform port
remapping and leave the packet unchanged.

Our load balancer also supports 2 types of algorithms;
1. round_robin
2. source_hash

The important part to note for a load balancer with multiple VMs is
that, each load balancer node will keep their own round_robin counter or
the source_hash result. Therefore, if the client resolves to different
load balancer node at the DNS level, they may not see the behavior
exactly what the algorithm requires. For example, if they use
round_robin with 2 VMs;
1. The first connection is opened to vm1 which points the customer to
vm1.
2. The second connection  is opened to vm1 which points the customer to
vm2.
3. The third connection is opened to vm2 and it points the customer to
vm2.
As you can see, the expected behavior was vm1, vm2, vm1 but we broke it
because the 3rd time we went to a new load balancer.
2024-07-10 13:17:48 +02:00

8 lines
130 B
Ruby

# frozen_string_literal: true
require_relative "../model"
class LoadBalancersVms < Sequel::Model
include ResourceMethods
end