[zz]Scripting KVM with Python, Part 1: libvirt

   2023-02-09 学习力0
核心提示: http://www.ibm.com/developerworks/opensource/library/os-python-kvm-scripting1/ Paul Ferrill, CTO, ATACPaul Ferrill has been writing in the computer trade press for more than 20 years. He got his start writing networking reviews for PC Ma
 
 
Paul Ferrill, CTO, ATAC
Paul Ferrill has been writing in the computer trade press for more than 20 years. He got his start writing networking reviews for PC Magazine on products like LANtastic and early versions of Novell Netware. Paul holds both BSEE and MSEE degrees and has written software for more computer platforms and architectures than he can remember.

 

Summary:  This two-part series explores how to use Python to create scripts for managing virtual machines using KVM. In this installment, learn the basics of using libvirt and the Python bindings to build a few simple status and display tools.

Virtualization is standard equipment with most server operating systems on the market today. In the Linux® world, there are two primary choices for server virtualization: the Kernel-based Virtual Machine (KVM) and Xen. KVM is the primary technology that Red Hat and others use. Although Citrix owns Xen, much of the core functionality remains in the public domain.

The Virtual Machine Manager (VMM, or virt-manager) project provides a tool for managing the creation and running of both KVM and Xen virtual machine (VM) instances. VMM is written in Python using the GTK+ library for graphical user interface construction. The real work is done through the libvirt library, which is what you'll be using for this article series. Although libvirt is a Red Hat-sponsored effort, it remains an open source project available under the GNU Lesser General Public License.

libvirt is made up of several different pieces, including the application programming interface (API) library, a daemon (libvirtd), and a default command-line utility (virsh). For the purposes of this article, all testing is done using Ubuntu Server version 11.04. The Installation and setup section covers everything I did to configure my server for developing the scripts presented here. Part 1 covers the basics of libvirt and Kernel-based Virtual Machine (KVM) virtualization along with a few command-line scripts to whet your appetite. Part 2 will dive deeper and show you how you can build your own virtualization management tools using libvirt, Python, and wxPython.

Getting started

Before we dive into the actual code examples, let's go over a few terms and concepts related to virtualization with KVM. When you install KVM on a server like Ubuntu Server 11.04, you're establishing a virtualization host, or hypervisor. That means that your server will be able to host multiple guest operating systems running on top of the KVM host. Each unique guest is called a domain and functions in much the same way you would expect from a single server instance on an individual machine. You can connect to the server over Secure Shell (SSH) or Virtual Network Computing just as if you were communicating with a physical machine.

Although KVM functions as the hypervisor or guest manager, QEMU provides the actual machine emulation, meaning that QEMU executes the native instruction set of the target machine. For x86 guests, this execution translates into native instructions capable of direct execution on the underlying hardware. For other architectures, such as ARM, a translation process must take place. The combination of KVM and QEMU provides all the support functions needed to virtualize essentially every currently available operating system plus a few that are no longer available.

A guest domain consists of a number of files, including one or more disk image files and an XML-based configuration file. This setup makes it extremely simple to manage multiple VMs by creating a baseline system image, and then modifying the configuration file to suit your needs. One method of configuring and communicating with KVM/QEMU is the libvirt toolkit. Multiple vendors have standardized their management products based on libvirt.

Look at the contents of a typical domain configuration file. Listing 1 shows the testdev.xml file from the libvirt examples.


Listing 1. Device XML definition

	
<device>
   <name>File_test_device</name>
   <capability type='system'>
         <hardware>
               <vendor>Libvirt</vendor>
               <version>Test driver</version>
               <serial>123456</serial>
               <uuid>11111111-2222-3333-4444-555555555555</uuid>
         </hardware>
         <firmware>
               <vendor>Libvirt</vendor>
               <version>Test Driver</version>
               <release_date>01/22/2007</release_date>
         </firmware>
   </capability>
</device>

 

From the test domfv0.xml file shown in Listing 2, you can see a bit more detail about configuring virtual devices.


