Die Proxmox VE-Weboberfläche ist komfortabel — aber bei 50 VMs, wiederkehrenden Aufgaben oder Multi-Cluster-Umgebungen stößt man schnell an Grenzen. Die Proxmox REST-API bietet programmatischen Zugriff auf sämtliche Funktionen: VMs erstellen, starten, stoppen, klonen, Snapshots anlegen, Backup-Jobs triggern und Cluster-Status abfragen. Mit der Python-Bibliothek proxmoxer wird die Automatisierung besonders einfach.
API-Zugang einrichten
API-Token erstellen
API-Tokens sind die empfohlene Methode für den programmatischen Zugriff. Im Gegensatz zu Benutzername/Passwort laufen Tokens nicht ab und können granulare Berechtigungen erhalten.
- Navigieren Sie in der Weboberfläche zu Datacenter → Permissions → API Tokens
- Klicken Sie auf Add:
- User: root@pam (oder ein dedizierter API-User)
- Token ID: automation
- Privilege Separation: Aktiviert (empfohlen)
- Notieren Sie den angezeigten Token-Wert — er wird nur einmal angezeigt
Das Token-Format ist: user@realm!tokenid=token-uuid
Beispiel: root@pam!automation=a1b2c3d4-e5f6-7890-abcd-ef1234567890
Dedizierten API-User erstellen
Für Produktivumgebungen sollte ein dedizierter User mit minimalen Rechten verwendet werden:
# User erstellen
pveum user add apiuser@pve
# API-Token erstellen
pveum user token add apiuser@pve automation
# Rolle zuweisen (nur benötigte Rechte)
pveum aclmod / -user apiuser@pve -role PVEVMAdmin
pveum aclmod /storage -user apiuser@pve -role PVEDatastoreUser
Benutzerdefinierte Rolle mit minimalen Rechten
pveum role add AutomationRole -privs "VM.Allocate VM.Audit VM.Clone VM.Config.Disk VM.Config.Memory VM.Config.Network VM.Config.Options VM.Console VM.PowerMgmt VM.Snapshot Datastore.AllocateSpace Datastore.Audit"
pveum aclmod / -user apiuser@pve -role AutomationRole
proxmoxer installieren und verbinden
Installation
pip install proxmoxer requests
Verbindung mit API-Token
from proxmoxer import ProxmoxAPI
proxmox = ProxmoxAPI(
'pve01.example.com',
user='apiuser@pve',
token_name='automation',
token_value='a1b2c3d4-e5f6-7890-abcd-ef1234567890',
verify_ssl=False # Nur für Self-Signed Certs
)
# Verbindung testen
version = proxmox.version.get()
print(f"Proxmox VE {version['version']} (Release {version['release']})")
Verbindung mit Benutzername/Passwort
proxmox = ProxmoxAPI(
'pve01.example.com',
user='root@pam',
password='geheim',
verify_ssl=False
)
Die Token-Methode ist vorzuziehen, da sie kein Passwort im Code erfordert und die Token-UUID in einer Umgebungsvariable gespeichert werden kann.
VMs erstellen
Einfache VM erstellen
def create_vm(node, vmid, name, cores=2, memory=4096, disk_size='32G'):
"""Erstellt eine neue VM mit Grundkonfiguration."""
proxmox.nodes(node).qemu.create(
vmid=vmid,
name=name,
cores=cores,
memory=memory,
cpu='host',
ostype='l26',
scsihw='virtio-scsi-single',
scsi0=f'local-zfs:{disk_size},iothread=1,discard=on',
net0='virtio,bridge=vmbr0,firewall=1',
boot='order=scsi0;ide2',
agent='enabled=1',
onboot=1,
start=0 # Nicht automatisch starten
)
print(f"VM {vmid} ({name}) auf {node} erstellt")
# Beispiel
create_vm('pve01', 200, 'web-server-01', cores=4, memory=8192, disk_size='64G')
VM aus Template klonen
def clone_vm(node, template_id, new_vmid, name, full_clone=True):
"""Klont eine VM aus einem Template."""
proxmox.nodes(node).qemu(template_id).clone.create(
newid=new_vmid,
name=name,
full=1 if full_clone else 0,
target=node
)
print(f"VM {new_vmid} ({name}) aus Template {template_id} geklont")
# Beispiel: 5 Web-Server aus Template klonen
for i in range(5):
clone_vm('pve01', 9000, 300 + i, f'web-{i+1:02d}')
Cloud-Init-VM erstellen
def create_cloudinit_vm(node, vmid, name, template_id, ip, gateway,
cores=2, memory=2048, ssh_keys=None):
"""Erstellt eine VM aus Cloud-Init-Template mit Netzwerkkonfiguration."""
# Template klonen
proxmox.nodes(node).qemu(template_id).clone.create(
newid=vmid,
name=name,
full=1
)
# Cloud-Init-Parameter setzen
config = {
'cores': cores,
'memory': memory,
'ipconfig0': f'ip={ip}/24,gw={gateway}',
'nameserver': '10.0.20.1',
'searchdomain': 'example.com',
}
if ssh_keys:
config['sshkeys'] = ssh_keys
proxmox.nodes(node).qemu(vmid).config.put(**config)
print(f"Cloud-Init VM {vmid} ({name}) mit IP {ip} konfiguriert")
# Beispiel
create_cloudinit_vm(
node='pve01',
vmid=210,
name='db-server-01',
template_id=9001,
ip='10.0.20.50',
gateway='10.0.20.1',
cores=4,
memory=16384
)
VMs steuern: Start, Stop, Reboot
Einzelne VM steuern
def vm_action(node, vmid, action):
"""Führt eine Aktion auf einer VM aus (start, stop, reboot, shutdown, reset)."""
endpoint = getattr(proxmox.nodes(node).qemu(vmid).status, action)
task = endpoint.post()
print(f"VM {vmid}: {action} ausgeführt (Task: {task})")
return task
# Beispiele
vm_action('pve01', 200, 'start')
vm_action('pve01', 200, 'shutdown') # ACPI Shutdown (sauber)
vm_action('pve01', 200, 'stop') # Sofortiger Stop (wie Stecker ziehen)
vm_action('pve01', 200, 'reboot') # ACPI Reboot
Mehrere VMs gleichzeitig starten
import time
def bulk_start(node, vmids, delay=5):
"""Startet mehrere VMs mit optionaler Verzögerung."""
for vmid in vmids:
try:
status = proxmox.nodes(node).qemu(vmid).status.current.get()
if status['status'] != 'running':
vm_action(node, vmid, 'start')
time.sleep(delay)
else:
print(f"VM {vmid} läuft bereits")
except Exception as e:
print(f"Fehler bei VM {vmid}: {e}")
# Alle Webserver starten
bulk_start('pve01', [300, 301, 302, 303, 304])
Auf Task-Abschluss warten
import time
def wait_for_task(node, task_id, timeout=300):
"""Wartet auf den Abschluss eines Proxmox-Tasks."""
start = time.time()
while time.time() - start < timeout:
task_status = proxmox.nodes(node).tasks(task_id).status.get()
if task_status['status'] == 'stopped':
if task_status.get('exitstatus') == 'OK':
print(f"Task {task_id} erfolgreich abgeschlossen")
return True
else:
print(f"Task {task_id} fehlgeschlagen: {task_status.get('exitstatus')}")
return False
time.sleep(2)
print(f"Task {task_id} Timeout nach {timeout}s")
return False
Cluster-Status abfragen
Cluster-Übersicht
def get_cluster_status():
"""Zeigt den Cluster-Status aller Nodes."""
nodes = proxmox.nodes.get()
print(f"{'Node':<15} {'Status':<10} {'CPU':<10} {'RAM':<15} {'Uptime':<12}")
print("-" * 62)
for node in nodes:
cpu_pct = f"{node['cpu'] * 100:.1f}%"
ram_used = node['mem'] / (1024**3)
ram_total = node['maxmem'] / (1024**3)
ram_str = f"{ram_used:.1f}/{ram_total:.1f} GB"
uptime_days = node['uptime'] // 86400
print(f"{node['node']:<15} {node['status']:<10} {cpu_pct:<10} "
f"{ram_str:<15} {uptime_days} Tage")
get_cluster_status()
Beispielausgabe:
Node Status CPU RAM Uptime
--------------------------------------------------------------
pve01 online 23.4% 48.2/128.0 GB 142 Tage
pve02 online 31.7% 62.1/128.0 GB 142 Tage
pve03 online 18.9% 35.8/128.0 GB 89 Tage
VM-Inventar über alle Nodes
def get_all_vms():
"""Listet alle VMs im Cluster mit Status und Ressourcen."""
vms = []
for node in proxmox.nodes.get():
for vm in proxmox.nodes(node['node']).qemu.get():
vms.append({
'node': node['node'],
'vmid': vm['vmid'],
'name': vm.get('name', 'unnamed'),
'status': vm['status'],
'cpu': vm.get('cpus', 0),
'mem_gb': vm.get('maxmem', 0) / (1024**3),
'disk_gb': vm.get('maxdisk', 0) / (1024**3),
})
return sorted(vms, key=lambda x: x['vmid'])
# Als Tabelle ausgeben
vms = get_all_vms()
for vm in vms:
print(f"[{vm['node']}] VM {vm['vmid']}: {vm['name']} "
f"({vm['status']}, {vm['cpu']} CPU, {vm['mem_gb']:.0f} GB RAM)")
Snapshots verwalten
def create_snapshot(node, vmid, name, description='', include_ram=False):
"""Erstellt einen Snapshot einer VM."""
proxmox.nodes(node).qemu(vmid).snapshot.create(
snapname=name,
description=description,
vmstate=1 if include_ram else 0
)
print(f"Snapshot '{name}' für VM {vmid} erstellt")
def list_snapshots(node, vmid):
"""Listet alle Snapshots einer VM."""
snapshots = proxmox.nodes(node).qemu(vmid).snapshot.get()
for snap in snapshots:
if snap['name'] != 'current':
print(f" {snap['name']}: {snap.get('description', '')} "
f"({snap.get('snaptime', 'N/A')})")
def rollback_snapshot(node, vmid, name):
"""Rollt eine VM auf einen Snapshot zurück."""
proxmox.nodes(node).qemu(vmid).snapshot(name).rollback.post()
print(f"VM {vmid} auf Snapshot '{name}' zurückgesetzt")
# Vor Update: Snapshot erstellen
create_snapshot('pve01', 200, 'pre-update-2026-04',
description='Vor Kernel-Update')
Backup-Jobs automatisieren
Einzelnes Backup starten
def backup_vm(node, vmid, storage='pbs-backup', mode='snapshot',
compress='zstd'):
"""Startet ein Backup einer VM."""
task = proxmox.nodes(node).vzdump.create(
vmid=vmid,
storage=storage,
mode=mode,
compress=compress,
notes_template='{{guestname}} - API Backup {{date}}'
)
print(f"Backup für VM {vmid} gestartet (Task: {task})")
return task
backup_vm('pve01', 200)
Alle VMs einer Gruppe sichern
def backup_vms_by_tag(tag, storage='pbs-backup'):
"""Sichert alle VMs mit einem bestimmten Tag/Pool."""
vms = get_all_vms()
for vm in vms:
if vm['status'] == 'running':
config = proxmox.nodes(vm['node']).qemu(vm['vmid']).config.get()
if tag in config.get('tags', ''):
print(f"Backup: VM {vm['vmid']} ({vm['name']}) auf {vm['node']}")
backup_vm(vm['node'], vm['vmid'], storage=storage)
# Alle VMs mit Tag "production" sichern
backup_vms_by_tag('production')
Storage-Status abfragen
def get_storage_status():
"""Zeigt den Storage-Status aller Nodes."""
for node_info in proxmox.nodes.get():
node = node_info['node']
print(f"\n=== {node} ===")
storages = proxmox.nodes(node).storage.get()
for s in storages:
if s.get('active'):
used_pct = (s.get('used', 0) / s.get('total', 1)) * 100
total_tb = s.get('total', 0) / (1024**4)
used_tb = s.get('used', 0) / (1024**4)
print(f" {s['storage']:<20} {used_tb:.2f}/{total_tb:.2f} TB "
f"({used_pct:.1f}%) [{s['type']}]")
get_storage_status()
Praxisbeispiel: Deployment-Script
Ein vollständiges Script, das eine Umgebung aus mehreren VMs erstellt:
#!/usr/bin/env python3
"""Proxmox Deployment Script: Web-Applikation mit DB und Load Balancer."""
import os
import sys
import time
from proxmoxer import ProxmoxAPI
# Konfiguration aus Umgebungsvariablen
PVE_HOST = os.environ.get('PVE_HOST', 'pve01.example.com')
PVE_USER = os.environ.get('PVE_USER', 'apiuser@pve')
PVE_TOKEN_NAME = os.environ.get('PVE_TOKEN_NAME', 'automation')
PVE_TOKEN_VALUE = os.environ['PVE_TOKEN_VALUE']
TEMPLATE_ID = 9001 # Debian 12 Cloud-Init Template
NETWORK = '10.0.20'
GATEWAY = '10.0.20.1'
DEPLOYMENT = [
{'vmid': 400, 'name': 'lb-01', 'ip': f'{NETWORK}.40', 'cores': 2, 'mem': 2048},
{'vmid': 401, 'name': 'web-01', 'ip': f'{NETWORK}.41', 'cores': 4, 'mem': 4096},
{'vmid': 402, 'name': 'web-02', 'ip': f'{NETWORK}.42', 'cores': 4, 'mem': 4096},
{'vmid': 403, 'name': 'db-01', 'ip': f'{NETWORK}.43', 'cores': 4, 'mem': 8192},
]
def main():
proxmox = ProxmoxAPI(PVE_HOST, user=PVE_USER,
token_name=PVE_TOKEN_NAME,
token_value=PVE_TOKEN_VALUE,
verify_ssl=False)
node = 'pve01'
for vm in DEPLOYMENT:
print(f"Erstelle {vm['name']} (VMID {vm['vmid']})...")
proxmox.nodes(node).qemu(TEMPLATE_ID).clone.create(
newid=vm['vmid'], name=vm['name'], full=1)
time.sleep(3)
proxmox.nodes(node).qemu(vm['vmid']).config.put(
cores=vm['cores'], memory=vm['mem'],
ipconfig0=f"ip={vm['ip']}/24,gw={GATEWAY}",
tags='webapp;production')
proxmox.nodes(node).qemu(vm['vmid']).status.start.post()
print(f" {vm['name']} gestartet mit IP {vm['ip']}")
print("\nDeployment abgeschlossen.")
if __name__ == '__main__':
main()
Sicherheitshinweise
- Tokens statt Passwörter: Verwenden Sie immer API-Tokens mit minimalen Rechten
- Umgebungsvariablen: Speichern Sie Token-Werte nie im Code, sondern in Umgebungsvariablen oder einem Secret Manager
- TLS verifizieren: Setzen Sie
verify_ssl=Trueund verwenden Sie gültige Zertifikate in Produktivumgebungen - Audit-Log: Proxmox protokolliert alle API-Zugriffe — prüfen Sie regelmäßig
/var/log/pveproxy/access.log - Rate Limiting: Begrenzen Sie API-Aufrufe in Ihren Scripts, um den Cluster nicht zu überlasten
Fazit
Die Proxmox REST-API mit proxmoxer macht Infrastruktur-Automatisierung zugänglich. Ob VM-Deployments, Backup-Orchestrierung oder Cluster-Monitoring — Python-Scripts ersetzen repetitive manuelle Arbeit in der Weboberfläche und ermöglichen reproduzierbare, versionierte Infrastruktur. Die Kombination aus API-Tokens mit minimalen Rechten und Umgebungsvariablen für Credentials hält die Automatisierung sicher.
Mehr zu diesen Themen:
Weitere Artikel
Backup-Strategie für KMU: Proxmox PBS + TrueNAS als zuverlässiges Backup-Konzept
Backup-Strategie für KMU mit Proxmox PBS und TrueNAS: 3-2-1-Regel umsetzen, PBS als primäres Backup-Target, TrueNAS-Replikation als Offsite-Kopie, Retention Policies und automatisierte Restore-Tests.
Proxmox Notification-System: Matcher, Targets, SMTP, Gotify und Webhooks
Proxmox Notification-System ab PVE 8.1 konfigurieren: Matcher und Targets, SMTP-Setup, Gotify-Integration, Webhook-Targets, Notification-Filter und sendmail vs. neue API.
Proxmox Cluster-Netzwerk richtig planen: Corosync, Migration, Storage und Management
Proxmox Cluster-Netzwerk designen: Corosync-Ring, Migration-Network, Storage-Network für Ceph/iSCSI, Management-VLAN, Bonding/LACP und MTU 9000 — mit Beispiel-Topologien.