mirror of
https://github.com/gyptazy/ProxLB.git
synced 2026-04-06 04:41:58 +02:00
Compare commits
7 Commits
v1.1.10
...
feature/38
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5101202f72 | ||
|
|
929390b288 | ||
|
|
d4560c3af4 | ||
|
|
55c885194e | ||
|
|
3d9f0eb85e | ||
|
|
490fb55ee1 | ||
|
|
a70330d4c3 |
@@ -0,0 +1,2 @@
|
||||
fixed:
|
||||
- Fixed missing overprovisioning safety guard to avoid node overprovisioning (@gyptazy). [#275]
|
||||
@@ -0,0 +1,2 @@
|
||||
fixed:
|
||||
- Fixed affinity matrix pre-validation by inverting validations (@Thalagyrt). [#335]
|
||||
@@ -0,0 +1,2 @@
|
||||
added:
|
||||
- Add possibility to sort and select balancing workloads by smaller/larger guest objects (@gyptazy). [#387]
|
||||
@@ -120,6 +120,8 @@ systemctl start proxlb
|
||||
|
||||
Afterwards, ProxLB is running in the background and balances your cluster by your defined balancing method (default: memory).
|
||||
|
||||
**Note**: If you want to use ProxLB with the proxmox-offline-mirror or any other APT mirror tool that does not support the flat repository architecture, please see the [docs](https://github.com/gyptazy/ProxLB/blob/main/docs/02_installation.md#Repo-Mirror-and-Proxmox-Offline-Mirror-Support) how you can add this by using ProxLB's fully repo.
|
||||
|
||||
#### Details
|
||||
ProxLB provides two different repositories:
|
||||
* https://repo.gyptazy.com/stable (only stable release)
|
||||
@@ -287,6 +289,7 @@ The following options can be set in the configuration file `proxlb.yaml`:
|
||||
| | memory_threshold | | 75 | `Int` | The maximum threshold (in percent) that needs to be hit to perform balancing actions. (Optional) |
|
||||
| | method | | memory | `Str` | The balancing method that should be used. [values: `memory` (default), `cpu`, `disk`]|
|
||||
| | mode | | used | `Str` | The balancing mode that should be used. [values: `used` (default), `assigned`, `psi` (pressure)] |
|
||||
| | balance_larger_guests_first | | False | `Bool` | Option to prefer larger/smaller guests first |
|
||||
| | psi | | { nodes: { memory: { pressure_full: 0.20, pressure_some: 0.20, pressure_spikes: 1.00 }}} | `Dict` | A dict of PSI based thresholds for nodes and guests |
|
||||
| | pools | | pools: { dev: { type: affinity }, de-nbg01-db: { type: anti-affinity }} | `Dict` | A dict of pool names and their type for creating affinity/anti-affinity rules |
|
||||
| `service` | | | | | |
|
||||
@@ -334,6 +337,7 @@ balancing:
|
||||
balanciness: 5
|
||||
method: memory
|
||||
mode: used
|
||||
balance_larger_guests_first: False
|
||||
# # PSI thresholds only apply when using mode 'psi'
|
||||
# # PSI based balancing is currently in beta and req. PVE >= 9
|
||||
# psi:
|
||||
|
||||
@@ -32,6 +32,7 @@ balancing:
|
||||
balanciness: 5 # Maximum delta of resource usage between highest and lowest usage node
|
||||
method: memory # 'memory' | 'cpu' | 'disk'
|
||||
mode: used # 'assigned' | 'used' | 'psi'
|
||||
balance_larger_guests_first: False # Option to prioritize balancing of larger or smaller guests first
|
||||
# # PSI thresholds only apply when using mode 'psi'
|
||||
# psi:
|
||||
# nodes:
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
- [Quick-Start](#quick-start)
|
||||
- [Details](#details)
|
||||
- [Debian Packages (.deb files)](#debian-packages-deb-files)
|
||||
- [Repo Mirror and Proxmox Offline Mirror Support](#repo-mirror-and-proxmox-offline-mirror-support)
|
||||
- [RedHat Package](#redhat-package)
|
||||
- [Container Images / Docker](#container-images--docker)
|
||||
- [Overview of Images](#overview-of-images)
|
||||
@@ -83,6 +84,27 @@ vi /etc/proxlb/proxlb.yaml
|
||||
systemctl start proxlb
|
||||
```
|
||||
|
||||
#### Repo Mirror and Proxmox Offline Mirror Support
|
||||
ProxLB uses the supported flat mirror style for the Debian repository. Unfortunately, not all offline-mirror applications support it. One of the known ones is the official *proxmox-offline-mirror* which is unable to handle flat repositories (see also: [#385](https://github.com/gyptazy/ProxLB/issues/385)).
|
||||
|
||||
Therefore, we currently operate and support both ways to avoid everyone force switching to the new repository. As a result, you can simply use this repository:
|
||||
```
|
||||
deb https://repo.gyptazy.com/proxlb stable main
|
||||
```
|
||||
|
||||
**Example Config for proxmox-offline-mirror:**
|
||||
|
||||
An example config for the proxmox-offline-mirror would look like:
|
||||
```
|
||||
mirror: proxlb
|
||||
architectures amd64
|
||||
base-dir /var/lib/proxmox-offline-mirror/mirrors/
|
||||
key-path /etc/apt/trusted.gpg.d/proxlb.asc
|
||||
repository deb https://repo.gyptazy.com/proxlb stable main
|
||||
sync true
|
||||
verify true
|
||||
```
|
||||
|
||||
### RedHat Package
|
||||
There's currently no official support for RedHat based systems. However, there's a dummy .rpm package for such systems in the pipeline which can be found here:
|
||||
* https://github.com/gyptazy/ProxLB/actions/workflows/20-pipeline-build-rpm-package.yml
|
||||
|
||||
@@ -377,7 +377,19 @@ class Calculations:
|
||||
if proxlb_data["meta"]["balancing"].get("enforce_affinity", False):
|
||||
logger.debug("Balancing of guests will be performed. Reason: enforce affinity balancing")
|
||||
|
||||
for group_name in proxlb_data["groups"]["affinity"]:
|
||||
# Sort guests by used memory
|
||||
# Allows processing larger guests first or smaller guests first
|
||||
larger_first = proxlb_data.get("meta", {}).get("balancing", {}).get("balance_larger_guests_first", False)
|
||||
|
||||
if larger_first:
|
||||
logger.debug("Larger guests will be processed first. (Sorting descending by memory used)")
|
||||
else:
|
||||
logger.debug("Smaller guests will be processed first. (Sorting ascending by memory used)")
|
||||
|
||||
sorted_guest_usage_groups = sorted(proxlb_data["groups"]["affinity"], key=lambda g: proxlb_data["groups"]["affinity"][g]["memory_used"], reverse=larger_first)
|
||||
|
||||
# Iterate over all affinity groups
|
||||
for group_name in sorted_guest_usage_groups:
|
||||
|
||||
# We get initially the node with the most free resources and then
|
||||
# migrate all guests within the group to that node to ensure the
|
||||
@@ -387,6 +399,10 @@ class Calculations:
|
||||
for guest_name in proxlb_data["groups"]["affinity"][group_name]["guests"]:
|
||||
mode = proxlb_data["meta"]["balancing"].get("mode", "used")
|
||||
|
||||
if not Calculations.validate_node_resources(proxlb_data, guest_name):
|
||||
logger.warning(f"Skipping relocation of guest {guest_name} due to insufficient resources on target node {proxlb_data['meta']['balancing']['balance_next_node']}. This might affect affinity group {group_name}.")
|
||||
continue
|
||||
|
||||
if mode == 'psi':
|
||||
logger.debug(f"Evaluating guest relocation based on {mode} mode.")
|
||||
method = proxlb_data["meta"]["balancing"].get("method", "memory")
|
||||
@@ -605,7 +621,7 @@ class Calculations:
|
||||
logger.debug(f"Affinity for guest {guest} is {'valid' if balancing_state_affinity else 'NOT valid'}")
|
||||
logger.debug(f"Anti-affinity for guest {guest} is {'valid' if balancing_state_anti_affinity else 'NOT valid'}")
|
||||
|
||||
balancing_ok = not balancing_state_affinity or not balancing_state_anti_affinity
|
||||
balancing_ok = balancing_state_affinity and balancing_state_anti_affinity
|
||||
|
||||
if balancing_ok:
|
||||
logger.debug(f"Rebalancing based on affinity/anti-affinity map is not required.")
|
||||
@@ -707,3 +723,40 @@ class Calculations:
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
@staticmethod
|
||||
def validate_node_resources(proxlb_data: Dict[str, Any], guest_name: str) -> bool:
|
||||
"""
|
||||
Validate that the target node has sufficient resources to host the specified guest.
|
||||
|
||||
This function checks if the target node, determined by the balancing logic,
|
||||
has enough CPU, memory, and disk resources available to accommodate the guest.
|
||||
|
||||
Args:
|
||||
proxlb_data (Dict[str, Any]): A dictionary containing the complete ProxLB state including:
|
||||
- "nodes": Dictionary with node resource information
|
||||
- "guests": Dictionary with guest resource requirements
|
||||
- "meta": Dictionary with balancing information including target node
|
||||
guest_name (str): The name of the guest to validate resources for
|
||||
Returns:
|
||||
bool: True if the target node has sufficient resources, False otherwise
|
||||
"""
|
||||
logger.debug("Starting: validate_node_resources.")
|
||||
node_target = proxlb_data["meta"]["balancing"]["balance_next_node"]
|
||||
|
||||
node_memory_free = proxlb_data["nodes"][node_target]["memory_free"]
|
||||
node_cpu_free = proxlb_data["nodes"][node_target]["cpu_free"]
|
||||
node_disk_free = proxlb_data["nodes"][node_target]["disk_free"]
|
||||
|
||||
guest_memory_required = proxlb_data["guests"][guest_name]["memory_used"]
|
||||
guest_cpu_required = proxlb_data["guests"][guest_name]["cpu_used"]
|
||||
guest_disk_required = proxlb_data["guests"][guest_name]["disk_used"]
|
||||
|
||||
if guest_memory_required < node_memory_free:
|
||||
logger.debug(f"Node '{node_target}' has sufficient resources for guest '{guest_name}'.")
|
||||
logger.debug("Finished: validate_node_resources.")
|
||||
return True
|
||||
else:
|
||||
logger.debug(f"Node '{node_target}' lacks sufficient resources for guest '{guest_name}'.")
|
||||
logger.debug("Finished: validate_node_resources.")
|
||||
return False
|
||||
|
||||
Reference in New Issue
Block a user