Listing 2. domfv0.xml device definition file

	
<devices>
  <emulator>/usr/lib/xen/bin/qemu-dm</emulator>
         <interface type='bridge'>
               <source bridge='xenbr0'/>
               <mac address='00:16:3e:5d:c7:9e'/>
               <script path='vif-bridge'/>
         </interface>
         <disk type='file'>
               <source file='/root/fv0'/>
               <target dev='hda'/>
         </disk>
         <disk type='file' device='cdrom'>
               <source file='/root/fc5-x86_64-boot.iso'/>
               <target dev='hdc'/>
               <readonly/>
         </disk>
         <disk type='file' device='floppy'>
               <source file='/root/fd.img'/>
               <target dev='fda'/>
         </disk>
         <graphics type='vnc' port='5904'/>
</devices>

 

The key point here is the relative ease with which you can read these files and subsequently create your own. Although you could build any number of configuration files by hand, it's also possible to automate the building using a scripting language like Python.


Installation and setup

Because this article is about scripting KVM, there is a basic assumption that you have a server with KVM installed. In the case of Ubuntu Server 11.04, you have the option of installing virtualization during the setup process by choosing the Virtual Machine Host option on the Software selection screen. You might also want to choose the OpenSSH server should you want to connect remotely to the machine.

The first order of business is to install the latest version of libvirt. To do this, you have to do some command-line work. When you install Ubuntu Server 11.04, you get libvirt version 0.8.8. The latest and greatest version available from the libvirt website is 0.9.5. To install a later version, you need to add a Personal Package Archive (PPA) repository to your system containing a more recent version of libvirt. A quick search on the launchpad.net site for libvirt shows a number of potential candidates. It's important to view the repository details page before you try to perform an update, as some may have broken packages. The Ubuntu Virtualization Team maintains a PPA repository with several packages, including libvirt. The latest version available at the time of this writing was 0.9.2-4.

Perform the following steps to install that version:

  1. Install the python-software-properties package as follows:
    sudo apt-get install python-software-properties
    

    This command makes available the add-apt-repository command that you need to reference the third-party source.

  2. Type the following commands:
    sudo add-apt-repository ppa:ubuntu-virt/ppa
    sudo apt-get update
    sudo apt-get install libvirt-bin
    
  3. Because you'll be using Python to do all the scripting for this article, install the IDLE shell to make it easier to write and test scripts.

    This step assumes that you have installed the desktop environment on your Ubuntu server. The quickest way to get the desktop installed is to use the following command:

    sudo apt-get install ubuntu-desktop
    

After that's done, you'll have access to any number of graphical applications along with the Ubuntu software installer. You can use the Ubuntu Software Center to install the Python IDLE tool.


Sample scripts

At this point, let's look at some of the fundamentals of working with libvirt before getting too deeply into code. Communication between an application and the libvirt library uses a simple remote procedure call mechanism, which makes it possible to build applications to communicate with remote hypervisors over a TCP/IP connection. Uniform Resource Identifiers (URIs, defined by Internet Engineering Task Force [IETF] Request for Comments [RFC] 2396) are used to identify a specific hypervisor with which you want to establish a connection.

Local connections typically do not require authentication, although some remote connections do. The libvirt.conf file controls the security configuration. The most extensive control over communicating with a unique domain is through network filtering. Here's an example of how you would control network traffic using a filter:

<devices>
    <interface type='bridge'>
      <mac address='00:16:3e:5d:c7:9e'/>
      <filterref filter='clean-traffic'/>
    </interface>
</devices>

 

This snippet defines a filter named clean-traffic that will be applied to all network traffic over the specified media access control (MAC) address. If you examine the clean-traffic XML, it contains the following:

<filter name='clean-traffic' chain='root'>
     <uuid>6f145c54-e3de-4c33-544a-70b69c16d9da</uuid>
     <filterref filter='no-mac-spoofing'/>
     <filterref filter='no-ip-spoofing'/>
     <filterref filter='allow-incoming-ipv4'/>
     <filterref filter='no-arp-spoofing'/>
     <filterref filter='no-other-l2-traffic'/>
     <filterref filter='qemu-announce-self'/>
</filter>

 

The filter capabilities are quite extensive and fully documented. It takes only one command if you want to have a local copy of the libvirt documentation and sample files. Here's what you need to do:

sudo apt-get install libvirt-doc

 

With that done, all the documentation is available in the /usr/share/doc/libvirt-doc directory. You'll see the Python examples a bit later. If you've updated to a more recent version of libvirt, you may need to explicitly install the Python bindings. Doing so requires a single command:

sudo apt-get install python-libvirt

 

