Libvirt avec python

Libvirt avec python
Dans l'un de mes articles précédents, j'ai montré comment on peut commencer avec Libvirt et KVM. Cette pile de virtualisation est censée ne pas être utilisée comme logiciel de virtualisation de bureau, il est plutôt destiné à fonctionner sur des serveurs offrant une plus grande flexibilité, efficacité et stabilité, au lieu de la convivialité des utilisateurs. Il est signifié automatisé pour le ne diplôme plutôt que de compter sur la configuration manuelle. Voyons donc comment vous pouvez vous connecter à votre démon libvirt et automatiser la gestion et la surveillance de base de machines virtuelles à l'aide de Python.

La configuration et les hypothèses de base

J'utilise une installation de libvirt KVM sur un serveur Debian. Les scripts Python que j'utiliserai sont en cours d'exécution dans un Python 3.7.3 environnement. Cet article est censé mouiller vos pieds avec les liaisons Python de Libvirt, lorsque vous concevez votre application, vous devez toujours vous référer à la documentation officielle qui couvre un large éventail de cas d'utilisation et est mis à jour raisonnablement souvent souvent.

Installons d'abord toutes les dépendances requises pour libvirt:

$ sudo apt installer pkg-config libvirt-dev
$ pip3 installer libvirt-python

C'est tous les packages dont vous avez besoin.

Les scripts et extraits suivants sont exécutés localement sur l'hôte Libvirt, comme racine, plutôt que d'être exécuté sur un client distant. Vous pouvez cependant accéder aux services à distance, ce qui nécessiterait une longue digression dans la sécurisation de la connexion entre le client et le serveur. Par conséquent, nous nous connecterons localement, pour la simplicité.

Établir une connexion avec le service LibVirtd

Pour commencer, ouvrons une invite Python, importons la bibliothèque LibVirt et ouvrons une connexion avec le libvirt.Méthode ouverte.

root @ deb: ~ # python3
Python 3.7.3 (par défaut, 15 avril 2019, 01:55:37)
[GCC 6.3.0 20170516] sur Linux

Tapez «Help», «Copyright», «Crédits» ou «Licence» pour plus d'informations.

>>> Importer libvirt
>>> Conn = libvirt.Open ('Qemu: /// Système')

La variable conn peut maintenant être utilisée pour interroger votre démon libvirt et nous le ferons sous peu. Mais d'abord, un peu de digression.

Libvirt peut être utilisé pour gérer un certain nombre de piles de virtualisation et de contenerisation différentes. KVM-Qemu, Xen et LXC sont les plus populaires d'entre eux. Alors quand tu entrez libvirt.Open ('Qemu: /// System') Libvirt vous permet de recueillir des informations sur les invités Qemu sur les invités. Vous pouvez tout aussi bien parler à LXD Daemon ou Xen Hyperviseur à l'aide du système LXC: /// Système ou Xen: /// Système respectivement.

De même, la méthode libvirt.Open () n'est pas le seul à votre disposition. Open (Nom), OpenAuth (URI, AUTH, FLAGS) et OpenReadonly (nom) sont trois appels différents, chacun renvoie un objet Virconnect et offre un niveau de contrôle variable sur l'hôte. Vous pouvez en savoir plus à leur sujet ici. Pour l'instant, nous avons Conn comme objet de la classe Virconnect. Cet objet est une passerelle pour faire presque n'importe quoi, de la configuration de l'hyperviseur lui-même à la modification des invités et de leur allocation de ressources.

Une fois que vous avez terminé de travailler avec l'objet, assurez-vous de fermer la connexion en appelant la méthode étroite dessus.

>>> Conn.fermer()

Cependant, n'exécutez pas la commande ci-dessus, encore. Parce que nous jouerons un peu plus avec libvirt. Demandons à notre hyperviseur quelques détails sur lui-même, comme le nom d'hôte, et le nombre de VCPU qu'il peut offrir aux machines virtuelles invitées au total.

>>> Conn.gethostname ()
'Deb'
>>> Conn.getmaxvcpus ('qemu')
16

Maintenant, nous devons comprendre qu'avec des métadonnées LibVirt sur des objets comme les statistiques d'hyperviseur, les machines virtuelles, leurs informations de réseautage et de stockage, etc. sont toutes représentées au format XML. XML est en quelque sorte comme JSON un peu plus maladroit (et un peu plus âgé). Les données sont stockées et présentées comme une chaîne littérale et ce que cela signifie, c'est que si vous interrogez LibVirt et que la sortie de cette requête est XML, vous obtiendrez une très longue sortie de ligne unique avec '\ n' présente comme une chaîne littérale plutôt que comme un nouvelle ligne. La fonction d'impression intégrée de Python peut la nettoyer pour la lisibilité humaine

>>> Imprimer (Conn.getSysInfo ())


Dell Inc.
A14


Listing et surveillance des machines virtuelles

