更改CloudStack中KVM平台的Windows虛擬機器預設磁碟類型為VirtIO

來源:互聯網
上載者:User

標籤:windows   kvm   ide   virtio   cloudstack   

前言

本文的目的是為瞭解決在使用CloudStack(CloudPlatform)時,基於KVM虛擬化平台,Windows虛擬機器的效能低下的問題。

此效能,主要指磁碟IO和網卡效能。


相關文檔

由於CS文檔中,只強調了PV這個概念,根據PV模式區分使用不同的硬體介面類型。所以收集部分連結給大家掃盲。

關於PV(Paravirtualization-半虛擬化)模式的概念,請參閱:

http://www.rackspace.com/knowledge_center/article/choosing-a-virtualization-mode-pv-versus-pvhvm

http://wiki.xenproject.org/wiki/Paravirtualization_%28PV%29

http://zh.wikipedia.org/wiki/%E8%99%9A%E6%8B%9F%E5%8C%96

http://www.ibm.com/developerworks/cn/cloud/library/cl-hypervisorcompare-kvm/


另外,關於virtio,可以查看如下連結:

http://www.linux-kvm.org/page/Virtio

http://smilejay.com/2012/11/virtio-overview/    (這個值得不懂kvm的兄弟一看)


背景

在兩個項目匯總(CS+KVM),客戶均提到Windows效能不足,但至於哪方面效能,不細說,太多。使用者反饋就一句話:虛擬機器運行太慢。

十幾台刀片伺服器,30T SAN儲存,將近萬G記憶體。才跑了100來個虛擬機器,還慢,像話嘛。

得了,慢,咱就得找原因。


初步分析

我這人比較膚淺,首先想到的就是磁碟IO不行,這個是最直接讓客戶覺得系統慢的原因(排除記憶體不足的問題)。

經過檢查,發現:

1.使用CS建立的Windows虛擬機器,系統硬碟的磁碟類型為IDE(你拿IDE介面跑Windows 2008R2,還要求效能,這像話嘛)。除系統硬碟之外所建立的所有資料盤,介面類型全部為VirtIO。

至於如何查看硬碟介面類型,可以在系統中,開啟裝置管理員-查看磁碟機類型。或者在kvm主機中,使用 ”virsh edit 虛擬機器名稱“ 尋找Disk相關配置。直接使用virt-manager也可以。

2.使用CS建立的Linux(常見發行版)虛擬機器,系統硬碟和資料盤硬碟介面類型全部為VirtIO。


到這裡,我將問題歸結為:在CS中,基於KVM平台,所建立的Windows虛擬機器,系統硬碟磁碟介面類型為IDE,這是導致效能慢的主要原因。最優磁碟介面類型應該為VirtIO。

註:

有人會說你這太武斷了,嗯,我上家公司基於KVM做案頭虛擬化產品,當時跟VMware View,XenDesktop做效能對比也不相上下(均是預設配置),跑Win7和Win2008,在負載一般的情況下,很少出現運行慢的問題。所以,基於KVM平台,跑Windows系統,效果並不會太差。當然了,除了硬碟介面使用了VirtIO,也做了其他調優。

但,瞭解KVM的朋友,應該知道KVM+VirtIO是一對好基友。至於IDE和VirtIO的效能測試對比,稍後有機會我再拿出具體測試資料。


問題視乎變得簡單了,將系統硬碟的IDE介面,換成VirtIO介面即可。


再來看下官方文檔中指出,哪些系統類別型,預設的系統硬碟介面類型為VirtIO:

  • (僅KVM) If you choose an OS that is PV-enabled, the VMs created from this ISO will have a SCSI (virtio) root disk. If the OS is not PV-enabled, the VMs will have an IDE root disk. The PV-enabled types are:

    • Fedora 13

    • Fedora 12

    • Fedora 11

    • Fedora 10

    • Fedora 9

    • Other PV

    • Debian GNU/Linux

    • CentOS 5.3

    • CentOS 5.4

    • CentOS 5.5

    • Red Hat Enterprise Linux 5.3

    • Red Hat Enterprise Linux 5.4

    • Red Hat Enterprise Linux 5.5

    • Red Hat Enterprise Linux 6

