Щёлкать мышой по графическому интерфейсу это конечно замечательно, но когда нужно сделать много однотипных действий над множеством серверов, то хочется завести смышлёную обезьянку или автоматизировать процесс. Proxmox VE предоставляет API, с помощью которого легко на любом языке программирования сделать требуемое. Можно даже использовать простой curl и дёргать параметры. В данной статье рассмотрен инструмент командной строки pvesh, который полезен в скриптах админа.
В одной из задач мне понадобилась таблица всех виртуальных машин, отсортированная от большего к меньшему по суммарному размеру виртуальных жёстких дисков. Вызов pvesh get /cluster/resources --type vm --output-format json, даёт много информации по виртуальным машинам, но, к сожаление, в выводе maxdisk у каждой ВМ - это размер её первого диска и только! Если у ВМ несколько виртуальных жёстких дисков, то maxdisk это не учитывает и информация получается неверной.
Пришлось сваять bash скрипт и позвать на помощь команду pvesm list для вашего конкретного хранилища, в котором собственно и хранятся виртуальные жёсткие диски (images). Так как хранилищем у меня является Ceph, то в скрипте можно видеть вызов pvesm list rbd. Берите скрипт infoVM.sh, модифицируйте под свои нужды, делайте исполняемым (chmod a+x infoVM.sh) и вызывайте для получения итоговой таблицы infoVM_report.csv, где подсчитаны суммы всех дисков конкретной ВМ.
#!/bin/bash
# vasilisc 2025
# инфо про ВМ - сортировка по суммарному размеру дисков
echo "VMID,NODE,NAME,TAGS,MAXCPU,MAXMEM,SIZE_B,SIZE_GB">infoVM_report.csv
# получаем инфу про ВМ - к сожалению maxdisk только про первый диск, даже если у ВМ их несколько
pvesh get /cluster/resources --type vm --output-format json | \
jq -r '.[] | [.vmid, .node, .name, .tags, .maxcpu, .maxmem] | @csv' > tmp.csv
# обходной манёвр - подсчитываем размеры дисков у ВМ
pvesm list rbd | grep -F images | tr -s ' ' | cut -d ' ' -f4,5 | awk '{print $2, $1}' | \
awk '$1!=p{ if (NR>1) print p, s; p=$1; s=0} {s+=$2} END{print p, s}' | \
sort -k2 -nr | tr ' ' ',' | while IFS=',' read -r vmid sizealldisks
do
s=`grep -m 1 -F "${vmid}," tmp.csv`
sizealldisks_GB=`echo "${sizealldisks}" | awk '{print $1/1024/1024/1024 " GB"}'`
echo "${s},${sizealldisks},\"${sizealldisks_GB}\"" >> infoVM_report.csv
done
rm -f tmp.csv
exit
Очень полезно страховаться на случай ошибок. Создание снимков (snapshot) перед обновлением виртуального сервера является хорошей идеей. Для создания снимков нужно использовать команду pvesh create /nodes/ИМЯ_НОДЫ/qemu/НОМЕР_VMID/snapshot -snapname "before_update" -vmstate false
Как получить ИМЯ_НОДЫ, на которой работает НОМЕР_VMID? Можно вызвать pvesh get /cluster/resources -type vm и получить JSON ответ в виде
{
"cpu" : 0,
"disk" : 0,
"diskread" : 32432430,
"diskwrite" : 45654650,
"id" : "qemu/123",
"maxcpu" : 1,
"maxdisk" : 34359738368,
"maxmem" : 536870912,
"mem" : 0,
"name" : "server_www",
"netin" : 3345430,
"netout" : 54675670,
"node" : "node1",
"status" : "running",
"template" : 0,
"type" : "qemu",
"uptime" : 0,
"vmid" : 123
},
...
Но лично я выбрал другой путь, возможно не идеальный. ИМЯ_НОДЫ взял из одноимённых каталогов - /etc/pve/nodes/, а НОМЕР_VMID из одноимённых конфигурационных файлов. Если вам нужно делать снимки ВСЕХ серверов, а не только ЗАПУЩЕННЫХ, то удалите защищающий if.
#!/bin/bash
for node in `ls -1 /etc/pve/nodes/`; do
for f in `find /etc/pve/nodes/${node} -name "*.conf"`; do
VMID=$(basename "${f}" .conf)
path2conf=`realpath ${f}`
nameVM=`cat ${path2conf} | grep -m 1 name | cut -d":" -f2 | tr -d ' '`
echo "node [${node}] -> ${nameVM} (${VMID}) -> ${path2conf}"
vmstatus=`pvesh get /nodes/${node}/qemu/${VMID}/status/current | grep -F '"status"' | cut -d'"' -f4`
if [ ${vmstatus} == 'running' ]; then
echo "create snapshot"
pvesh create /nodes/${node}/qemu/${VMID}/snapshot -snapname "before_update" -vmstate false
fi
echo "--------------"
done
done
exit 0
Для удаления снимков нужно использовать команду pvesh delete /nodes/ИМЯ_НОДЫ/qemu/НОМЕР_VMID/snapshot/ИМЯ_СНИМКА
#!/bin/bash
for node in `ls -1 /etc/pve/nodes/`; do
for f in `find /etc/pve/nodes/${node} -name "*.conf"`; do
VMID=$(basename "${f}" .conf)
path2conf=`realpath ${f}`
nameVM=`cat ${path2conf} | grep -m 1 name | cut -d":" -f2 | tr -d ' '`
echo "node [${node}] -> ${nameVM} (${VMID}) -> ${path2conf}"
vmstatus=`pvesh get /nodes/${node}/qemu/${VMID}/status/current | grep -F '"status"' | cut -d'"' -f4`
if [ ${vmstatus} == 'running' ]; then
echo "delete snapshot"
pvesh delete /nodes/${node}/qemu/${VMID}/snapshot/before_update
fi
done
done
exit 0
Вам нужно сделать 3 этапа:
pvesh create /nodes/kvm01/storage/local/content -filename vm-101-disk-0.qcow2 -format qcow2 -size 32G -vmid 101
pvesh create /nodes/kvm01/qemu -vmid 101 -memory 2048 -sockets 1 -cores 4 -net0 e1000,bridge=vmbr0 -net1 e1000,bridge=vmbr1 -ide0=local:101/vm-101-disk-0.qcow2 -ide2 local:iso/ubuntu-14.04-server-amd64.iso,media=cdrom
pvesh create /nodes/kvm01/qemu/101/status/start
Через веб-интерфейс Proxmox VE вы можете наблюдать графики по потреблению различных ресурсов.

Можно сделать запрос к RRD и получить готовое изображение в формате PNG. Недостаток в том, что ответ придёт в JSON и картинка будет в значении поля image. В примере подразумеваем ноду p1 и ВМ с идентификатором 107. Подробности /nodes/{node}/qemu/{vmid}/rrd
Вот так можно получить готовое изображение в виде файла.
#!/bin/bash
pvesh get /nodes/p1/qemu/107/rrd -timeframe week -ds maxmem | python -c "import json,sys; f = open('maxmem.png', 'w+'); f.write( json.loads( str(sys.stdin.read()))['image'].encode('raw_unicode_escape'))"
Возможности актуальной версии Proxmox Virtual Environment
Дополнительные материалы:
Оглавление статей о продуктах компании Proxmox Server Solutions GmbH.
Proxmox VE API.
Обновление Proxmox VE 3.4 до 4.
Замена сбойного диска в корне ZFS RAID 1 Proxmox 3.4.
Proxmox VE.
Отдайте моё назад.
Балансировка виртуальных машин.
Перезагрузка в командной строке виртуальной машины Proxmox VE.
Как я сел ваять скрипт и нашёл 2 бага.
Быстрое и безопасное увеличение корневого раздела с файловой системой ext4.