KVM&QEMU學習筆記(二)

使用快照

快照(Snapshot)是Copy-on-write的一種應用。QEMU支持兩種快照:

  1. 內部快照(internal snapshot):在qcow2鏡像的snapshot table中維護的快照,所有快照都存放在一個鏡像文件中
  2. 外部快照(external snapshot):與Backing file很類似,在外部文件中創建新的鏡像,原先的鏡像只讀
內部快照

內部快照的原理是:

  1. 創建一個Snapshot後,在Snapshot Table中新增一項,複製L1 Table
  2. 當L2 Table或者Data Cluster發生改變,則把改變前的數據複製一份(Copy-on-write),由新創建的Snapshot的L1 Table來管理
  3. L2 Table或者Data Cluster的變化,直接寫到原始位置
  4. 要刪除快照,很簡單,直接把Snapshot Table對應項、以及複製的L1-L2-DS刪除即可
  5. 要加載快照,則需要依據L1-L2-DS信息,將其合併到鏡像的L1-L2-DS信息中

可以使用Monitor來創建、加載、刪除內部快照:

# 保存一個內部快照
(qemu) savevm snapshot-1
 
qemu-img info hda.img
# 輸出如下:
#Snapshot list:
#ID        TAG                 VM SIZE                DATE       VM CLOCK
#1         snapshot-1             112M 2016-09-07 18:05:48   00:00:21.536
#Format specific information:
#    compat: 1.1
#    lazy refcounts: false
 
# 加載內部快照
(qemu) loadvm snapshot-1
 
# 刪除內部快照
(qemu) delvm snapshot-1

外部快照

外部快照與內部快照相反:內部快照是原數據變化,外部快照則是新文件變化。

可以使用Monitor來管理外部快照:

snapshot_blkdev ide0-hd0 snapshot.img qcow2
配置客戶機磁盤

有了磁盤鏡像文件後,你需要爲qemu-system-*指定參數,給客戶機增加磁盤。有幾種不同的配置方式:

# 最簡單的方式
-hda hda.img 
 
# 使用-drive配置塊設備,可以指定if爲virtio來提升性能
-drive file=hda.img,index=0,media=disk,if=virtio
 
# 使用-device配置通用設備
-drive file=hda.img,if=none,id=virtio-disk0,format=qcow2,cache=none 
# 可以指定virtio-blk-pci來提升性能
-device virtio-blk-pci,scsi=off,bus=pci.0,addr=0x4,drive=virtio-disk0,bootindex=1

配置網絡

QEMU中的網絡,包含兩部分的內容:

  1. 客戶機使用的虛擬網絡設備
  2. 和上述虛擬設備通信的網絡後端,這些後端負責把虛擬設備的數據包發到宿主機的網絡中

要創建一個網絡後端,可以指定如下選項:

# TYPE爲後端類型:user、tap、bridge、socket、vde等
# id爲一個標識符,將虛擬網絡設備和網絡後端關聯在一起
# 如果客戶機有多個虛擬網絡設備,則每一個都需要自己的網絡後端
-netdev TYPE,id=NAME,...

QEME支持多種網絡後端:

USER後端

如果沒有指定網絡選項,QEMU默認會模擬單張Intel e1000 PCI網卡,該網卡基於user後端(SLIRP)連接到宿主機:

# 不指定網絡
qemu 
# 等價配置。自0.12開始廢棄的配置方式 -net nic相當於-device DEVNAME;-net TYPE相當於-netdev TYPE
qemu -hda disk.img -net nic -net user
# 等價配置。-netdev指定網絡後端,-device指定虛擬網絡設備,後者通過netdev字段引用後端的ID
qemu -netdev user,id=network0 -device e1000,netdev=network0

在客戶機看來:

  1. 本身的IP地址被分配爲 10.0.2.15+
  2. 分配IP的虛擬DHCP爲 10.0.2.2
  3. 虛擬DNS服務器爲 10.0.2.3
  4. 虛擬Samba服務器爲 10.0.2.4,客戶機可以通過此服務器訪問宿主機的文件系統

用戶模式網絡可以很方便的訪問網絡資源。但是它有很多限制:

  1. 默認的,它運作方式類似於防火牆,且不允許任何入站流量。這個限制可以通過端口重定向解決
  2. 僅僅支持TCP、UDP協議,對於ICMP則不支持
  3. 性能比較差

爲了支持入站請求,你可以使用端口重定向(Redirecting ports)——把針對宿主機某個端口的請求轉發給客戶機的某個端口。映射後,客戶機可以對外提供SSH、HTTP等服務:

# 把宿主機的7080端口重定向到客戶機的80端口;把宿主機的7022端口重定向到客戶機的22端口
qemu-system-x86_64 -redir tcp:7080::80 -redir tcp:7022::22 -hda ~/Vmware/KVM/centos7-base.img -m 512 
 