由上面的資訊得知:啟用了PV模式的作業系統,根磁碟,也就是系統磁碟,預設會使用VirtIO模式,而沒用啟用PV模式的作業系統,將會預設使用IDE模式

細心的你也會發現,上面的列表中,幾乎全部是Linux系統,除了"Other PV"這個怪胎(其實還有"Windows PV"啦,至於為啥,也許是寫文檔的人懶,也許是,稍後再說)。

為啥幾乎都是Linux系統,官方說了這樣一句話:

(僅KVM)All VMs are required to support the virtio drivers. These drivers are installed in all Linux kernel versions 2.6.25 and greater. The administrator must set CONFIG_VIRTIO_BALLOON=y in the virtio configuration.


所有的虛擬機器都要求支援virtio驅動,而Linux平台的virtio驅動已經整合到2.6.25或更高版本的核心中。也就是說Linux可以直接識別virtio介面裝置。而virtio是一個在hypervisor之上的抽象API介面,是一個半虛擬化驅動,virtio與hypervisor協作工作,用於提供出色的效能。也就是說,virtio不是標準介面類型。你買硬碟的時候有看到過virtio硬碟嘛。所以,Windows中不整合此驅動,也在情理之中。這也是為啥沒有啟用PV模式的虛擬機器的系統磁碟介面類型為IDE。


那是不是Windows就不能使用VirtIO了?當然不是。人家說了嘛,只要啟用了PV模式的作業系統,系統磁碟就會是VirtIO。所以CS中提供了2中PV模式的作業系統類型Other PV 和 Windows PV。 其實只有Other PV這一種。因為代碼中,Windows PV最終也是歸類為Other PV。

當然了,Windows 系統中的VirtIO驅動,就需要自己安裝了。


初步解決

到這裡,問題初步已經可以解決了,就是在CS中,將Windows相關的虛擬機器和模版中的作業系統類型,定義為:Windows PV或Other PV。

只要選擇了PV模式的作業系統類型,系統磁碟類型即可使用VirtIO。

650) this.width=650;" src="http://s3.51cto.com/wyfs02/M02/43/A3/wKioL1Pbm3Xxs9MKAACusWfkZhk877.jpg" style="float:none;" title="pv-mode-1.png" alt="wKioL1Pbm3Xxs9MKAACusWfkZhk877.jpg" />

650) this.width=650;" src="http://s3.51cto.com/wyfs02/M01/43/A3/wKiom1PbmlywrOqBAAEBRUxMzOI423.jpg" style="float:none;" title="pv-mode-2.png" alt="wKiom1PbmlywrOqBAAEBRUxMzOI423.jpg" />


如果這樣你以為就該高興了,那我就要呵呵了。

本著 no zuo no die , why you try的原則,我還是要找到根本解決方案。


深入分析

首先想想為啥CS中定義了啟用PV和不啟用PV模式的作業系統,為啥CS中基於KVM平台的windows虛擬機器系統磁碟不直接使用virtio介面類型。而除系統磁碟以外的第二塊,第三塊磁碟卻使用virtio介面類型?難道CS的開發人員不知道這樣效能會有質的提升嗎?


我認為:

1.啟用PV和不啟用PV,在CS代碼層面,最根本要解決的還是區分根磁碟介面類型使用IDE或VirtIO(針對KVM平台)

2.KVM平台中windows虛擬機器系統磁碟不直接使用virtio介面而是使用IDE,實際上是為了方便使用CS部署KVM虛擬機器的人員。為啥,如果windows虛擬機器預設也使用virtio介面類型的磁碟機,那你會碰到什麼問題?你會發現虛擬機器啟動失敗。或者當你在從ISO安裝一台windows虛擬機器時發現到磁碟機那一步,windows找不到磁碟機。這個時候你會怎麼辦?

