Top Tags

Fedora VM Server. Best alternative to Proxmox and VMware Setup

VM server based on Fedora 42 server edition. No need Proxmox or VMware ESXi.

Introduction

Fedora Server provides an enterprise-grade virtualization platform using KVM (Kernel-based Virtual Machine) and libvirt - the same technologies that power major cloud providers and hypervisors like Proxmox and OpenStack. Unlike proprietary solutions (VMware ESXi) or dedicated hypervisors (Proxmox), Fedora Server offers a complete Linux environment with virtualization capabilities, giving you flexibility for both VM hosting and container workloads.

Why Choose Fedora as a Virtualization Host?

FeatureFedora ServerProxmox VEVMware ESXi
Base SystemFull Linux OSDebian-basedProprietary
License CostFreeFree (paid support)Paid
HypervisorKVM/QEMUKVM/QEMUESXi
Container RuntimePodman (native)LXC/DockerNone
Web ManagementCockpitProxmox UIvCenter
CLI AccessFull Linux shellLimitedVery limited
Package Updatesdnf (latest)apt (stable)VMware patches

Architecture Overview

The virtualization stack consists of several layers:

  • KVM - Kernel module that turns Linux into a Type-1 hypervisor
  • QEMU - Hardware emulator that provides virtual hardware devices
  • libvirt - Virtualization API and daemon for managing VMs
  • virt-manager - Desktop GUI for VM management
  • Cockpit - Web-based administration interface

Setup Fedora VM Server

The @virtualization group installs all necessary packages including QEMU, libvirt, virt-install, and related tools.

bash
1sudo dnf install @virtualization
2sudo systemctl enable --now libvirtd

Verify KVM Hardware Support

Before creating VMs, verify that your CPU supports hardware virtualization (Intel VT-x or AMD-V):

bash
1# Check if KVM modules are loaded
2lsmod | grep kvm
3
4# Verify hardware virtualization support
5egrep -c '(vmx|svm)' /proc/cpuinfo
6# Output > 0 means virtualization is supported
7
8# Detailed CPU flags check
9cat /proc/cpuinfo | grep -E '(vmx|svm|ept|npt)'

Expected output for Intel CPUs shows kvm_intel, for AMD shows kvm_amd:

plaintext
1kvm_intel 458752 0
2kvm 1339392 1 kvm_intel
3irqbypass 12288 1 kvm

Configure libvirt for Non-Root Access

Add your user to the libvirt group to manage VMs without sudo:

bash
1# Add current user to libvirt group
2sudo usermod -aG libvirt $(whoami)
3
4# Apply group changes (or logout/login)
5newgrp libvirt
6
7# Verify access
8virsh list --all

Network Configuration

libvirt creates a default NAT network (virbr0). For production servers, you may want to configure bridged networking:

bash
1# View existing networks
2virsh net-list --all
3
4# View default network details
5virsh net-info default
6
7# Start and autostart default network
8virsh net-start default
9virsh net-autostart default

For bridged networking (VMs get IPs from your LAN DHCP):

bash
1# Create bridge interface using NetworkManager
2sudo nmcli connection add type bridge ifname br0 con-name br0
3sudo nmcli connection add type ethernet ifname eth0 master br0
4
5# Activate the bridge
6sudo nmcli connection up br0

Storage Pool Configuration

Configure dedicated storage pools for VM images:

bash
1# Create directory for VM images
2sudo mkdir -p /var/lib/libvirt/images
3
4# Define and start a storage pool
5virsh pool-define-as default dir --target /var/lib/libvirt/images
6virsh pool-start default
7virsh pool-autostart default
8
9# View pool information
10virsh pool-info default

Tools

Cockpit provides a modern web interface for server administration, and the cockpit-machines module adds VM management capabilities.

bash
1sudo dnf install cockpit cockpit-machines
2sudo systemctl enable --now cockpit.socket

Accessing Cockpit

