Pitone

Libvirt con Python

Libvirt con Python
In uno dei miei post precedenti, ho mostrato come iniziare con Libvirt e KVM. Questo stack di virtualizzazione non è pensato per essere utilizzato come software di virtualizzazione desktop, ma è pensato per essere eseguito su server che offrono maggiore flessibilità, efficienza e stabilità, anziché facilità d'uso. Si intende automatizzato al nquesto laurea piuttosto che affidarsi alla configurazione manuale. Quindi vediamo come puoi connetterti al tuo demone libvirt e automatizzare la gestione e il monitoraggio di base delle VM usando Python.

L'impostazione e le assunzioni di base

Sto usando un'installazione Libvirt KVM su un server Debian. Gli script Python che utilizzerò sono in esecuzione in Python 3.7.3 ambiente. Questo articolo dovrebbe farti bagnare i piedi con i collegamenti Python di Libvirt, quando stai progettando la tua applicazione dovresti sempre fare riferimento alla documentazione ufficiale che copre una vasta gamma di casi d'uso e viene aggiornata ragionevolmente spesso.

Installiamo prima tutte le dipendenze richieste per libvirt:

$ sudo apt install  pkg-config libvirt-dev
$ pip3 installa libvirt-python

Questi sono tutti i pacchetti di cui hai bisogno.

Vengono eseguiti i seguenti script e frammenti localmente sull'host Libvirt, come root, piuttosto che essere eseguito su un client remoto. È possibile accedere ai servizi in remoto, tuttavia, che richiederebbe una lunga digressione per proteggere la connessione tra il client e il server. Pertanto, ci collegheremo localmente, per semplicità.

Stabilire una connessione con il servizio Libvirtd

Per iniziare, apriamo un prompt Python, importiamo la libreria libvirt e apriamo una connessione con libvirt.metodo aperto.

root@deb:~# python3
Pitone 3.7.3 (predefinito, 15 aprile 2019, 01:55:37)
[CGC 6.3.0 20170516] su linux

Digita "aiuto", "copyright", "crediti" o "licenza" per ulteriori informazioni.

>>> importa libvirt
>>> conn = libvirt.open('qemu:///sistema')

La variabile conn può ora essere utilizzata per interrogare il tuo demone libvirt e lo faremo a breve. Ma prima, una piccola digressione.

Libvirt può essere utilizzato per gestire una serie di diversi stack di virtualizzazione e containerizzazione. KVM-QEMU, Xen e LXC sono i più popolari di questi. Quindi quando entri in libvirt.open('qemu:///system') libvirt ti consente di raccogliere informazioni e gestire i guest QEMU. Puoi anche parlare con il demone LXD o con l'hypervisor Xen usando rispettivamente lxc:///system o xen:///system.

Allo stesso modo, il metodo libvirt.open() non è l'unico a tua disposizione. open(name), openAuth(uri, auth, flags) e openReadOnly(name) sono tre chiamate differenti ognuna delle quali restituisce un oggetto virConnect e offre diversi livelli di controllo sull'host. Puoi leggere di più su di loro qui. Per ora, abbiamo conn come oggetto della classe virConnect. Questo oggetto è un gateway per fare quasi tutto, dalla configurazione dell'hypervisor stesso alla modifica dei guest e della loro allocazione delle risorse.

Una volta che hai finito di lavorare con l'oggetto, assicurati di chiudere la connessione chiamando il metodo close su di esso.

>>> conn.vicino()

Tuttavia, non eseguire ancora il comando precedente just. Perché giocheremo un po' di più con libvirt. Chiediamo al nostro hypervisor alcuni dettagli su se stesso, come il nome host e il numero di vCPU che può offrire in totale alle VM guest.

>>> conn.getHostname()
'deb'
>>> conn.getMaxVcpus('qemu')
16

