mirror of
https://github.com/gyptazy/ProxLB.git
synced 2026-04-05 20:31:57 +02:00
Add config exmaples to README for resource reservations on node level
Fixes: #373
This commit is contained in:
@@ -0,0 +1,2 @@
|
|||||||
|
added:
|
||||||
|
- Add resource reservation support for PVE nodes (@Chipmonk2). [#373]
|
||||||
4
.gitignore
vendored
4
.gitignore
vendored
@@ -5,7 +5,3 @@ build/
|
|||||||
dist/
|
dist/
|
||||||
*.egg-info/
|
*.egg-info/
|
||||||
proxlb_dev.yaml
|
proxlb_dev.yaml
|
||||||
log.log
|
|
||||||
proxlb/log.log
|
|
||||||
proxlb.yaml
|
|
||||||
proxlb_reservation.yaml
|
|
||||||
|
|||||||
@@ -290,6 +290,7 @@ The following options can be set in the configuration file `proxlb.yaml`:
|
|||||||
| | method | | memory | `Str` | The balancing method that should be used. [values: `memory` (default), `cpu`, `disk`]|
|
| | 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)] |
|
| | 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 |
|
| | balance_larger_guests_first | | False | `Bool` | Option to prefer larger/smaller guests first |
|
||||||
|
| | node_resource_reserve | | { default: { memory: 4 }, { node01: { memory: 6 }} } | `Dict` | A dict of pool names and their type for creating affinity/anti-affinity rules |
|
||||||
| | 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 |
|
| | 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 |
|
| | 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` | | | | | |
|
| `service` | | | | | |
|
||||||
@@ -338,6 +339,11 @@ balancing:
|
|||||||
method: memory
|
method: memory
|
||||||
mode: used
|
mode: used
|
||||||
balance_larger_guests_first: False
|
balance_larger_guests_first: False
|
||||||
|
node_resource_reserve:
|
||||||
|
defaults:
|
||||||
|
memory: 4
|
||||||
|
node01:
|
||||||
|
memory: 6
|
||||||
# # PSI thresholds only apply when using mode 'psi'
|
# # PSI thresholds only apply when using mode 'psi'
|
||||||
# # PSI based balancing is currently in beta and req. PVE >= 9
|
# # PSI based balancing is currently in beta and req. PVE >= 9
|
||||||
# psi:
|
# psi:
|
||||||
@@ -530,7 +536,7 @@ Connect with us in our dedicated chat room for immediate support and live intera
|
|||||||
| Support Channel | Link |
|
| Support Channel | Link |
|
||||||
|------|:------:|
|
|------|:------:|
|
||||||
| Matrix | [#proxlb:gyptazy.com](https://matrix.to/#/#proxlb:gyptazy.com) |
|
| Matrix | [#proxlb:gyptazy.com](https://matrix.to/#/#proxlb:gyptazy.com) |
|
||||||
| Discord | [Discord](https://discord.gg/JemGu7WbfQ) |
|
| Discord | [Discord](https://discord.gg/JemGu7WbfQ) |
|
||||||
| GitHub Community | [GitHub Community](https://github.com/gyptazy/ProxLB/discussions/)
|
| GitHub Community | [GitHub Community](https://github.com/gyptazy/ProxLB/discussions/)
|
||||||
| GitHub | [ProxLB GitHub](https://github.com/gyptazy/ProxLB/issues) |
|
| GitHub | [ProxLB GitHub](https://github.com/gyptazy/ProxLB/issues) |
|
||||||
|
|
||||||
|
|||||||
@@ -33,6 +33,11 @@ balancing:
|
|||||||
method: memory # 'memory' | 'cpu' | 'disk'
|
method: memory # 'memory' | 'cpu' | 'disk'
|
||||||
mode: used # 'assigned' | 'used' | 'psi'
|
mode: used # 'assigned' | 'used' | 'psi'
|
||||||
balance_larger_guests_first: False # Option to prioritize balancing of larger or smaller guests first
|
balance_larger_guests_first: False # Option to prioritize balancing of larger or smaller guests first
|
||||||
|
node_resource_reserve: # Optional: Define resource reservations for nodes (in GB)
|
||||||
|
defaults: # Default reservation values applying to all nodes (unless explicitly overridden)
|
||||||
|
memory: 4 # Default: 4 GB memory reserved per node
|
||||||
|
node01: # Specific node reservation override for node 'node01'
|
||||||
|
memory: 6 # Specific: 6 GB memory reserved for node 'node01'
|
||||||
# # PSI thresholds only apply when using mode 'psi'
|
# # PSI thresholds only apply when using mode 'psi'
|
||||||
# psi:
|
# psi:
|
||||||
# nodes:
|
# nodes:
|
||||||
@@ -69,15 +74,6 @@ balancing:
|
|||||||
pin: # Define a pinning og guests to specific node(s)
|
pin: # Define a pinning og guests to specific node(s)
|
||||||
- virt66
|
- virt66
|
||||||
- virt77
|
- virt77
|
||||||
# reserve some ressource for proxmox and / or other application on the nodes
|
|
||||||
node_resource_reserve:
|
|
||||||
# defaults - cpu in %, memory in GB, disk in %
|
|
||||||
defaults:
|
|
||||||
cpu: 10
|
|
||||||
memory: 4
|
|
||||||
disk: 20
|
|
||||||
node1:
|
|
||||||
memory: 4
|
|
||||||
|
|
||||||
service:
|
service:
|
||||||
daemon: True
|
daemon: True
|
||||||
|
|||||||
@@ -256,7 +256,6 @@ class Nodes:
|
|||||||
logger.debug("Finished: get_node_pve_version.")
|
logger.debug("Finished: get_node_pve_version.")
|
||||||
return version["version"]
|
return version["version"]
|
||||||
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def apply_resource_reservation(node_name, proxlb_config: Dict[str, Any], node_data: Dict[str, Any]) -> None:
|
def apply_resource_reservation(node_name, proxlb_config: Dict[str, Any], node_data: Dict[str, Any]) -> None:
|
||||||
"""
|
"""
|
||||||
@@ -264,24 +263,19 @@ class Nodes:
|
|||||||
Checks for a node specific config first, then if there is any configured default and if neither then nothing is reserved.
|
Checks for a node specific config first, then if there is any configured default and if neither then nothing is reserved.
|
||||||
Reservations are applied by directly modifying the data gathered from the nodes.
|
Reservations are applied by directly modifying the data gathered from the nodes.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
node_name: (str) the name of the node
|
node_name: (str) the name of the node
|
||||||
proxlb_config (Dict[str, Any]): A dictionary containing the ProxLB configuration.
|
proxlb_config (Dict[str, Any]): A dictionary containing the ProxLB configuration.
|
||||||
node_data: (Dict[str, Any]): Dict containing the current nodes data
|
node_data: (Dict[str, Any]): Dict containing the current nodes data
|
||||||
Returns: none
|
Returns: none
|
||||||
"""
|
"""
|
||||||
logger.debug(f"Starting: Resource reservation")
|
logger.debug(f"Starting: apply_resource_reservation")
|
||||||
logger.debug(f"Processing resource reservation for node {node_name}")
|
|
||||||
# load the balancing section from the config dict, will create an empty dict if there isnt anything
|
|
||||||
balancing_cfg = proxlb_config.get("balancing", {})
|
balancing_cfg = proxlb_config.get("balancing", {})
|
||||||
# get the reservation dict from the previously loaded dict , will create an empty dict if there isnt anything
|
reserve_cfg = balancing_cfg.get("node_resource_reserve", {})
|
||||||
reserve_cfg = balancing_cfg.get("node_resource_reserve", {})
|
|
||||||
# try to get the reserved memory for the node
|
|
||||||
reserved_memory_gb_node = reserve_cfg.get(node_name, {}).get("memory")
|
reserved_memory_gb_node = reserve_cfg.get(node_name, {}).get("memory")
|
||||||
# try to load the default reserved memory - will set to 0 if there isn't anything
|
|
||||||
reserved_memory_gb_default = reserve_cfg.get("defaults", {}).get("memory", 0)
|
reserved_memory_gb_default = reserve_cfg.get("defaults", {}).get("memory", 0)
|
||||||
|
|
||||||
# make sure the reservation is a numeric value - check for both, default and node specific
|
# Make sure the reservation is a numeric value - check for both, default and node specific
|
||||||
if not isinstance(reserved_memory_gb_default, (int, float)):
|
if not isinstance(reserved_memory_gb_default, (int, float)):
|
||||||
if reserved_memory_gb_default is not None:
|
if reserved_memory_gb_default is not None:
|
||||||
logger.info("Invalid default memory reservation: Found a string while expecting a numeric value - skipping default reservation")
|
logger.info("Invalid default memory reservation: Found a string while expecting a numeric value - skipping default reservation")
|
||||||
@@ -292,16 +286,16 @@ class Nodes:
|
|||||||
logger.info(f"Invalid memory reservation: Found a string while expecting a numeric value - applying current default of {reserved_memory_gb_default} Bytes")
|
logger.info(f"Invalid memory reservation: Found a string while expecting a numeric value - applying current default of {reserved_memory_gb_default} Bytes")
|
||||||
reserved_memory_gb_node = reserved_memory_gb_default
|
reserved_memory_gb_node = reserved_memory_gb_default
|
||||||
|
|
||||||
# make sure the reservation is positive
|
# Make sure the reservation is positive
|
||||||
if reserved_memory_gb_node < 0:
|
if reserved_memory_gb_node < 0:
|
||||||
logger.info(f"{nodes['nodes'][node['node']]['name']}: Invalid assigned memory reservation, applying defaults")
|
logger.info(f"{nodes['nodes'][node['node']]['name']}: Invalid assigned memory reservation, applying defaults")
|
||||||
reserved_memory_gb_node = reserved_memory_gb_default
|
reserved_memory_gb_node = reserved_memory_gb_default
|
||||||
|
|
||||||
# convert the reservation from GB to Bytes, get the current nodes physical memory
|
# Convert the reservation from GB to Bytes, get the current nodes physical memory
|
||||||
reserved_memory_node = int(round(reserved_memory_gb_node * 1024 ** 3))
|
reserved_memory_node = int(round(reserved_memory_gb_node * 1024 ** 3))
|
||||||
total_mem = node_data.get("memory_total")
|
total_mem = node_data.get("memory_total")
|
||||||
|
|
||||||
# check if the reservation doesnt exceed the nodes total memory
|
# Check if the reservation doesnt exceed the nodes total memory
|
||||||
if reserved_memory_node > total_mem:
|
if reserved_memory_node > total_mem:
|
||||||
logger.debug(f"Reservation of {reserved_memory_node} Bytes exceeds available memory of {total_mem} Bytes- skipping reservation")
|
logger.debug(f"Reservation of {reserved_memory_node} Bytes exceeds available memory of {total_mem} Bytes- skipping reservation")
|
||||||
reserved_memory_node = 0
|
reserved_memory_node = 0
|
||||||
@@ -310,7 +304,4 @@ class Nodes:
|
|||||||
logger.debug(f"Reserved Memory: {reserved_memory_gb_node} GB ({reserved_memory_node} Bytes)")
|
logger.debug(f"Reserved Memory: {reserved_memory_gb_node} GB ({reserved_memory_node} Bytes)")
|
||||||
node_data["memory_total"] -= reserved_memory_node
|
node_data["memory_total"] -= reserved_memory_node
|
||||||
Helper.update_node_resource_percentages(node_data)
|
Helper.update_node_resource_percentages(node_data)
|
||||||
|
logger.debug(f"Finished: apply_resource_reservation")
|
||||||
logger.debug(f"End: Resource reservation")
|
|
||||||
return
|
|
||||||
|
|
||||||
|
|||||||
@@ -362,4 +362,3 @@ class Helper:
|
|||||||
logger.debug(f"node data: {node_data}")
|
logger.debug(f"node data: {node_data}")
|
||||||
logger.debug(f"End: Update resource percentages")
|
logger.debug(f"End: Update resource percentages")
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user