Files
gh-basher83-lunar-claude-pl…/skills/proxmox-infrastructure/reference/qemu-guest-agent.md
2025-11-29 18:00:27 +08:00

9.0 KiB

QEMU Guest Agent Integration

Overview

The QEMU Guest Agent (qemu-guest-agent) is a service running inside VMs that enables communication between Proxmox and the guest OS. It provides IP address detection, graceful shutdowns, filesystem freezing for snapshots, and more.

Why Use QEMU Guest Agent?

Without Guest Agent:

  • VM IP address unknown to Proxmox
  • Shutdown = hard power off
  • Snapshots don't freeze filesystem (risk of corruption)
  • No guest-level monitoring

With Guest Agent:

  • Automatic IP address detection
  • Graceful shutdown/reboot
  • Consistent snapshots with filesystem freeze
  • Execute commands inside VM
  • Query guest information (hostname, users, OS details)

Installation in Guest VM

Ubuntu/Debian

sudo apt update
sudo apt install qemu-guest-agent
sudo systemctl enable qemu-guest-agent
sudo systemctl start qemu-guest-agent

RHEL/Rocky/AlmaLinux

sudo dnf install qemu-guest-agent
sudo systemctl enable qemu-guest-agent
sudo systemctl start qemu-guest-agent

Verify Installation

systemctl status qemu-guest-agent

Expected output:

● qemu-guest-agent.service - QEMU Guest Agent
     Loaded: loaded (/lib/systemd/system/qemu-guest-agent.service; enabled)
     Active: active (running)

Enable in VM Configuration

Via Proxmox Web UI

VM → Hardware → Add → QEMU Guest Agent

OR edit VM options:

VM → Options → QEMU Guest Agent → Edit → Check "Use QEMU Guest Agent"

Via CLI

qm set <vmid> --agent 1

With custom options:

# Enable with filesystem freeze support
qm set <vmid> --agent enabled=1,fstrim_cloned_disks=1

Via Terraform

resource "proxmox_vm_qemu" "vm" {
  name = "my-vm"
  # ... other config ...

  agent = 1  # Enable guest agent
}

Via Ansible

- name: Enable QEMU guest agent
  community.proxmox.proxmox_kvm:
    api_host: "{{ proxmox_api_host }}"
    api_user: "{{ proxmox_api_user }}"
    api_token_id: "{{ proxmox_token_id }}"
    api_token_secret: "{{ proxmox_token_secret }}"
    node: foxtrot
    vmid: 101
    agent: 1
    update: true

Using Guest Agent

Check Agent Status

Via CLI:

# Test if agent is responding
qm agent 101 ping

# Get guest info
qm agent 101 info

# Get network interfaces
qm agent 101 network-get-interfaces

# Get IP addresses
qm agent 101 get-osinfo

Example output:

{
  "result": {
    "id": "ubuntu",
    "kernel-release": "5.15.0-91-generic",
    "kernel-version": "#101-Ubuntu SMP",
    "machine": "x86_64",
    "name": "Ubuntu",
    "pretty-name": "Ubuntu 22.04.3 LTS",
    "version": "22.04",
    "version-id": "22.04"
  }
}

Execute Commands

Via CLI:

# Execute command in guest
qm guest exec 101 -- whoami

# With arguments
qm guest exec 101 -- ls -la /tmp

Via Python API:

from proxmoxer import ProxmoxAPI

proxmox = ProxmoxAPI('192.168.3.5', user='root@pam', password='pass')

# Execute command
result = proxmox.nodes('foxtrot').qemu(101).agent.exec.post(
    command=['whoami']
)

# Get execution result
pid = result['pid']
exec_status = proxmox.nodes('foxtrot').qemu(101).agent('exec-status').get(pid=pid)
print(exec_status)

Graceful Shutdown/Reboot

Shutdown (graceful with agent):

# Sends ACPI shutdown to guest, waits for agent to shutdown OS
qm shutdown 101

# Force shutdown if doesn't complete in 60s
qm shutdown 101 --timeout 60 --forceStop 1

Reboot:

qm reboot 101

Snapshot Integration

Filesystem Freeze for Consistent Snapshots

When guest agent is enabled, Proxmox can freeze the filesystem before taking a snapshot, ensuring consistency.

Create snapshot with FS freeze:

# Guest agent automatically freezes filesystem
qm snapshot 101 before-upgrade --vmstate 0 --description "Before upgrade"

Rollback to snapshot:

qm rollback 101 before-upgrade

Delete snapshot:

qm delsnapshot 101 before-upgrade

IP Address Detection

Automatic IP Assignment

With guest agent, Proxmox automatically detects VM IP addresses.

View in Web UI:

VM → Summary → IPs section shows detected IPs

Via CLI:

qm agent 101 network-get-interfaces | jq '.result[] | select(.name=="eth0") | ."ip-addresses"'