Ora, dobbiamo capire che con i metadati di Libvirt su oggetti come le statistiche dell'hypervisor, le macchine virtuali, le loro informazioni di rete e di archiviazione, ecc. sono tutti rappresentati in formato XML. XML è una sorta di JSON solo un po' più goffo (e un po' più vecchio). I dati vengono archiviati e presentati come una stringa letterale e ciò significa che se si interroga libvirt e l'output di tale query è XML si otterrà un output a riga singola molto lungo con '\n' presente come stringa letterale anziché come nuova linea. La funzione di stampa integrata di Python può ripulirlo per la leggibilità umana

>>> print(conn.getSysinfo())


Dell Inc.
A14

 

Elenco e monitoraggio delle VM

Se stai mantenendo una vasta gamma di VM, hai bisogno di un metodo per creare centinaia di VM con una configurazione uniforme che anche scala correttamente da semplici carichi di lavoro a thread singolo all'elaborazione multi-core e multi-thread. Libvirt chiama le VM guest (o i container se stai usando LXC) Domini e puoi elencare le informazioni sui singoli domini e configurarli se il tuo oggetto virConnect ha privilegi sufficienti.

Per ottenere informazioni sulle VM e sul loro utilizzo delle risorse è possibile utilizzare le seguenti chiamate:

>>> conn.listDomainsID()
[4, 5]

Questo restituisce un array di ID di dominio che sono solo piccoli interi per una semplice configurazione di libvirt. Un modo più affidabile per etichettare le tue VM, senza avere due VM (diciamo su nodi diversi) con lo stesso ID o nome, è usare gli UUID. In libvirt tutto può avere un UUID, che è un numero a 128 bit generato casualmente. Le possibilità che tu crei due UUID identici sono davvero piuttosto ridotte.

La rete per le tue macchine virtuali, le VM stesse e persino gli storage pool e i volumi hanno i loro UUID individuali. Usali liberamente nel tuo codice Python, invece di fare affidamento su nomi assegnati da umani assigned. Sfortunatamente, il modo per ottenere gli UUID dei domini è un po' disordinato nell'attuale implementazione di questa libreria, secondo me. È necessario fornire l'ID della VM (l'ID del dominio), ecco come appare.

domainIDs = conn.listDomainsID()
per l'ID di dominio negli ID di dominio:
dominio = conn.ricercaPerID()
uuid = dominio.UUIDString()
stampa (uid)

Ora puoi vedere l'elenco degli UUID del dominio. Ci siamo anche imbattuti in un nuovo oggetto Python libvirt.virDomain, che ha il proprio set di metodi associati ad esso molto simile alla variabile conn che era un libvirt.virConnect e aveva metodi come listDomainsID() e lookupByID() ad esso associati.

Per entrambi questi metodi puoi usare i metodi dir() incorporati di Python in modo che gli oggetti possano elencare le loro variabili e metodi interni.

Per esempio:

>>> dir(conn)
['_… gs', 'schedulerType', 'screenshot', 'securityLabel', 'securityLabelList',
'sendKey', 'sendProcessSignal', 'setAutostart', 'setBlkioParameters', 'setBlockIoTune',
'setGuestVcpus', 'setInterfaceParameters', 'setMaxMemory', 'setMemory', 'setMemoryFlags',
'setMemoryParameters', 'setMemoryStatsPeriod', 'setMetadata', 'setNumaParameters',
'setPerfEvents', 'setSchedulerParameters', 'setSchedulerParametersFlags', 'setTime',
'impostaUsa'...]

Questo può davvero aiutarti a ricordare rapidamente il nome esatto di un metodo e l'oggetto con cui dovrebbe essere usato. Ora che abbiamo una libvirt.oggetto virDomain, usiamolo per elencare vari dettagli su questa VM in esecuzione.

>>> dominio.Informazioni()

Questo ti dà le informazioni riguardanti lo stato della VM, la memoria massima e i core della CPU come mostrato qui.

Puoi anche trovare altre informazioni sulla VM usando metodi diversi come OSType()

>>> dominio.Tipo OS()
'hvm'

C'è molta flessibilità quando si tratta dell'API che libvirt espone e devi solo preoccuparti del tuo caso d'uso e senza preoccuparti dell'enorme complessità che gestisce libvirt.

Conclusione

Nei miei viaggi nella tecnologia Libvirt, l'assenza di UUID come cittadino di prima classe è stato probabilmente l'unico punto dolente che ho dovuto affrontare e che sembrava una cattiva scelta di design. A parte questo, libvirt è piuttosto elegante per ciò che realizza. Sì, ci sono molte altre cose che avrebbero potuto essere fatte in un modo migliore, ma è sempre così con il software. Col senno di poi, le decisioni sbagliate sono sempre ovvie, ma il costo della riscrittura di un software, diffuso come libvirt, è spesso enorme.

Molto è stato costruito su di esso, poiché il progetto si è evoluto lentamente e costantemente.

Invece di provare a imparare l'intera libreria in una volta, consiglierei di elaborare un piccolo progetto o un'idea e implementarla utilizzando Python e Libvirt. La documentazione è piuttosto ampia con molti esempi e ti costringe davvero a pensare alla corretta progettazione del software e allo stack di virtualizzazione allo stesso tempo.

Motori di gioco gratuiti e open source per lo sviluppo di giochi Linux
Questo articolo tratterà un elenco di motori di gioco gratuiti e open source che possono essere utilizzati per lo sviluppo di giochi 2D e 3D su Linux....
Tutorial Shadow of the Tomb Raider per Linux
Shadow of the Tomb Raider è la dodicesima aggiunta alla serie Tomb Raider, un franchise di giochi d'azione e avventura creato da Eidos Montreal. Il gi...
Come aumentare gli FPS in Linux?
FPS sta per Fotogrammi al secondo. Il compito dell'FPS è misurare il frame rate nelle riproduzioni video o nelle prestazioni di gioco game. In parole ...