Использование go-qemu и go-libvirt

QEMU – это виртуализатор и эмулятор машин, который может поддерживать работу большого количества облачных серверов. Для управления серверами обычно используется virsh, клиент командной строки, который взаимодействует с демоном libvirt.

При разработке и развёртывании проектов Go вам могут понадобиться простые и производительные блоки для управления серверами. Такие пакеты должны:

  • Предоставлять хорошо продуманный и документированный API.
  • Исключать использование CGO и поддерживать кросс-компиляцию.
  • Взаимодействовать с сокетами QEMU для обеспечения максимального контроля.

Всем этим требованиям отвечают go-qemu и go-libvirt, приложения для управления libvirt и QEMU.

Как работает QEMU и go-qemu?

QEMU обеспечивает уровень аппаратной эмуляции между облачными и физическими серверами. Каждый процесс QEMU предоставляет JSON API через сокет UNIX или TCP (это как REST API при работе с веб-сервисами). Обмен данными осуществляется не через HTTP, а через протокол QEMU Monitor Protocol (QMP). При запросе действия (например, отключения сервера) запрос передается процессу QEMU через сокет QMP в таком виде:

{ "execute" : "system_powerdown" }

go-qemu – это пакет Go, который предоставляет простой интерфейс для взаимодействия с экземплярами QEMU по QMP. Он позволяет управлять виртуальными машинами QEMU непосредственно: либо с помощью monitor-сокета виртуальной машины, либо проксируя запрос через libvirt.

Все взаимодействия go-qemu зависят от типов qemu.Domain и qmp.Monitor: тип qemu.Domain основан на qmp.Monitor, который взаимодействует с monitor-сокетом виртуальной машины.

Как работает libvirt и go-libvirt?

Пакет libvirt был разработан для клиент-серверного взаимодействия. Пользователи обычно взаимодействуют с демоном libvirt с помощью клиента командной строки virsh. Клиент virsh устанавливает соединение с демоном через локальный UNIX-сокет или TCP-соединение. Соединение использует асинхронный протокол, который добавляет в каждый RPC-запрос или ответ заголовок, описывающий входящую полезную нагрузку. Заголовок содержит идентификатор процедуры (например, start domain), тип запроса (например, call или reply) и уникальный серийный номер, который используется для корреляции RPC-вызовов с соответствующими ответами. Полезная нагрузка после заголовка кодируется в XDR, предоставляя архитектурно независимый метод для описания типов данных.

go-libvirt – это пакет Go, предоставляющий удобный Go-интерфейс для libvirt. Пакет go-libvirt можно использовать в сочетании с go-qemu ля управления виртуальными машинами путём проксирования соединений с помощью демона libvirt.

go-libvirt использует протокол RPC для взаимодействия без cgo и привязок C. Конечно, использовать C проще, но cgo лучше избегать.

Чистая библиотека Go разгружает конвейеры сборки, а также упрощает управление зависимостями и кросс-компиляцию.

Отказываясь от библиотеки С, внимательно следите за изменениями в новых версиях libvirt; разработчики libvirt в любое время могут изменить протокол RPC, а это может стать причиной сбоев go-libvirt. Для обеспечения стабильности и совместимости с различными версиями libvirt пакет go-libvirt установлен и запущен в Travis CI, что позволяет проводить интеграционные тесты каждого нововведения go-libvirt.

Пример

Следующий код демонстрирует использование go-qemu и go-libvirt для взаимодействия с виртуальными машинами, управляемыми с помощью libvirt.

package main
import (
"fmt"
"log"
"net"
"time"
"github.com/digitalocean/go-qemu/hypervisor"
)
func main() {
driver := hypervisor.NewRPCDriver(func() (net.Conn, error) {
return net.DialTimeout("unix", "/var/run/libvirt/libvirt-sock", 2*time.Second)
})
hv := hypervisor.New(driver)
fmt.Println("Domain\t\tQEMU Version")
fmt.Println("--------------------------------------")
domains, err := hv.Domains()
if err != nil {
log.Fatal(err)
}
for _, dom := range domains {
version, err := dom.Version()
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s\t\t%s\n", dom.Name, version)
dom.Close()
}
}
Domain        QEMU Version
----------------------------
Droplet-1        2.7.0
Droplet-2        2.6.0
Droplet-3        2.5.0

Что дальше?

Пакеты go-qemu и go-libvirt до сих пор находятся в стадии активной разработки. В будущем разработчики намерены предоставить дополнительный CGO QMP monitor.

go-qemu и go-libvirt уже используются в производстве, но API-интерфейсы пока что находятся в разработке и не могут считаться стабильными.

Вы также можете поучаствовать в разработке пакетов go-qemu и go-libvirt. Присоединиться к проекту можно на GitHub (freenode/#go-qemu).

Сейчас команда работает над автоматическим генерированием QMP-структур на основе спецификации QMP в go-qemu. Это сэкономит огромное количество времени и сил на разработке и позволит разработчикам встроить простые типы в типы более высокого уровня, чтобы предоставить уникальный интерфейс для взаимодействия с экземплярами QEMU.

Tags: , ,

Добавить комментарий