安裝 vista,win7,2008.win8 等高版本windows時,在硬碟那一步驟中,允許你通過ISO載入磁碟機驅動。確實也提供了virtio的iso格式驅動安裝包,這個時候你可以彈出安裝iso,然後附加virtio的驅動iso,安裝完驅動以後再彈出該iso,再次附件系統iso。好了,系統可以識別到磁碟機了。那2003呢,xp呢,必須要插入磁碟片安裝驅動,你咋辦?CS提供軟碟機了不?

3.系統硬碟為IDE介面,其他盤均為virtio,如上面所說。先保證你可以把系統安裝好,再來裝virtio驅動。不管xp,2003,還是win7,2008,windows系統都能識別到IDE介面的硬碟吧,等你安裝好系統,再為資料盤安裝virtio驅動。

4.開發人員正是基於如上考慮,才這麼設計的吧。當然你可以在安裝完virtio的磁碟和網卡驅動後,關機,把虛擬機器作業系統類型改為Windows PV模式,再開機,那虛擬機器就會使用virtio作為系統磁碟介面類型。或者你可以把安裝好virtio驅動的虛擬機器轉化為模版,並設定作業系統類別型為windows pv,那麼以後使用該模版建立的虛擬機器,都不用再擔心驅動問題。

5.當然,如果你在CS之外,已經做好了KVM平台的windows虛擬機器模版,並直接加入了virtio的驅動,然後匯入CS。然後這個模版的作業系統類型,你也需要設定為Windows PV模式。


但,我目前所在的項目中,不太方便使用將虛擬機器或模版的作業系統類型修改為Windows PV的方式。

一來虛擬機器多了,統計不方便,所有的windows虛擬機器都是windows pv模式。。。二來,本著打破沙鍋的精神,從代碼層面,直接找到根源,並修改之。這樣就不用設定煩人的Windows PV了。

當然,前提是,我的模版中,已經加入了VirtIO的所有驅動(磁碟機+網卡)


解析代碼:


在CS官方的github https://github.com/apache/cloudstack

搜尋如下關鍵字: vritio,windows pv,other pv,ide 等等,自由發揮。


經過一番研究,找到如下兩個檔案:

https://github.com/apache/cloudstack/blob/afc188cb5c72e316975799c95529e8692ddcb94b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/KVMGuestOsMapper.java


https://github.com/apache/cloudstack/blob/7542ffc48282ff703fdb586ce447091260ae3c02/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java



1.首先來看KVMGuestOsMapper.java , 定義了kvm平台中,支援的作業系統列表:

public class KVMGuestOsMapper {    private static final Logger s_logger = Logger.getLogger(KVMGuestOsMapper.class);    private static Map<String, String> s_mapper = new HashMap<String, String>();    static {       ......        s_mapper.put("Windows Server 2008 (64-bit)", "Windows Server 2008");        s_mapper.put("Windows Server 2008 R2 (64-bit)", "Windows Server 2008");        s_mapper.put("Windows XP (64-bit)", "Windows XP");        s_mapper.put("Windows NT 4", "Windows NT");        s_mapper.put("Windows 3.1", "Windows 3.1");        s_mapper.put("Windows PV", "Other PV");        s_mapper.put("FreeBSD 10 (32-bit)", "FreeBSD 10");        s_mapper.put("FreeBSD 10 (64-bits", "FreeBSD 10");        s_mapper.put("Other PV (32-bit)", "Other PV");        s_mapper.put("Other PV (64-bit)", "Other PV");       ......    }


可以看到,此表為作業系統類型對應關係,s_mapper.put中,有兩個欄位: s_mapper.put(作業系統版本,作業系統類型);

 一個作業系統類型中,包括多個作業系統版本,注意我們說過的Windows PV,也被歸類為Other PV。


2.再來查看LibvirtComputingResource.java檔案。

尋找virtio看到如下資訊:

做了一個判斷,如果作業系統類型屬於GuestPVEnabled,則返回磁碟bus為VIRTIO,如果不屬於,則使用IDE。