Use Python's IDLE console to examine Python code to establish a connection with a local QEMU instance, and then examine the defined domains. Listing 3 shows what you should see using this approach.


Listing 3. Viewing Python code in the IDLE console

	
Python 2.7.1+ (r271:86832, Apr 11 2011, 18:13:53) 
[GCC 4.5.2] on linux2
Type "copyright", "credits" or "license()" for more information.
==== No Subprocess ====
>>> import libvirt
>>> conn=libvirt.open("qemu:///system")
>>> names = conn.listDefinedDomains()
>>> print names
['Test1', 'SBSLite', 'UbuntuServer1104', 'Win7_64-bit']]
>>>

 

This code shows how to get a list of all defined domains. The return from the listDefinedDomains() function shows a list containing four named domains. Once you establish a connection to the hypervisor, you will have access to a laundry list of available functions. Here's a short script showing how to get a list of all available functions available on the conn object:

clist = dir(conn)
for item in clist:
            print item

 

To see a list of defined filters, you could use a similar approach:

filts = conn.listNWFilters()
for item in filts:
            print item

 

The IDLE tool is a great way to investigate the various API calls and quickly see the results returned when executed. Some of the functions operate only on running domains. The Python dir() function returns a list of valid attributes for the specified object. It's a convenient command-line tool to quickly see what a particular object provides. You can use it as shown above to get a list of functions available after establishing a connection to the hypervisor.

To demonstrate, you can use a few lines of Python code in the IDLE console to get an idea of the kinds of operations you can perform on a specific domain. Listing 4 provides an example of what you can do.


