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.
8 lines
130 B
Ruby
8 lines
130 B
Ruby
# frozen_string_literal: true
|
|
|
|
require_relative "../model"
|
|
|
|
class LoadBalancersVms < Sequel::Model
|
|
include ResourceMethods
|
|
end
|