A Kubernetes operator for managing Proxmox Virtual Environment (VE) virtual machines through declarative Machine CRDs. Built with the vitistack/common framework.
- Declarative VM Management: Create and manage Proxmox VMs using Kubernetes CRDs
- Flexible Authentication: Support for both username/password and API token authentication
- Intelligent Node Selection: Configurable strategies for VM placement across Proxmox cluster nodes
- ISO Validation: Pre-creation validation ensures ISOs exist before VM provisioning
- Kubernetes-Native: Full integration with Kubernetes controller-runtime and conditions
- Configurable Storage & Network: Environment-based configuration for different Proxmox setups
- Production Ready: Comprehensive error handling, logging, and monitoring
- Kubernetes cluster (v1.19+)
- Proxmox Virtual Environment (v6.0+)
- vitistack/common CRDs installed
- Go 1.26+ (for development)
# Add the vitistack helm repository
helm repo add vitistack https://charts.vitistack.io
helm repo update
# Install the operator
helm install proxmox-operator vitistack/proxmox-operator# Clone the repository
git clone https://github.com/vitistack/proxmox-operator.git
cd proxmox-operator
# Build and deploy
make deployCreate a .env file or set environment variables:
# Required: Proxmox Connection
PROXMOX_ENDPOINT=https://your-proxmox-host:8006
PROXMOX_USERNAME=root@pam
PROXMOX_PASSWORD=your-proxmox-password
# Optional: Authentication (alternative to username/password)
# PROXMOX_TOKEN_ID=your-token-id
# PROXMOX_TOKEN_SECRET=your-token-secret
# Optional: TLS and Security
PROXMOX_INSECURE_TLS=false
# Optional: VM Management
PROXMOX_VM_ID_START=2000
PROXMOX_NODE_SELECTION=first
PROXMOX_ALLOWED_NODES=
PROXMOX_DEFAULT_STORAGE=local-lvm
PROXMOX_DEFAULT_NETWORK=vmbr0
# Optional: Logging
LOG_LEVEL=info
LOG_JSON=true| Variable | Default | Description |
|---|---|---|
PROXMOX_ENDPOINT |
- | Proxmox API endpoint URL (including /api2/json) |
PROXMOX_USERNAME |
- | Proxmox username (e.g., root@pam) |
PROXMOX_PASSWORD |
- | Proxmox password |
PROXMOX_TOKEN_ID |
- | API token ID (alternative auth) |
PROXMOX_TOKEN_SECRET |
- | API token secret (alternative auth) |
PROXMOX_INSECURE_TLS |
false |
Skip TLS certificate verification |
PROXMOX_VM_ID_START |
2000 |
Starting VM ID for new machines |
PROXMOX_NODE_SELECTION |
first |
Node selection strategy (first, random, round-robin) |
PROXMOX_ALLOWED_NODES |
- | Comma-separated list of allowed nodes |
PROXMOX_DEFAULT_STORAGE |
local-lvm |
Default storage pool for VM disks |
PROXMOX_DEFAULT_NETWORK |
vmbr0 |
Default network bridge for VMs |
PROXMOX_NETWORK_MODEL |
virtio |
Network model (virtio, e1000, e1000e, rtl8139, vmxnet3) |
PROXMOX_DEFAULT_VLAN |
0 |
Fallback VLAN if no NetworkNamespace found (0 = no VLAN tagging) |
PROXMOX_DEFAULT_MTU |
0 |
Default MTU (0 = Proxmox default 1500, common: 1500, 9000) |
PROXMOX_DEFAULT_CPU_TYPE |
x86-64-v2-AES |
CPU type for VMs (e.g., host, kvm64) |
PROXMOX_ENABLE_NUMA |
true |
Enable NUMA for VMs |
PROXMOX_SCSI_CONTROLLER |
virtio-scsi-single |
SCSI controller type |
PROXMOX_ENABLE_QEMU_AGENT |
true |
Enable QEMU Guest Agent |
PROXMOX_START_ON_CREATE |
true |
Start VM immediately after creation |
IP_SOURCE |
proxmox |
IP source: proxmox (QEMU agent) or networkconfiguration (Kea DHCP) |
MAC_SET |
24 |
Second octet for generated MAC addresses (format: 02:XX:...) |
-
Ensure MachineClasses are available:
kubectl get machineclasses
-
Create a Machine:
apiVersion: vitistack.io/v1alpha1 kind: Machine metadata: name: my-proxmox-vm namespace: default spec: name: my-proxmox-vm machineClass: small # Uses pre-installed machineclass os: family: linux distribution: debian version: "12" imageID: "local:iso/debian-12-netinst.iso" # Must be uploaded to Proxmox network: assignPublicIP: false interfaces: - name: eth0 primary: true disks: - name: root sizeGB: 20 boot: true provider: proxmox
-
Apply and monitor:
kubectl apply -f machine.yaml kubectl get machines -w
See the examples/ directory for complete examples including:
- Debian netinstall VM creation
- MachineClass definitions
- Configuration templates
The operator extends the vitistack/common Machine CRD with Proxmox-specific functionality.
The operator populates comprehensive status information from the Proxmox VM:
status:
phase: Running
state: running # VM state from Proxmox (running, stopped, paused)
providerID: proxmox://pve1/2001
machineID: "2001"
provider: proxmox
hostname: my-proxmox-vm
region: pve1 # Proxmox node name
zone: pve1 # Proxmox node name
cpus: 4
memory: 4294967296 # Memory in bytes
creationTime: "2025-12-07T10:00:00Z"
lastUpdated: "2025-12-07T10:05:00Z"
# Network information (requires QEMU Guest Agent)
ipAddresses:
- 192.168.1.100
ipv6Addresses:
- "2001:db8::1"
privateIPAddresses:
- 192.168.1.100
publicIPAddresses: []
networkInterfaces:
- name: eth0
macAddress: "BC:24:11:XX:XX:XX"
ipAddresses:
- 192.168.1.100
ipv6Addresses:
- "2001:db8::1"
state: up
type: ethernet
conditions:
- type: Ready
status: "True"
reason: VMRunning
message: "VM successfully created and running"
lastTransitionTime: "2025-12-07T10:00:00Z"| Field | Description |
|---|---|
phase |
Current lifecycle phase (Pending, Creating, Running, Terminating, Terminated, Failed) |
state |
VM state from Proxmox (running, stopped, paused) |
providerID |
Unique identifier in format proxmox://node/vmid |
machineID |
Proxmox VM ID |
provider |
Always proxmox for this operator |
hostname |
VM name from Proxmox |
region / zone |
Proxmox node name where VM is running |
cpus |
Number of CPU cores assigned |
memory |
Memory in bytes |
creationTime |
When the VM was created |
lastUpdated |
Last status sync timestamp |
ipAddresses |
All IPv4 addresses (requires QEMU Guest Agent) |
ipv6Addresses |
All IPv6 addresses (requires QEMU Guest Agent) |
privateIPAddresses |
RFC 1918 private IPv4 addresses |
publicIPAddresses |
Public IPv4 addresses |
networkInterfaces |
Detailed per-interface network info |
Note: Network information (IP addresses, interfaces) requires the QEMU Guest Agent to be installed and running inside the VM. Enable it with
PROXMOX_ENABLE_QEMU_AGENT=true.
Ready: Overall machine readinessCreating: VM creation in progressVMRunning: VM successfully createdISOValidationFailed: ISO not found in storageVMCreationFailed: VM creation failedVMProvisioningFailed: VM provisioning failedStopping: VM is being stoppedTerminating: VM deletion in progressTerminated: VM successfully deletedDeletionFailed: VM deletion failedVMDeleted: VM was deleted externally from Proxmox
cpu.cores: Number of CPU coresmemory.quantity: Memory allocation (e.g.,2Gi,4096Mi)machineProviders: Must include"proxmox"
# Clone and setup
git clone https://github.com/vitistack/proxmox-operator.git
cd proxmox-operator
# Install dependencies
go mod download
# Run tests
make test
# Run linter
make lint
# Build
make build
# Run locally (requires Kubernetes cluster)
make runβββ cmd/ # Application entrypoints
βββ internal/
β βββ consts/ # Configuration constants
β βββ controller/ # Kubernetes controllers
β βββ services/ # Business logic services
β βββ settings/ # Configuration management
βββ examples/ # Usage examples
βββ hack/ # Build and deployment scripts
βββ config/ # Kubernetes manifests
βββ test/ # Integration tests
# Unit tests
make test
# Linting
make lint
# Security scanning
make gosec
# Format code
make fmt
# Run all checks
make test && make lint && make gosecWe welcome contributions! Please see our Contributing Guide for details.
- Fork the repository
- Create a feature branch:
git checkout -b feature/your-feature - Make your changes with tests
- Run the full test suite:
make ci - Submit a pull request
- Go 1.26+ compatible
- Follow standard Go formatting (
gofmt) - Comprehensive test coverage
- Security-first approach (passes
gosec) - Kubernetes API conventions
Licensed under the Apache License, Version 2.0. See LICENSE for details.
- vitistack/common - Shared CRDs and utilities
- go-proxmox - Proxmox API client
- controller-runtime - Kubernetes operator framework
- Issues: GitHub Issues
- Discussions: GitHub Discussions
- Documentation: Wiki
Happy ProxMoxing! π