Listing 4. Python output of a domain object

	
>>> import libvirt
>>> import pprint
>>> conn=libvirt.open("qemu:///system")
>>> p = conn.lookupByName('ubuntu100403')
>>> pprint.pprint(dir(p))
['ID',
 'OSType',
 'UUID',
 'UUIDString',
 'XMLDesc',
 '__del__',
 '__doc__',
 '__init__',
 '__module__',
 '_conn',
 '_o',
 'abortJob',
 'attachDevice',
 'attachDeviceFlags',
 'autostart',
 'blkioParameters',
 'blockInfo',
 'blockPeek',
 'blockStats',
 'connect',
 'coreDump',
 'create',
 'createWithFlags',
 'destroy',
 'detachDevice',
 'detachDeviceFlags',
 'hasCurrentSnapshot',
 'hasManagedSaveImage',
 'info',
 'injectNMI',
 'interfaceStats',
 'isActive',
 'isPersistent',

 

You can take this basic approach to building a simple script that lists information about all running domains. You use the listDomainsID() and lookupByID() function calls to do most of the work, as Listing 5 shows.


Listing 5. Python list domains script

	            
import libvirt
conn=libvirt.open("qemu:///system")

for id in conn.listDomainsID():
   dom = conn.lookupByID(id)
   infos = dom.info()
   print 'ID = %d' % id
   print 'Name =  %s' % dom.name()
   print 'State = %d' % infos[0]
   print 'Max Memory = %d' % infos[1]
   print 'Number of virt CPUs = %d' % infos[3]
   print 'CPU Time (in ns) = %d' % infos[2]
   print ' '

 

The output from this script, with one domain active and another suspended, looks like this:

ID = 3
Name =  ubuntu100403
State = 3
Max Memory = 1048576
Number of virt CPUs = 1
CPU Time (in ns) = 1048576

ID = 4
Name =  Win7_64-bit
State = 1
Max Memory = 2097152
Number of virt CPUs = 2
CPU Time (in ns) = 2097152

 

libvirt also implements Python docstrings for all classes and methods. You can access this information by typing help(libvirt) for the top-level help or help(libvirt.class) for a specific class. You must have imported the libvirt module before typing the help() command. The version I tested for this review implements the following 11 classes:

  • libvirtError
  • virConnect
  • virDomain
  • virDomainShapshot
  • virInterface
  • virNWFilter
  • virNetwork
  • virSecret
  • virStoragePool
  • virStorageVol
  • virStream

This list should help you decode the syntax for accessing libvirt functions from Python. It also gives you a list of all named constants, like VIR_DOMAIN_RUNNING, which equals 1. Functions like dom.info(), used above, return an integer value and need to be decoded against this constant table.


Utility scripts for automation

You could write any number of utility scripts to manage a KVM installation using libvirt and Python. It might not be efficient for a small number of domains but can quickly save time when the count gets into double digits. One simple task would be to make a mass change of static IP addresses for all domain images. You can do this by iterating over all the .conf files, and then making the appropriate changes. Python has many built-in features to help with this task.

Listing 6 shows an example of an XML network definition.


Listing 6. Network configuration XML file

	         
<network>
  <name>testnetwork</name>
  <bridge name="virbr1" />
  <forward/>
  <ip address="192.168.100.1" netmask="255.255.255.0">
    <dhcp>
      <range start="192.168.100.2" end="192.168.100.254" />
      <host mac='de:af:de:af:00:02' name='vm-1' ip='192.168.100.2' />
      <host mac='de:af:de:af:00:03' name='vm-2' ip='192.168.100.3' />
      <host mac='de:af:de:af:00:04' name='vm-3' ip='192.168.100.4' />
      <host mac='de:af:de:af:00:05' name='vm-4' ip='192.168.100.5' />
      <host mac='de:af:de:af:00:06' name='vm-5' ip='192.168.100.6' />
      <host mac='de:af:de:af:00:07' name='vm-6' ip='192.168.100.7' />
      <host mac='de:af:de:af:00:08' name='vm-7' ip='192.168.100.8' />
      <host mac='de:af:de:af:00:09' name='vm-8' ip='192.168.100.9' />
      <host mac='de:af:de:af:00:10' name='vm-9' ip='192.168.100.10' />
    </dhcp
  </ip>
</network>

 

If you wanted to change the main subnet from 192.168.100 to 192.168.200, you could open the configuration file in an editor and do a global search and replace. The trick is when you want to do something a bit more complex, like add 10 to all the IP and MAC addresses starting with 2. Figure 7 shows how you might do that with a little over 20 lines of Python code.


Listing 7. Python script to change MAC and IP addresses

	
#!/usr/bin/env python

from xml.dom.minidom import parseString
import sys

def main():
    target = sys.argv[1]
    number = int(sys.argv[2])
    
    xml = open(target, 'r').read()
    doc = parseString(xml)
    for host in doc.getElementsByTagName('host'):
        ip = host.getAttribute('ip')
        parts = ip.split('.')
        parts[-1] = str(int(parts[-1]) + number)
        host.setAttribute('ip', '.'.join(parts))
        
        mac = host.getAttribute('mac')
        parts = mac.split(':')
        parts[-1] = str(int(parts[-1]) + number)
        host.setAttribute('mac', ':'.join(parts))
    
    f = open(target, 'w')
    f.write(doc.toxml())
    f.close()

if __name__ == '__main__':
    main()    

 sys.argv 这个参数是怎么来的?我要从外部改变一个虚拟机的ip,或者在创建的时候指定,要怎么做?要运行这个python文件的时候指定的

This script demonstrates the power of Python when you take advantage of the Python Standard Library. Here, you use parseString from xml.dom.minidom to do the heavy lifting of parsing the XML file. After you have a specific XML attribute, you simply break it into individual pieces using the Python string.split function. Then, just do the math and put the strings back together. You can expand this approach to make bulk changes to any XML file, including the .conf files for libvirt.

Another helpful script would take a snapshot of all running domains. This script would need first to get a list of all running domains, then individually pause and create a snapshot of each one. Although this operation might not be practical for a production environment, you could set it to run as a CRON job in the middle of the night. This script would be straightforward to implement with the commands highlighted so far, along with a call to snapshotCreateXML().


Winding down

This article has just scratched the surface of the capabilities contained in libvirt. Check the Resources section for links to more in-depth reading on libvirt and virtualization in general. Understanding the basics of KVM goes a long way when you start trying to implement code to monitor and manage your environment. The next installment in this series will take the foundation established here and build a few real-world virtual management tools.

 

Resources

Learn

Get products and technologies

  • Evaluate IBM software products: From trial downloads to cloud-hosted products, you can innovate your next open source development project using software especially for developers.

Discuss

 
反对 0举报 0 评论 0
 

免责声明:本文仅代表作者个人观点,与乐学笔记(本网)无关。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
    本网站有部分内容均转载自其它媒体,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责,若因作品内容、知识产权、版权和其他问题,请及时提供相关证明等材料并与我们留言联系,本网站将在规定时间内给予删除等相关处理.

  • 云计算中的OpenStack和KVM到底是什么
    云计算中的OpenStack和KVM到底是什么
    OpenStack是一个开放源代码云计算平台 openstack是云管理平台,其本身并不提供虚拟化功能,真正的虚拟化能力是由底层的hypervisor(如KVM、Qemu、Xen等)提供。 以下内容真的的背了一遍又一遍的内容,openstart组件介绍Nova:Nova是OpenStack的主要计算引擎,
    03-08
  • KVM 虚拟机联网方式:NAT 和 Bridge
    KVM 客户机网络连接有两种方式:用户网络(User Networking):让虚拟机访问主机、互联网或本地网络上的资源的简单方法,但是不能从网络或其他的客户机访问客户机,性能上也需要大的调整。NAT方式。虚拟网桥(Virtual Bridge):这种方式要比用户网络复杂一些
    03-08
  • 如何在 CentOS 7 / RHEL 7 终端服务器上安装 KVM
    如何在 CentOS 7 / RHEL 7 终端服务器上安装 KV
    如何在 CnetOS 7 或 RHEL 7(Red Hat 企业版 Linux)服务器上安装和配置 KVM(基于内核的虚拟机)?如何在 CentOS 7 上设置 KVM 并使用云镜像 / cloud-init 来安装客户虚拟机?基于内核的虚拟机(KVM)是 CentOS 或 RHEL 7 的虚拟化软件。KVM 可以将你的服务
    03-08
  • kvm虚拟机扩容系统盘 虚拟机扩容c盘
    kvm虚拟机扩容系统盘 虚拟机扩容c盘
     一,宿主机扩容虚拟机系统盘环境文件系统CentOS 7XFS1.1查看虚拟机(以下操作在宿主机上)[root@office-prd-kvm-01 ~]# virsh list 4 office-com-ldap-01 running1.2查看虚拟机系统盘[root@office-prd-kvm-01 ~]# virsh domblklist office-com-ldap-01 目标 源
    03-08
  • kvm虚拟化介绍 kvm开源虚拟化系统
  • Linux中KVM桥接的配置
    Linux中KVM桥接的配置
    1. 原理1.1 说明在安装一个拥有虚拟化功能的Linux操作系统(此处以CentOS为例),一般我们有两种方法:1.在光盘安装的时候安装好虚拟化包或者PXE服务器上配置好虚拟化包2.手动在没有安装虚拟化组件的系统中安装虚拟化组件1.2 目的 如果我们搭建的环境是必须使
    02-10
  • kvm学习笔记(一,基础概念) kvm 原理
    kvm学习笔记(一,基础概念) kvm 原理
    前言   阿里云的云主机,采用的kvm,今天就花了点时间研究了下。一、安装官方文档参考:http://www.linux-kvm.org/page/HOWTO二、快速建立一个基于vnc的虚拟机安装 桥接网卡命令创建虚拟机 virt-install \#--network bridge:br0如果主机网卡不是桥接模式
    02-10
  • KVM 内存虚拟化
    KVM 内存虚拟化
    内存虚拟化的概念    除了 CPU 虚拟化,另一个关键是内存虚拟化,通过内存虚拟化共享物理系统内存,动态分配给虚拟机。虚拟机的内存虚拟化很象现在的操作系统支持的虚拟内存方式,应用程序看到邻近的内存地址空间,这个地址空间无需和下面的物理机器内存直
    02-10
  • 在Ubuntu1804中通过KVM创建bridge型的网络虚拟机
    在Ubuntu1804中通过KVM创建bridge型的网络虚拟
    桥接网络可以运行在宿主机上的虚拟机使用和宿主机同网段的IP,并且可以从外部直接访问到虚拟机。目前企业中大部分场景都是使用桥接网络第一步:首先在宿主机上创建桥接网卡,如下:Ubuntu1804创建桥接网卡 1 # cat/etc/netplan/01-netcfg.yaml 23 # This file
    02-10
  • 通过python-libvirt管理KVM虚拟机 代码实现
    初步代码 [python] view plain copy span style="font-size:18px;"''''' Work with virtual machines managed by libvirt     :depends: libvirt Python module '''  # Special Thanks to Michael Dehann, many of the conce
    02-10
点击排行