Proxmox API. Введение

в 1:02, , рубрики: api, proxmox, виртуализация, метки: ,

Всем привет!
Сегодня я бы хотел немного рассказать об использовании API небезызвестной системы виртуализации — Proxmox.

Предыстория…
С проксмоксом я столкнулся несколько лед назад, когда мне в руки попала неплохая машина, расположенная в одном из дата центров пресловутого Хетзнера. На тот момент у нас встал вопрос о поднятии виртуализации под свои нужды. Мы рассматривали несколько вариантов, а именно: VMWare, OpenStack и конечно же Proxmox. Не буду говорить, что он лучше 2-ух других кандидатов, просто на тот момент он вполне удовлетворял нашим потребностям. Через некоторое время, появилась необходимость создать своего рода панель управления для сторонних пользователей, которые могли бы просто отслеживать статус своей виртуальной машины, запускать/останавливать ВМ, делать ребут, а так же управлять несколькими настройками. Конечно же, проксмокс позволят добавлять пользователей, а так же группы пользователей и назначать им свои права. Но нам такой вариант не подходил. Не знаю как сейчас, но на тот момент нормальной документации API Proxmox на русском языке не было. Меня конечно же это не остановило и я вполне обошелся англоязычной версией, в которой кстати все очень хорошо и наглядно описано. Однако, всегда есть люди, которые не очень ладят с английским. Так вот, эта статья для Вас.
Сразу оговорюсь, что все VM (виртуальные машины) у нас были на базе KVM. Следовательно и API которое мы рассмотрим в этой статье будет для машин на базе KVM с использованием PhP.

Итак, начнем…

Для работы с их API нам понадобиться PhP класс, который можно забрать с репозитория github.
Типы запросов к серверу API делятся всего на 3 вида: GET, POST и PUT. А ответы мы будем получать в формате JSON.

Создаем файл index.php в которой инклудим скаченный нами апи класс и создаем объект.

require_once "proxmox.api.php";
$px = new PVE2_API("192.168.2.1", "root", "pam", "my_password");

где в качестве параметров указываем IP нашего сервера, логин и пароль.
По умолчанию, proxmox ставиться на 8006 порт. Однако, если Вы изменили его, то Вам так же придется изменить порт и в API классе proxmox'a. Для этого нам необходимо найти строки наподобие этой: (Таких всего 3)

curl_setopt($prox_ch, CURLOPT_URL, "https://".$this->pve_hostname.":8006/api2/json/access/ticket");

У меня это 93 строка. (На момент скачивания класса. Может быть сейчас там какие-то изменения. Я не проверял) и заменить 8006 на необходимое значение.

Для того, чтобы проверить успешно ли прошла авторизация на нашем сервере нужно использовать следующий метод:

if($px->constructor_success()){
    if($px->login()){
        // do something..
    }
}

Теперь попытаемся выполнить наш первый запрос, который выдаст нам информацию об интересующей нас VM. У каждой виртуальной машины есть свой уникальный идентификационный номер, по которому мы и будем получать информацию. Так же каждая VM может размещаться в своей «ноде» (node), которая так же участвует в запросе.

if($px->constructor_success()){
    if($px->login()){
        $status = $px->get("/nodes/node2/qemu/100/status/current");
        var_dump($status);
    }
}

где: node2 — это название используемой мною ноды, а 100 — это id VM.

В результате мы получим примерно следующее:

array(19) { 
    ["disk"]=> int(0) 
    ["status"]=> string(7) "running" 
    ["ha"]=> int(0) 
    ["freemem"]=> int(518893568) 
    ["qmpstatus"]=> string(7) "running" 
    ["netout"]=> int(214648283) 
    ["maxdisk"]=> int(21474836480) 
    ["maxmem"]=> int(3221225472) 
    ["pid"]=> string(6) "526695" 
    ["uptime"]=> int(2585643) 
    ["balloon"]=> int(3221225472) 
    ["cpu"]=> float(0.089612785396815) 
    ["netin"]=> int(3038528849) 
    ["diskread"]=> int(5224400988) 
    ["template"]=> string(0) "" 
    ["name"]=> string(15) "vds-192.168.1.9" 
    ["diskwrite"]=> int(100378349568) 
    ["mem"]=> int(2638614528) 
    ["cpus"]=> int(1) 
} 

В большей степени здесь все понятно, поэтому комментировать я не стану и мы пойдем дальше.
В предыдущем примере, где мы получали статус нашей VM мы использовали GET запрос. Как правило, GET используются для получения информации, POST и PUT для выполнения каких-то действий или изменения настроек.