# 從宿主機SSH到客戶機
ssh [email protected] -p 7022

你可以不使用默認的10.0.2網段:

Shell
1
-netdev user,id=network0,net=192.168.5.0/24,dhcpstart=192.168.5.9 

客戶機OS配置

依據客戶機安裝的操作系統,可能需要進行一些配置,才能正常使用網絡。以CentOS 7 Minimal + 用戶模式網絡爲例,需要修改以下配置文件:

NETWORKING=yes
# 如果不使用IPV6
NETWORKING_IPV6=no
# 如果不使用IPV6
IPV6INIT=no
# 開機啓動此網卡,默認不啓動
ONBOOT=yes
網關、DNS不需要設置。修改完這些配置文件後,重啓客戶機網絡: /etc/init.d/network restart  。然後執行yum update 測試一下能否正常聯網(不要使用ping測試)
TAP後端

QEMU的TAP後端利用宿主機的TAP設備,爲客戶機提供完整的橋接網絡支持,如果外部需要使用標準端口連接到客戶機, 或者多個客戶機需要相互通信,可以使用該方式。 TAP後端還具有以下優勢:

  1. 非常好的性能
  2. 可以配置以支持各種網絡拓撲

但是,你需要在宿主機上進行網絡拓撲的配置,而且各種系統的配置不同。

使用TAP後端前,你需要確認你的宿主機的內核支持TAP網絡接口: /dev/net/tun 文件存在則說明支持。如果沒有這樣的文件,可以嘗試手工創建:

sudo mkdir /dev/net
sudo mknod /dev/net/tun c 10 200
sudo /sbin/modprobe tun


如果你想創建幾個客戶機之間的私有網絡,可以使用該方式。未參與進來的客戶機、真實網絡無法看到此網絡。基於TAP的私有橋接網絡
如果你不是root,則你需要 /dev/kvm 的讀寫權限。

首先,添加一個以太網橋設備:

sudo ip link add br0 type bridge
# 也可以使用:sudo brctl addbr br0添加網橋
# 要刪除網橋,執行: ip link delete br0
# 注意:網橋會在重啓後消失
 
# 啓用此網橋
sudo ip link set br0 up
 
# 爲網橋分配IP地址
sudo ip addr add 10.0.0.1 dev br0
 
# 在宿主機添加一條直接路由,便於它能和客戶機通信
sudo ip route add 10.0.0.0/8 dev br0
創建一個創建TAP設備並橋接到網橋的腳本:

#!/bin/sh
 
switch=br0
 
if [ -n "$1" ];then
        # tunctl -u `whoami` -t $1
        # 添加一個tap設備,在我的機器上不需要,原因見下面
        # ip tuntap add $1 mode tap user `whoami`
        # 不知道從什麼時候開始,QEMU會在執行此腳本之前就創建好tap設備,因此會報下面的錯誤
        # ioctl(TUNSETIFF): Device or resource busy
        # 啓動tap設備
        ip link set $1 up
        # brctl addif $switch $1
        # 將網橋和tap設備進行橋接
        ip link set $1 master $switch
        exit 0
else
        echo "Error: no interface specified"
        exit 1
fi
創建一個生成隨機MAC地址的腳本:

#!/bin/bash
# generate a random mac address for the qemu nic
printf 'DE:AD:BE:EF:%02X:%02X\n' $((RANDOM%256)) $((RANDOM%256))
啓動客戶機的腳本:

#!/bin/bash
# $1 base name of virtual disk
# $2 memory size
# $3 tap device id
 
mac=`/usr/bin/qemu-genmac`
src=/usr/bin/qemu-ifup
sudo qemu-system-x86_64 -enable-kvm -device e1000,netdev=$3,mac=$mac -netdev tap,id=$3,script=$src,downscript=no \
                        -hda ~/Vmware/KVM/$1.img -m $2

爲上面的腳本文件添加可執行權限:

sudo chmod +x /usr/bin/qemu-ifup-br0
sudo chmod +x /usr/bin/qemu-genmac
sudo chmod +x /usr/bin/qemu-start-br0

執行下面的命令,啓動一臺客戶機(或者更多虛擬機,但是命令中的tap0要更換爲不同的名字):

/usr/bin/qemu-start centos7-base 512 tap0

修改客戶機的IP地址,使用10.0.0.0/8網段:

TYPE=Ethernet
BOOTPROTO=static
DEFROUTE=yes
PEERDNS=yes
PEERROUTES=yes
IPV4_FAILURE_FATAL=no
IPV6INIT=no
NAME=ens3
UUID=d9f47102-b177-4a27-ae98-86f6939d6680
DEVICE=ens3
ONBOOT=yes
IPADDR=10.0.0.10
PREFIX=8
GATEWAY=10.0.0.1
現在可以互相ping客戶機和宿主機,應該可以正常連通了。