Si vous maintenez un large éventail de machines virtuelles, vous avez besoin d'une méthode pour créer des centaines de machines virtuelles avec une configuration uniforme qui évolue également correctement des simples charges de travail en file. Libvirt appelle les machines virtuelles invitées (ou conteneurs si vous utilisez LXC) Domaines Et vous pouvez énumérer des informations sur les domaines individuels et les configurer si votre objet Virconnect a des privilèges suffisants.

Pour obtenir des informations sur les machines virtuelles et leur utilisation des ressources, vous pouvez utiliser les appels suivants:

>>> Conn.listDomainsId ()
[4, 5]

Cela renvoie un tableau d'identifices de domaine qui ne sont que de petits entiers pour une configuration de libvirt simple. Une façon plus fiable d'étiqueter vos machines virtuelles, sans avoir deux machines virtuelles (disons sur différents nœuds) avec le même identifiant ou nom, consiste à utiliser des uuids. Dans libvirt, tout peut avoir un UUID, qui est généré de manière aléatoire de 128 bits. Les chances que vous créiez deux uuid identiques sont assez petites en effet.

Le réseau de vos machines virtuelles, les machines virtuelles elles-mêmes et même les pools de stockage et les volumes ont leurs uuides individuels. Faites-en usage libéral dans votre code Python, au lieu de compter sur les noms assignés par l'homme. Malheureusement, la façon d'obtenir les Uuids of Domains est un peu désordonné dans l'implémentation actuelle de cette bibliothèque, à mon avis. Cela vous oblige à fournir l'ID de la machine virtuelle (l'ID de domaine), voici à quoi il ressemble.

Domainids = Conn.listDomainsId ()
Pour Domainid dans les domainides:
domaine = conn.lookupbyid ()
uuid = domaine.UUidString ()
imprimer (uuid)

Maintenant, vous pouvez voir la liste des uuids de domaine. Nous sommes également tombés sur un nouvel objet Python libvirt.Virdomain, qui, a son propre ensemble de méthodes qui lui sont associés un peu comme la variable Conn qui était une libvirt.objet Virconnect et avait des méthodes comme ListDomainId () et LookupById () associées à lui.

Pour ces deux méthodes, vous pouvez utiliser les méthodes DIR () intégrées de Python afin que les objets puissent répertorier leurs variables et méthodes internes.

Par exemple:

>>> dir (Conn)
['_… Gs', 'schedulerType', 'Screenshot', 'SecurityLabel', 'SecurityLabellist',
«Sendkey», «SendProcessSignal», «setAutostart», «setblkioparameters», «setblockotune»,
'setGuestvcpus', 'setterfaceparameters', 'setmaxmemory', 'setMemory', 'setMemoryFlags',
«setMemoryParameters», «setMemoryStatsperiod», «setmetadata», «setNumaparameters»,
«setperfevents», «setschedulerParameters», «setschedulerParametersFlags», «settime»,
'SetUse'…]

Cela peut vraiment vous aider à vous rappeler rapidement le nom exact d'une méthode et l'objet avec lequel il devrait être utilisé. Maintenant que nous avons une libvirt.Objet Virdomain, utilisons-le pour énumérer divers détails sur cette machine virtuelle en cours d'exécution.

>>> Domaine.Info()

Cela vous donne les informations concernant l'état de la machine virtuelle, la mémoire maximale et les cœurs CPU comme indiqué ici.

Vous pouvez également trouver d'autres informations sur la machine virtuelle en utilisant différentes méthodes comme Ostype ()

>>> Domaine.Ostype ()
'hvm'

Il y a beaucoup de flexibilité en ce qui concerne l'API que Libvirt expose et vous n'avez qu'à vous soucier de votre cas d'utilisation et sans vous soucier de l'énorme complexité que Libvirt gère.

Conclusion

Dans mes voyages dans la technologie LibVirt, l'absence d'Uuids en tant que citoyen de première classe était probablement le seul point de douleur que j'ai affronté, ce qui semblait être un mauvais choix de conception. A part ça, Libvirt est assez astucieux pour ce qu'il accomplit. Oui, il y a beaucoup d'autres choses qui auraient pu être faites d'une meilleure manière, mais c'est toujours le cas avec le logiciel. Avec le recul, les mauvaises décisions sont toujours évidentes, mais le coût de la réécriture d'un logiciel, aussi répandu que LibVirt, est souvent formidable.

Beaucoup a été construit par-dessus, car le projet a évolué lentement et régulièrement.

Au lieu d'essayer d'apprendre la bibliothèque entière à la fois, je recommanderais de trouver un petit projet ou une idée et de mettre en œuvre cela en utilisant Python et Libvirt. La documentation est assez étendue avec de nombreux exemples et cela vous oblige vraiment à réfléchir à la conception et à la pile de virtualisation des logiciels appropriés en même temps.