Теперь попробуем остановить нашу виртуальную машину. Для этого отправим POST запрос с vmid (идентификатором виртуальной машины и нодой):

if($px->constructor_success()){
    if($px->login()){
        $px->post("/nodes/node2/qemu/192/status/shutdown", array("forceStop" => true));        
    }
}

Как видите, все довольно просто. Первым параметром POST запроса выступает инфа о нашей VM, а вторым некоторые не всегда необязательные параметры. В данном случае для наглядности я использовал параметр forceStop, который говорит сам за себя. Иногда бывают случаи, когда VM по каким причинам не может завершить свою работу «добровольно». Это может произойти по разным причинам, ошибка системы, повисший процесс и т.д. Так вот параметр forceStop говорит proxmox'u о том, что машина должна завершить свою работу в любом случае. Полный список параметров можно посмотреть в приведенной документации.

Теперь запустим обратно нашу VM.

if($px->constructor_success()){
    if($px->login()){
        $start = $px->post("/nodes/node2/qemu/192/status/start");
    }
}

Все доступные команды для статусов VM:

  • reset — своего рода ребут
  • resume — возобновляет работу VM
  • shutdown — выключает VM
  • start — запускает VM
  • stop — останавливает VM
  • suspend — приостанавливает работу VM

Перейдем к настройкам…

Получаем настройки конкретной VM, как обычно:

if($px->constructor_success()){
    if($px->login()){
        $start = $px->get("/nodes/node2/qemu/166/config");
        var_dump($start);
    }
}

Если все ок, ты мы получим следующий результат:

array(10) { 
    ["net0"]=> string(36) "e1000=9A:7B:96:C7:C4:7D,bridge=vmbr0" 
    ["ide2"]=> string(59) "local:iso/debian-6.0.7-amd64-CD-1.iso,media=cdrom,size=645M" 
    ["name"]=> string(15) "san-192.168.1.9" 
    ["bootdisk"]=> string(4) "ide0" 
    ["cores"]=> int(1) 
    ["ide0"]=> string(50) "local:166/vm-166-disk-1.qcow2,format=qcow2,size=1G" 
    ["ostype"]=> string(3) "l26" 
    ["memory"]=> int(512) 
    ["sockets"]=> int(1) 
    ["digest"]=> string(40) "2aa7fcf6cbaff2f11d2f50f1b7b18fc97d2b04d6" 
}

Для того, чтобы установить VM конфигурацию, необходимо использовать PUT запрос:

if($px->constructor_success()){
    if($px->login()){
        $px->put("/nodes/node2/qemu/166/config", array(

        ));
    }
}

где в массиве нужно указать необходимые параметры и их значение. Все параметры я не стану приводить, т.к их много и они есть и описаны в официальной документации. Обратите внимание, что для вступления некоторых надстроек в силу необходим ребут VM.

Теперь немного интересней. Иногда появляется необходимость автоматизировать процесс создания виртуальных машин. Об этом мне хотелось бы рассказать более подробно в следующей статье, но для самых нетерпеливых, небольшой пример сейчас:

if($px->constructor_success()){
    if($px->login()){
        $d = array(
            'vmid'      => '777',
            'memory'    => '300',
            'cores'     => '2',
            'autostart' => true,
            'ostype'    => 'l26',
            'ide0'      => 'local:32,format=qcow2',
            'ide2'      => 'local:iso/ubuntu-12.04.2-server-amd64.iso,media=cdrom',
            'net0'      => 'e1000,bridge=vmbr0'
        );

        $px->post("/nodes/node2/qemu", $d);
        $px->post("/nodes/node2/qemu/777/status/start");
    }
}

где:

  • vmid — уникальный идентификатор VM
  • memory — число типа (integer) обозначает размер RAM в мегабайтах
  • cores — кол-во ядер VM
  • autostart — (bool) инициировать ли автостарт VM
  • ostype — тип ОС
  • ide0 — Размер и формат HDD диска. local:32 — означает 32GB
  • ide2 — путь к образу ОС и тип бута
  • net0 — Network Adapter

На этом пока все. В следующей части я бы хотел углубиться в методы, которые описал выше, а так же рассказать о некоторых тонкостях, которые на тот момент в API я не нашел.

P.S Вместо того, чтобы просто минусовать статью, уделите немного своего времени и опишите что в ней не так, что Вам не понравилось и чтобы Вы хотели видеть еще. Это позволит мне понять мои ошибки и в дальнейшем не совершать их.

Спасибо за внимание.

Автор: byabuzyak

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js