Via Python:

interfaces = proxmox.nodes('foxtrot').qemu(101).agent('network-get-interfaces').get()

for iface in interfaces['result']:
    if iface['name'] == 'eth0':
        for ip in iface.get('ip-addresses', []):
            if ip['ip-address-type'] == 'ipv4':
                print(f"IPv4: {ip['ip-address']}")

Advanced Configuration

Guest Agent Options

Full options syntax:

qm set <vmid> --agent [enabled=]<1|0>[,fstrim_cloned_disks=<1|0>][,type=<virtio|isa>]

Parameters:

  • enabled - Enable/disable guest agent (default: 1)
  • fstrim_cloned_disks - Run fstrim after cloning disk (default: 0)
  • type - Agent communication type: virtio or isa (default: virtio)

Example:

# Enable with fstrim on cloned disks
qm set 101 --agent enabled=1,fstrim_cloned_disks=1

Filesystem Trim (fstrim)

For VMs on thin-provisioned storage (LVM-thin, CEPH), fstrim helps reclaim unused space.

Manual fstrim:

# Inside VM
sudo fstrim -av

Automatic on clone:

qm set <vmid> --agent enabled=1,fstrim_cloned_disks=1

Scheduled fstrim (inside VM):

# Enable weekly fstrim timer
sudo systemctl enable fstrim.timer
sudo systemctl start fstrim.timer

Cloud-Init Integration

Include in Cloud-Init Template

During template creation:

# Install agent package
virt-customize -a ubuntu-22.04.img \
  --install qemu-guest-agent \
  --run-command "systemctl enable qemu-guest-agent"

# Create VM from image
qm create 9000 --name ubuntu-template --memory 2048 --cores 2 --net0 virtio,bridge=vmbr0
qm importdisk 9000 ubuntu-22.04.img local-lvm
qm set 9000 --scsihw virtio-scsi-pci --scsi0 local-lvm:vm-9000-disk-0
qm set 9000 --agent 1  # Enable guest agent
qm set 9000 --ide2 local-lvm:cloudinit
qm template 9000

Cloud-Init User Data

Include in cloud-init config:

#cloud-config
packages:
  - qemu-guest-agent

runcmd:
  - systemctl enable qemu-guest-agent
  - systemctl start qemu-guest-agent

Troubleshooting

Guest Agent Not Responding

1. Check if service is running in guest:

# Inside VM
systemctl status qemu-guest-agent
journalctl -u qemu-guest-agent

2. Check if agent is enabled in VM config:

# On Proxmox host
qm config 101 | grep agent

3. Check virtio serial device:

# Inside VM
ls -l /dev/virtio-ports/
# Should show: org.qemu.guest_agent.0

4. Restart agent:

# Inside VM
sudo systemctl restart qemu-guest-agent

5. Check Proxmox can communicate:

# On Proxmox host
qm agent 101 ping

IP Address Not Detected

Possible causes:

  1. Guest agent not running
  2. Network interface not configured
  3. DHCP not assigning IP
  4. Firewall blocking communication

Debug:

# Check all interfaces
qm agent 101 network-get-interfaces | jq

# Verify cloud-init completed
# Inside VM
cloud-init status

Filesystem Freeze Timeout

Symptoms:

Snapshot creation hangs or times out.

Solution:

# Disable FS freeze for snapshots
qm set 101 --agent enabled=1

# Take snapshot without FS freeze
qm snapshot 101 test --vmstate 0

Agent Installed but Not Enabled

Check VM config:

qm config 101 | grep agent

If missing, enable:

qm set 101 --agent 1

Restart VM for changes to take effect:

qm reboot 101

Best Practices

  1. Always install in templates - Include qemu-guest-agent in VM templates
  2. Enable during provisioning - Set --agent 1 when creating VMs
  3. Use for production VMs - Critical for graceful shutdowns and monitoring
  4. Enable fstrim for thin storage - Helps reclaim space on LVM-thin and CEPH
  5. Test before snapshots - Verify agent works: qm agent <vmid> ping
  6. Cloud-init integration - Automate installation via cloud-init packages
  7. Monitor agent status - Check agent is running in monitoring tools

Ansible Automation Example

---
- name: Ensure QEMU guest agent is configured
  hosts: proxmox_vms
  become: true
  tasks:
    - name: Install qemu-guest-agent
      ansible.builtin.apt:
        name: qemu-guest-agent
        state: present
      when: ansible_os_family == "Debian"

    - name: Enable and start qemu-guest-agent
      ansible.builtin.systemd:
        name: qemu-guest-agent
        enabled: true
        state: started

    - name: Verify agent is running
      ansible.builtin.systemd:
        name: qemu-guest-agent
      register: agent_status

    - name: Report agent status
      ansible.builtin.debug:
        msg: "Guest agent is {{ agent_status.status.ActiveState }}"

Further Reading