    private DiskDef.diskBus getGuestDiskModel(String platformEmulator) {        if (isGuestPVEnabled(platformEmulator)) {            return DiskDef.diskBus.VIRTIO;        } else {            return DiskDef.diskBus.IDE;        }    }


然後再尋找GuestPVEnabled,尋找到一個類,該類型中,定義了,那些系統類別型屬於GuestPVEnabled,可以看到大部分linux系統和Other PV被歸類為GuestPVEnabled:

    
boolean isGuestPVEnabled(String guestOSName) {        if (guestOSName == null) {            return false;        }        if (guestOSName.startsWith("Ubuntu") || guestOSName.startsWith("Fedora 13") || guestOSName.startsWith("Fedora 12") || guestOSName.startsWith("Fedora 11") ||                guestOSName.startsWith("Fedora 10") || guestOSName.startsWith("Fedora 9") || guestOSName.startsWith("CentOS 5.3") || guestOSName.startsWith("CentOS 5.4") ||                guestOSName.startsWith("CentOS 5.5") || guestOSName.startsWith("CentOS") || guestOSName.startsWith("Fedora") ||                guestOSName.startsWith("Red Hat Enterprise Linux 5.3") || guestOSName.startsWith("Red Hat Enterprise Linux 5.4") ||                guestOSName.startsWith("Red Hat Enterprise Linux 5.5") || guestOSName.startsWith("Red Hat Enterprise Linux 6") || guestOSName.startsWith("Debian GNU/Linux") ||                guestOSName.startsWith("FreeBSD 10") || guestOSName.startsWith("Other PV")) {            return true;        } else {            return false;        }


徹底解決:

由此,我們有思路了,修改isGuestPVEnabled類(LibvirtComputingResource.java),或修改作業系統對應關係(KVMGuestOsMapper.java )。

但,修改這兩個檔案,效果不一樣:

1.如果修改LibvirtComputingResource.java檔案中的isGuestPVEnabled類,在該類中,添加作業系統類型。注意,是作業系統類型,而並非作業系統版本。比如添加windows 2008 作業系統所有版本均為PV模式,要加入guestOSName.startsWith("Windows Server 2008"),這樣的話,2008下面的所有版本,均應用PV設定。

2.如果修改KVMGuestOsMapper.java ,可以將其中一個作業系統版本,定義為PV模式。例如,將2008 R2定義為PV模式,

將:       

 s_mapper.put("Windows Server 2008 R2 (64-bit)", "Windows Server 2008");

修改為:

 s_mapper.put("Windows Server 2008 R2 (64-bit)", "Other PV");


這樣,不會影響Windows Server 2008 (32-bit)和Windows Server 2008 (64-bit)版本。


修改完畢後,需要將該檔案編譯(貌似需要將CS代碼全部編譯一遍,編譯單個檔案失敗)。會得到LibvirtComputingResource.class或KVMGuestOsMapper.class檔案。


然後使用winrar 等工具開啟KVM節點中:/usr/share/cloudstack-agent/lib/cloud-plugin-hypervisor-kvm-4.2.1.jar 檔案,將得到的class檔案替換至\com\cloud\hypervisor\kvm\resource目錄中的舊檔案。儲存。


然後再將修改後的jar檔案替換回KVM主機,重啟cloudstack-agent服務。然後建立新的Windows Server 2008 R2 (64-bit)虛擬機器,會發現預設使用virtio磁碟機和網卡適配器。


已經存在的Windows Server 2008 R2 (64-bit)虛擬機器,需要關機,再開機。才會應用virtio配置。注意在KVM虛擬化中,虛擬機器的關閉,再啟動和重啟是有區別的。


此方法由於直接修改代碼,將需要的作業系統類型或具體版本加入GuestPVEnabled類中,所以無需在CS中指定作業系統類型為Windows PV。從根本上解決該問題。


帶來的弊端:

每次升級,都需要編譯替換該檔案,除非使用自己編譯的安裝包進行安裝。


本文出自 “systems” 部落格,請務必保留此出處http://systems.blog.51cto.com/2500547/1533981

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.