私有橋接下訪問互聯網

上一節介紹的這種基於TAP的私有橋接網絡,可以讓客戶機、宿主機相互連通,但是客戶機無法訪問互聯網。

要解決此問題,你可以選擇以下方法之一:

  1. 讓客戶機通過宿主機暴露的HTTP/SOCKS代理上網
  2. 配置宿主機的路由規則,設置好源地址轉換即可:
sudo sysctl -w net.ipv4.ip_forward=1 
# 對客戶機網段進行源地址轉換
sudo iptables -t nat -A POSTROUTING  -s 10.0.0.0/255.0.0.0 ! -d 10.0.0.0/255.0.0.0 -j MASQUERADE 


公共橋接網絡

此方式和私有橋接網絡類似,主要區別是,除了TAP設備橋接到網橋之外,以太網卡(例如eth0)也橋接到網橋(例如br1)。

你可以通過發行版的配置文件來配置網橋:

# 注意網絡管理器組件的影響
# 去掉 auto eth0,改爲:
auto br1
 
# 配置br1
iface br1 inet dhcp
    bridge_ports    eth0
    bridge_stp      off
    bridge_maxwait  0
    bridge_fd       0
    # 這裏附加上原來屬於eth0的配置
或者基於腳本來配置: 

sudo ip link add br1 type bridge
sudo ip link set br1 up
sudo ip link set eth0 master br1 
 
# DHCP
sudo killall dhclient && sudo ip addr flush dev eth0
sudo dhclient br1


無論用哪種方式,都應該注意到eth0的IP地址需要轉移給br1,這樣才能確保網絡正常運作——br1必須在鏈路層接收到相關ARP請求,並決定是否需要轉發給客戶機,eth0沒有這種轉發能力。

如果eth0所在網絡是基於DHCP的,那麼客戶機配置爲DHCP後,會自動獲取公共IP地址。否則,需要手工設置客戶機的IP地址。 

基於TAP的橋接的簡化配置

現在QEMU支持自動橋接TAP設備到宿主機的一個網橋,因此你不再需要編寫腳本,修改網絡後端爲bridge即可:

-netdev bridge,id=tap0,br=br0

注意,使用上述選項時,QEMU需要讀取配置文件/etc/qemu/bridge.conf,你只需在此文件中添加一行代碼:
allow br0
你可以編寫如下腳本自動創建網橋、配置iptables規則。示例:

# Create private bridge link
 for QEMU

/sbin/ip
link
add
br0
type
bridge

/sbin/ip
link
set
br0
up

/sbin/ip
addr
add
10.0.0.1
dev
br0

/sbin/ip
route
add
10.0.0.0/8
dev
br0

# NAT for 10.0.0.0/8

/sbin/iptables
-t
nat
-A
POSTROUTING  -s
10.0.0.0/255.0.0.0
!
-d
10.0.0.0/255.0.0.0  -j
MASQUERADE

 

 

# Create public bridge link
 for QEMU

/sbin/ip
link
add
br1
type
bridge

/sbin/ip
link
set
br1
up

/sbin/ip
link
set
eth0
master
br1

/usr/bin/killall
dhclient
&&
/sbin/ip
addr
flush
dev
eth0

/sbin/dhclient
br1

macvtap直連

關於MacVTap的相關知識,參考Linux知識集錦。建議和libvirt一起使用macvtap。 

基於libvirt的橋接

在使用libvirt時,客戶機(Domain)的網絡接口配置可以簡化爲:

<interface type='bridge'>
    <mac address='DE:AD:BE:EF:F1:00'/>
    <source bridge='br0'/>
    <target dev='tap0'/>
    <model type='virtio'/>
</interface>

基於libvirt VLAN的橋接

可以使用libvrit的虛擬局域網,這樣宿主機上不會爲客戶機創建專門的tap設備,那些手工編寫的腳本也全都不需要了。虛擬網絡配置示例:

<network>
  <name>default</name>
  <uuid>9bae4de8-ca58-48c5-ba58-109aebf8b954</uuid>
  <forward mode='nat'>
  </forward>
  <bridge name='virbr0' stp='on' delay='0'/>
  <ip address='10.0.0.1' netmask='255.0.0.0'>
    <dhcp>
      <range start='10.0.0.100' end='10.0.0.200'/>
    </dhcp>
  </ip>
</network>
客戶機(Domain)的網絡接口配置示例:
<interface type='network'>
    <mac address='DE:AD:BE:EF:F1:00'/>
    <source network='default'/>
    <model type='virtio'/>
</interface>
另外,libvirt的虛擬網絡提供了DHCP功能,因此客戶機的IP地址不需要靜態設置。





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章