mirror of
https://github.com/gyptazy/ProxLB.git
synced 2026-04-06 04:41:58 +02:00
Compare commits
20 Commits
v1.1.5
...
fix/285-au
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
155c417d39 | ||
|
|
1ff0c5d96e | ||
|
|
3eb4038723 | ||
|
|
47e7dd3c56 | ||
|
|
bb8cf9033d | ||
|
|
756b4efcbd | ||
|
|
8630333e4b | ||
|
|
7bd9a9b038 | ||
|
|
16651351de | ||
|
|
63805f1f50 | ||
|
|
c0ff1b5273 | ||
|
|
07f8596fc5 | ||
|
|
affbe433f9 | ||
|
|
7bda22e754 | ||
|
|
253dcf8eb9 | ||
|
|
6212d23268 | ||
|
|
cf8c06393f | ||
|
|
5c23fd3433 | ||
|
|
0fb732fc8c | ||
|
|
f36d96c72a |
2
.changelogs/1.1.6/268_fix_balancing_type_eval.yml
Normal file
2
.changelogs/1.1.6/268_fix_balancing_type_eval.yml
Normal file
@@ -0,0 +1,2 @@
|
||||
fixed:
|
||||
- Fix balancing evaluation of guest types (e.g., VM or CT) (@gyptazy). [#268]
|
||||
2
.changelogs/1.1.6/285_fix_authentication_timeout.yml
Normal file
2
.changelogs/1.1.6/285_fix_authentication_timeout.yml
Normal file
@@ -0,0 +1,2 @@
|
||||
fixed:
|
||||
- Fix authentication timeout in rare cases that could lead to a stacktrace (@gyptazy). [#285]
|
||||
2
.changelogs/1.1.6/290_validate_user_token_syntax.yml
Normal file
2
.changelogs/1.1.6/290_validate_user_token_syntax.yml
Normal file
@@ -0,0 +1,2 @@
|
||||
added:
|
||||
- Add validation for provided API user token id to avoid confusions (@gyptazy). [#291]
|
||||
@@ -0,0 +1,2 @@
|
||||
fixed:
|
||||
- Fix stacktrace output when validating permissions on non existing users in Proxmox (@gyptazy). [#291]
|
||||
1
.changelogs/1.1.6/release_meta.yml
Normal file
1
.changelogs/1.1.6/release_meta.yml
Normal file
@@ -0,0 +1 @@
|
||||
date: TBD
|
||||
10
README.md
10
README.md
@@ -77,6 +77,10 @@ Before starting any migrations, ProxLB validates that rebalancing actions are ne
|
||||
## Installation
|
||||
|
||||
### Requirements / Dependencies
|
||||
* Proxmox
|
||||
* Proxmox 7.x
|
||||
* Proxmox 8.x
|
||||
* Proxmox 9.x (Beta 1 tested)
|
||||
* Python3.x
|
||||
* proxmoxer
|
||||
* requests
|
||||
@@ -241,7 +245,7 @@ The following options can be set in the configuration file `proxlb.yaml`:
|
||||
| Section | Option | Sub Option | Example | Type | Description |
|
||||
|---------|:------:|:----------:|:-------:|:----:|:-----------:|
|
||||
| `proxmox_api` | | | | | |
|
||||
| | hosts | | ['virt01.example.com', '10.10.10.10', 'fe01::bad:code::cafe', 'virt01.example.com:443', '[fc00::1]', '[fc00::1]:443', 'fc00::1:8006'] | `List` | List of Proxmox nodes. Can be IPv4, IPv6 or mixed. You can specify custom ports. In case of IPv6 without brackets the port is considered after the last colon |
|
||||
| | hosts | | ['virt01.example.com', '10.10.10.10', 'fe01:bad:code::cafe', 'virt01.example.com:443', '[fc00::1]', '[fc00::1]:443', 'fc00::1:8006'] | `List` | List of Proxmox nodes. Can be IPv4, IPv6 or mixed. You can specify custom ports. In case of IPv6 without brackets the port is considered after the last colon |
|
||||
| | user | | root@pam | `Str` | Username for the API. |
|
||||
| | pass | | FooBar | `Str` | Password for the API. (Recommended: Use API token authorization!) |
|
||||
| | token_id | | proxlb | `Str` | Token ID of the user for the API. |
|
||||
@@ -251,7 +255,7 @@ The following options can be set in the configuration file `proxlb.yaml`:
|
||||
| | retries | | 1 | `Int` | How often a connection attempt to the defined API host should be performed. |
|
||||
| | wait_time | | 1 | `Int` | How many seconds should be waited before performing another connection attempt to the API host. |
|
||||
| `proxmox_cluster` | | | | | |
|
||||
| | maintenance_nodes | | ['virt66.example.com'] | `List` | A list of Proxmox nodes that are defined to be in a maintenance. |
|
||||
| | maintenance_nodes | | ['virt66.example.com'] | `List` | A list of Proxmox nodes that are defined to be in a maintenance. (must be the same node names as used within the cluster) |
|
||||
| | ignore_nodes | | [] | `List` | A list of Proxmox nodes that are defined to be ignored. |
|
||||
| | overprovisioning | | False | `Bool` | Avoids balancing when nodes would become overprovisioned. |
|
||||
| `balancing` | | | | | |
|
||||
@@ -281,7 +285,7 @@ The following options can be set in the configuration file `proxlb.yaml`:
|
||||
An example of the configuration file looks like:
|
||||
```
|
||||
proxmox_api:
|
||||
hosts: ['virt01.example.com', '10.10.10.10', 'fe01::bad:code::cafe']
|
||||
hosts: ['virt01.example.com', '10.10.10.10', 'fe01:bad:code::cafe']
|
||||
user: root@pam
|
||||
pass: crazyPassw0rd!
|
||||
# API Token method
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
proxmox_api:
|
||||
hosts: ['virt01.example.com', '10.10.10.10', 'fe01::bad:code::cafe']
|
||||
hosts: ['virt01.example.com', '10.10.10.10', 'fe01:bad:code::cafe']
|
||||
user: root@pam
|
||||
pass: crazyPassw0rd!
|
||||
# API Token method
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
6. [Parallel Migrations](#parallel-migrations)
|
||||
7. [Run as a Systemd-Service](#run-as-a-systemd-service)
|
||||
8. [SSL Self-Signed Certificates](#ssl-self-signed-certificates)
|
||||
9. [Node Maintenances](#node-maintenances)
|
||||
|
||||
## Authentication / User Accounts / Permissions
|
||||
### Authentication
|
||||
@@ -213,4 +214,25 @@ proxmox_api:
|
||||
ssl_verification: False
|
||||
```
|
||||
|
||||
*Note: Disabling SSL certificate validation is not recommended.*
|
||||
*Note: Disabling SSL certificate validation is not recommended.*
|
||||
|
||||
### Node Maintenances
|
||||
To exclude specific nodes from receiving any new workloads during the balancing process, the `maintenance_nodes` configuration option can be used. This option allows administrators to define a list of nodes that are currently undergoing maintenance or should otherwise not be used for running virtual machines or containers.
|
||||
|
||||
```yaml
|
||||
maintenance_nodes:
|
||||
- virt66.example.com
|
||||
```
|
||||
|
||||
which can also be written as:
|
||||
|
||||
```yaml
|
||||
maintenance_nodes: ['virt66.example.com']
|
||||
```
|
||||
|
||||
The maintenance_nodes key must be defined as a list, even if it only includes a single node. Each entry in the list must exactly match the node name as it is known within the Proxmox VE cluster. Do not use IP addresses, alternative DNS names, or aliases—only the actual cluster node names are valid. Once a node is marked as being in maintenance mode:
|
||||
|
||||
* No new workloads will be balanced or migrated onto it.
|
||||
* Any existing workloads currently running on the node will be migrated away in accordance with the configured balancing strategies, assuming resources on other nodes allow.
|
||||
|
||||
This feature is particularly useful during planned maintenance, upgrades, or troubleshooting, ensuring that services continue to run with minimal disruption while the specified node is being worked on.
|
||||
24
helm/proxlb/Chart.yaml
Normal file
24
helm/proxlb/Chart.yaml
Normal file
@@ -0,0 +1,24 @@
|
||||
apiVersion: v3
|
||||
name: proxlb
|
||||
description: A Helm chart for self-hosted ProxLB
|
||||
|
||||
# A chart can be either an 'application' or a 'library' chart.
|
||||
#
|
||||
# Application charts are a collection of templates that can be packaged into versioned archives
|
||||
# to be deployed.
|
||||
#
|
||||
# Library charts provide useful utilities or functions for the chart developer. They're included as
|
||||
# a dependency of application charts to inject those utilities and functions into the rendering
|
||||
# pipeline. Library charts do not define any templates and therefore cannot be deployed.
|
||||
type: application
|
||||
|
||||
# This is the chart version. This version number should be incremented each time you make changes
|
||||
# to the chart and its templates, including the app version.
|
||||
# Versions are expected to follow Semantic Versioning (https://semver.org/)
|
||||
version: "1.1.5"
|
||||
|
||||
# This is the version number of the application being deployed. This version number should be
|
||||
# incremented each time you make changes to the application. Versions are not expected to
|
||||
# follow Semantic Versioning. They should reflect the version the application is using.
|
||||
# It is recommended to use it with quotes.
|
||||
appVersion: "v1.1.5"
|
||||
13
helm/proxlb/templates/_helpers.yaml
Normal file
13
helm/proxlb/templates/_helpers.yaml
Normal file
@@ -0,0 +1,13 @@
|
||||
{{- define "proxlb.fullname" -}}
|
||||
{{- printf "%s-%s" .Release.Name .Chart.Name | trunc 63 | trimSuffix "-" -}}
|
||||
{{- end -}}
|
||||
|
||||
{{ define "proxlb.labels" }}
|
||||
app.kubernetes.io/name: {{ .Release.Name }}
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
app.kubernetes.io/version: {{ .Chart.AppVersion }}
|
||||
app.kubernetes.io/component: proxlb
|
||||
{{- if .Values.labels }}
|
||||
{{ toYaml .Values.labels }}
|
||||
{{- end }}
|
||||
{{ end }}
|
||||
11
helm/proxlb/templates/configmap.yaml
Normal file
11
helm/proxlb/templates/configmap.yaml
Normal file
@@ -0,0 +1,11 @@
|
||||
{{- if .Values.configmap.create }}
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: proxlb-config
|
||||
labels:
|
||||
{{- include "proxlb.labels" . | nindent 4 }}
|
||||
data:
|
||||
proxlb.yaml: |
|
||||
{{ toYaml .Values.configmap.config | indent 4 }}
|
||||
{{ end }}
|
||||
44
helm/proxlb/templates/deployment.yaml
Normal file
44
helm/proxlb/templates/deployment.yaml
Normal file
@@ -0,0 +1,44 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ .Release.Name }}
|
||||
labels:
|
||||
{{- include "proxlb.labels" . | nindent 4 }}
|
||||
spec:
|
||||
replicas: 1 # Number of replicas cannot be more than 1
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "proxlb.labels" . | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "proxlb.labels" . | nindent 8 }}
|
||||
spec:
|
||||
{{- with .Values.image.imagePullSecrets }}
|
||||
imagePullSecrets:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
# not interacting with the k8s cluster
|
||||
automountServiceAccountToken: False
|
||||
containers:
|
||||
- name: proxlb
|
||||
image: "{{ .Values.image.registry }}/{{ .Values.image.repository }}:{{ .Values.image.tag }}"
|
||||
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
||||
args:
|
||||
{{- if .Values.extraArgs.dryRun }}
|
||||
- --dry-run
|
||||
{{- end }}
|
||||
volumeMounts:
|
||||
- name: config
|
||||
mountPath: /etc/proxlb/proxlb.yaml
|
||||
subPath: proxlb.yaml
|
||||
{{ if .Values.resources }}
|
||||
resources:
|
||||
{{ with .Values.resources }}
|
||||
{{ toYaml . | nindent 10 }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
volumes:
|
||||
- name: config
|
||||
configMap:
|
||||
name: proxlb-config
|
||||
60
helm/proxlb/values.yaml
Normal file
60
helm/proxlb/values.yaml
Normal file
@@ -0,0 +1,60 @@
|
||||
image:
|
||||
registry: cr.gyptazy.com
|
||||
repository: proxlb/proxlb
|
||||
tag: v1.1.5
|
||||
pullPolicy: IfNotPresent
|
||||
imagePullSecrets: [ ]
|
||||
|
||||
resources:
|
||||
limits:
|
||||
cpu: "1000m"
|
||||
memory: "2Gi"
|
||||
requests:
|
||||
cpu: "100m"
|
||||
memory: "100Mi"
|
||||
|
||||
labels: {}
|
||||
|
||||
extraArgs:
|
||||
dryRun: false
|
||||
|
||||
configmap:
|
||||
create: true
|
||||
config:
|
||||
proxmox_api:
|
||||
hosts: []
|
||||
#Can be either a user or a token
|
||||
# user: ""
|
||||
# pass: ""
|
||||
# token_id: ""
|
||||
# token_secret: ""
|
||||
ssl_verification: True
|
||||
timeout: 10
|
||||
proxmox_cluster:
|
||||
maintenance_nodes: [ ]
|
||||
ignore_nodes: [ ]
|
||||
overprovisioning: True
|
||||
balancing:
|
||||
enable: True
|
||||
enforce_affinity: False
|
||||
parallel: False
|
||||
# If running parallel job, you can define
|
||||
# the amount of prallel jobs (default: 5)
|
||||
parallel_jobs: 1
|
||||
live: True
|
||||
with_local_disks: True
|
||||
balance_types: [ 'vm', 'ct' ]
|
||||
max_job_validation: 1800
|
||||
balanciness: 5
|
||||
method: memory
|
||||
mode: used
|
||||
service:
|
||||
daemon: True
|
||||
schedule:
|
||||
interval: 12
|
||||
format: "hours"
|
||||
delay:
|
||||
enable: False
|
||||
time: 1
|
||||
format: "hours"
|
||||
log_level: INFO
|
||||
@@ -1,6 +1,12 @@
|
||||
#!/usr/bin/env bash
|
||||
VERSION="1.1.4"
|
||||
|
||||
# ProxLB
|
||||
sed -i "s/^__version__ = .*/__version__ = \"$VERSION\"/" "proxlb/utils/version.py"
|
||||
sed -i "s/version=\"[0-9]*\.[0-9]*\.[0-9]*\"/version=\"$VERSION\"/" setup.py
|
||||
|
||||
# Helm Chart
|
||||
sed -i "s/^version: .*/version: \"$VERSION\"/" helm/proxlb/Chart.yaml
|
||||
sed -i "s/^appVersion: .*/appVersion: \"v$VERSION\"/" helm/proxlb/Chart.yaml
|
||||
|
||||
echo "OK: Versions have been sucessfully set to $VERSION"
|
||||
|
||||
@@ -51,14 +51,14 @@ def main():
|
||||
# Validate of an optional service delay
|
||||
Helper.get_service_delay(proxlb_config)
|
||||
|
||||
# Connect to Proxmox API & create API object
|
||||
proxmox_api = ProxmoxApi(proxlb_config)
|
||||
|
||||
# Overwrite password after creating the API object
|
||||
proxlb_config["proxmox_api"]["pass"] = "********"
|
||||
|
||||
while True:
|
||||
|
||||
# Connect to Proxmox API & create API object
|
||||
proxmox_api = ProxmoxApi(proxlb_config)
|
||||
|
||||
# Overwrite password after creating the API object
|
||||
proxlb_config["proxmox_api"]["pass"] = "********"
|
||||
|
||||
# Validate if reload signal was sent during runtime
|
||||
# and reload the ProxLB configuration and adjust log level
|
||||
if Helper.proxlb_reload:
|
||||
|
||||
@@ -90,11 +90,23 @@ class Balancing:
|
||||
|
||||
# VM Balancing
|
||||
if guest_meta["type"] == "vm":
|
||||
job_id = self.exec_rebalancing_vm(proxmox_api, proxlb_data, guest_name)
|
||||
if 'vm' in proxlb_data["meta"]["balancing"].get("balance_types", []):
|
||||
logger.debug("Balancing: Balancing for guest {guest_name} of type VM started.")
|
||||
job_id = self.exec_rebalancing_vm(proxmox_api, proxlb_data, guest_name)
|
||||
else:
|
||||
logger.debug(
|
||||
f"Balancing: Balancing for guest {guest_name} will not be performed. "
|
||||
"Guest is of type VM which is not included in allowed balancing types.")
|
||||
|
||||
# CT Balancing
|
||||
elif guest_meta["type"] == "ct":
|
||||
job_id = self.exec_rebalancing_ct(proxmox_api, proxlb_data, guest_name)
|
||||
if 'ct' in proxlb_data["meta"]["balancing"].get("balance_types", []):
|
||||
logger.debug("Balancing: Balancing for guest {guest_name} of type CT started.")
|
||||
job_id = self.exec_rebalancing_ct(proxmox_api, proxlb_data, guest_name)
|
||||
else:
|
||||
logger.debug(
|
||||
f"Balancing: Balancing for guest {guest_name} will not be performed. "
|
||||
"Guest is of type CT which is not included in allowed balancing types.")
|
||||
|
||||
# Just in case we get a new type of guest in the future
|
||||
else:
|
||||
|
||||
@@ -135,6 +135,14 @@ class ProxmoxApi:
|
||||
proxlb_credentials = proxlb_config["proxmox_api"]
|
||||
present_auth_pass = "pass" in proxlb_credentials
|
||||
present_auth_secret = "token_secret" in proxlb_credentials
|
||||
token_id = proxlb_credentials.get("token_id", None)
|
||||
|
||||
if token_id:
|
||||
non_allowed_chars = ["@", "!"]
|
||||
for char in non_allowed_chars:
|
||||
if char in token_id:
|
||||
logger.error(f"Wrong user/token format defined. User and token id must be splitted! Please see: https://github.com/gyptazy/ProxLB/blob/main/docs/03_configuration.md#required-permissions-for-a-user")
|
||||
sys.exit(1)
|
||||
|
||||
if present_auth_pass and present_auth_secret:
|
||||
logger.critical(f"Username/password and API token authentication are mutal exclusive. Please use only one!")
|
||||
@@ -336,7 +344,15 @@ class ProxmoxApi:
|
||||
permissions_available = []
|
||||
|
||||
# Get the permissions for the current user/token from API
|
||||
permissions = proxmox_api.access.permissions.get()
|
||||
try:
|
||||
permissions = proxmox_api.access.permissions.get()
|
||||
except proxmoxer.core.ResourceException as api_error:
|
||||
if "no such user" in str(api_error):
|
||||
logger.error("Authentication to Proxmox API not possible: User not known - please check your username and config file.")
|
||||
sys.exit(1)
|
||||
else:
|
||||
logger.error(f"Proxmox API error: {api_error}")
|
||||
sys.exit(1)
|
||||
|
||||
# Get all available permissions of the current user/token
|
||||
for path, permission in permissions.items():
|
||||
|
||||
Reference in New Issue
Block a user