After installation, access the web interface at https://your-server-ip:9090. The interface provides:

  • Virtual Machines - Create, start, stop, and console access
  • Storage - Manage disks and storage pools
  • Networking - Configure network interfaces and bridges
  • Terminal - Web-based terminal access
  • Users - System user management
  • Services - systemd service control

Firewall Configuration

If firewalld is active, allow Cockpit access:

bash
1# Allow Cockpit through firewall
2sudo firewall-cmd --permanent --add-service=cockpit
3sudo firewall-cmd --reload
4
5# Verify
6sudo firewall-cmd --list-services

Additional Cockpit Modules

Extend Cockpit functionality with additional packages:

bash
1# Storage management (LVM, RAID, etc.)
2sudo dnf install cockpit-storaged
3
4# Container management
5sudo dnf install cockpit-podman
6
7# Performance monitoring (PCP)
8sudo dnf install cockpit-pcp
9
10# Software updates
11sudo dnf install cockpit-packagekit

Creating Virtual Machines

Using virt-install (CLI)

Create VMs from the command line for automation and scripting:

bash
1# Download Fedora cloud image
2curl -LO https://download.fedoraproject.org/pub/fedora/linux/releases/42/Cloud/x86_64/images/Fedora-Cloud-Base-42-1.1.x86_64.qcow2
3
4# Create VM from cloud image
5virt-install \
6 --name fedora-vm \
7 --memory 4096 \
8 --vcpus 2 \
9 --disk path=/var/lib/libvirt/images/fedora-vm.qcow2,size=40 \
10 --os-variant fedora42 \
11 --network network=default \
12 --graphics vnc \
13 --import \
14 --noautoconsole

Common virt-install Options

OptionDescriptionExample
--nameVM name--name myvm
--memoryRAM in MB--memory 8192
--vcpusCPU cores--vcpus 4
--diskStorage config--disk size=50
--cdromISO installer--cdrom /path/to.iso
--networkNetwork type--network bridge=br0
--os-variantOS optimization--os-variant ubuntu24.04
--graphicsDisplay type--graphics spice

virsh Management Commands

bash
1# List all VMs
2virsh list --all
3
4# Start a VM
5virsh start vm-name
6
7# Graceful shutdown
8virsh shutdown vm-name
9
10# Force stop
11virsh destroy vm-name
12
13# Delete VM (keeps disk)
14virsh undefine vm-name
15
16# Delete VM with storage
17virsh undefine vm-name --remove-all-storage
18
19# Console access
20virsh console vm-name
21
22# View VM configuration
23virsh dumpxml vm-name

Podman Container

Podman is a daemonless container engine that's fully compatible with Docker but runs rootless by default, providing enhanced security.

bash
1sudo dnf install podman
2podman machine init
3podman machine start

Rootless Container Execution

Podman's primary advantage is running containers without root privileges:

bash
1# Verify rootless setup
2podman info | grep -i rootless
3
4# Run container as regular user
5podman run --rm alpine:latest id
6# Output: uid=0(root) gid=0(root) - root inside, your user outside
7
8# Check user namespace mapping
9podman unshare cat /proc/self/uid_map

Container Networking

Podman supports multiple networking modes for different use cases:

bash
1# Default bridge networking with port mapping
2podman run -d -p 8080:80 --name webserver nginx:alpine
3
4# Connect to multiple networks with static IPs
5podman run --network net1:ip=10.89.1.5 --network net2:ip=10.89.10.10 alpine ip addr
6
7# Host networking (container uses host network stack)
8podman run --network host nginx:alpine
9
10# Create custom network
11podman network create mynetwork
12podman run --network mynetwork alpine

Volume Mounts and Persistence

bash
1# Mount host directory with SELinux context
2podman run -v ~/data:/data:Z alpine:latest ls -la /data
3
4# Named volumes for persistence
5podman volume create mydata
6podman run -v mydata:/app/data alpine
7
8# Bind mount with read-only access
9podman run -v /etc/hosts:/etc/hosts:ro alpine cat /etc/hosts

Podman Compose

Use Docker Compose files with Podman:

bash
1# Install podman-compose
2sudo dnf install podman-compose
3
4# Run compose file
5podman-compose up -d
6
7# Or use podman's built-in compose
8podman compose up -d

Systemd Integration

Generate systemd service files for containers:

bash
1# Generate systemd unit for existing container
2podman generate systemd --name mycontainer --files
3
4# Enable container to start on boot
5systemctl --user enable container-mycontainer.service
6systemctl --user start container-mycontainer.service
7
8# For rootful containers
9sudo systemctl enable container-mycontainer.service

Container Resource Limits

bash
1# Limit CPU and memory
2podman run --cpus 2 --memory 1g nginx:alpine
3
4# CPU shares (relative weight)
5podman run --cpu-shares 512 nginx:alpine
6
7# Memory with swap limit
8podman run --memory 1g --memory-swap 2g nginx:alpine

Performance Tuning

CPU Pinning for VMs

Pin virtual CPUs to physical cores for consistent performance. Edit VM configuration:

xml
1<vcpu placement='static'>4</vcpu>
2<cputune>
3 <vcpupin vcpu="0" cpuset="2"/>
4 <vcpupin vcpu="1" cpuset="3"/>
5 <vcpupin vcpu="2" cpuset="4"/>
6 <vcpupin vcpu="3" cpuset="5"/>
7 <emulatorpin cpuset="0-1"/>
8</cputune>

Apply with: virsh edit vm-name

Hugepages for Memory Performance

Enable hugepages for VMs with large memory allocations:

bash
1# Check current hugepage configuration
2cat /proc/meminfo | grep Huge
3
4# Allocate hugepages (2MB pages, allocate 4GB worth)
5echo 2048 | sudo tee /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages
6
7# Make persistent in /etc/sysctl.conf
8echo "vm.nr_hugepages = 2048" | sudo tee -a /etc/sysctl.conf

I/O Tuning

Use virtio drivers for best I/O performance:

bash
1# Create VM with virtio disk and network
2virt-install \
3 --name fast-vm \
4 --memory 8192 \
5 --vcpus 4 \
6 --disk path=/var/lib/libvirt/images/fast-vm.qcow2,size=100,bus=virtio,cache=writeback \
7 --network network=default,model=virtio \
8 --os-variant fedora42 \
9 --cdrom /path/to/fedora.iso

Backup and Snapshots

VM Snapshots

bash
1# Create snapshot
2virsh snapshot-create-as vm-name snapshot1 "Before update"
3
4# List snapshots
5virsh snapshot-list vm-name
6
7# Revert to snapshot
8virsh snapshot-revert vm-name snapshot1
9
10# Delete snapshot
11virsh snapshot-delete vm-name snapshot1

Backup VM Images

bash
1# Shutdown VM for consistent backup
2virsh shutdown vm-name
3
4# Copy disk image
5cp /var/lib/libvirt/images/vm-name.qcow2 /backup/
6
7# Export VM configuration
8virsh dumpxml vm-name > /backup/vm-name.xml
9
10# Compress backup
11qemu-img convert -c -O qcow2 vm-name.qcow2 vm-name-backup.qcow2

Monitoring and Troubleshooting

Resource Monitoring

bash
1# VM statistics
2virt-top
3
4# Detailed VM info
5virsh dominfo vm-name
6virsh domstats vm-name
7
8# CPU usage
9virsh cpu-stats vm-name
10
11# Memory stats (requires balloon driver)
12virsh dommemstat vm-name

Log Files

Key log locations for troubleshooting:

LogPathPurpose
libvirtd/var/log/libvirt/libvirtd.loglibvirt daemon logs
QEMU/var/log/libvirt/qemu/vm-name.logPer-VM QEMU logs
Cockpitjournalctl -u cockpitCockpit service logs
Podmanpodman logs container-nameContainer stdout/stderr
bash
1# Enable debug logging for libvirt
2sudo virsh -c qemu:///system managedsave-define --config \
3 "<libvirtd><log_level>1</log_level></libvirtd>"
4
5# View QEMU process for specific VM
6ps aux | grep qemu | grep vm-name