首先聲明,我對容器虛擬化并不精通,雖然我們公司也從事Linux Container這個容器虛擬化的研究,但是那是另外一個team的工作。
我這里從原理性的角度分析一下容器虛擬化的原理,可能和實際的容器虛擬化技術(shù)并不相同,還請見諒和指正。我只談原理不談風(fēng)月。
進(jìn)程是準(zhǔn)虛擬化的虛擬機(jī)
虛擬化技術(shù)最早是IBM在上世紀(jì)60年代的System/360操作系統(tǒng)中開發(fā)的。一般操作系統(tǒng)是用進(jìn)程來劃分資源,而System/360把虛擬計算機(jī)當(dāng)作資源劃分的單位。
System/360和后來的vmware,kvm等都是完全虛擬化。
讓我們看一下虛擬化的定義,維基百科中這樣定義:
虛擬化(Virtualization)是一個表現(xiàn)邏輯群組或電腦資源的子集的進(jìn)程,用戶可以用比原本的組態(tài)更好的方式來存取這些進(jìn)程。這些資源的新虛擬部份是不受現(xiàn)有資源的架設(shè)方式,地域或物理組態(tài)所限制。一般所指的虛擬化資源包括計算能力和資料儲存。
我的理解是,虛擬化就是虛擬硬件資源,包括CPU,內(nèi)存,硬盤,外設(shè)等等。
完全虛擬化完全虛擬了計算機(jī)的所有硬件。運行于其上的操作系統(tǒng)意識不到它運行在虛擬的計算機(jī)上。這樣的效果當(dāng)然是我們所理解的虛擬化。
那么,如果僅僅虛擬化一部分資源呢?算虛擬化嗎?
如果虛擬機(jī)上的操作系統(tǒng)能夠意識到自己運行在虛擬機(jī)中呢?算虛擬化嗎?
如果虛擬機(jī)中不能運行操作系統(tǒng),但依然虛擬化了若干硬件資源呢?算虛擬化嗎?
我的答案是上述種種情況都是虛化化!
Xen的虛擬機(jī)中的操作系統(tǒng)意識到自己是運行在虛擬機(jī)上,而不是真正的硬件上,它需要通過hypercall調(diào)用物理計算機(jī)上運行的操作系統(tǒng)提供的API才能完成運行。
Xen是虛擬機(jī)管理器嗎?是的,它是準(zhǔn)虛擬化類型的虛擬機(jī)。
KVM使用的virtio,是在虛擬機(jī)操作系統(tǒng)中安全了一個驅(qū)動。這個驅(qū)動知道自己運行在虛擬機(jī)中而不是物理機(jī)中。它通過hypercall調(diào)用物理機(jī)操作系統(tǒng)提供的服務(wù),實現(xiàn)了對外設(shè)的虛擬化。Virtio屬于外設(shè)的類虛擬化。
虛擬內(nèi)存技術(shù),把一小塊物理內(nèi)存虛擬為多塊獨立的非常非常大的虛擬內(nèi)存。內(nèi)存管理模塊算不算是hypervisor呢?當(dāng)然算。
多進(jìn)程操作系統(tǒng),分時調(diào)度多個進(jìn)程,每一個進(jìn)程都認(rèn)為自己獨占CPU。進(jìn)程調(diào)度算不算是hypervisor呢?當(dāng)然算。
現(xiàn)代操作系統(tǒng)同時支持多進(jìn)程和虛擬內(nèi)存技術(shù),進(jìn)程可以使用虛擬CPU,虛擬內(nèi)存,共享外部設(shè)備,使用的都是虛擬的資源。所以多進(jìn)程就更是虛擬化技術(shù)了。進(jìn)程就是虛擬機(jī)。
進(jìn)程和xen的虛擬機(jī)操作系統(tǒng)一樣,它知道自己運行在虛擬資源之上,需要使用hypercall才能完成自己的正常運行。
進(jìn)程的hypercall就是系統(tǒng)調(diào)用!
xen虛擬機(jī)通過hypercall要求Host為它提供特權(quán)和外部設(shè)備。進(jìn)程也是通過系統(tǒng)調(diào)用,要求內(nèi)核提供特權(quán)服務(wù)和外部設(shè)備。
因此,我們說內(nèi)核是準(zhǔn)虛擬化的hypervisor,進(jìn)程就是準(zhǔn)虛擬化的虛擬機(jī)。
容器虛擬化的原理
讀者可能對我上面的結(jié)論并不信服?赡軙f,xen的虛擬機(jī)可以跑操作系統(tǒng),雖然是修改過的操作系統(tǒng),但也是操作系統(tǒng)。進(jìn)程這個“虛擬機(jī)”可以嗎?
【其實也可以啦。qemu/bochs不就是在一個進(jìn)程中模擬一臺計算機(jī)。計算機(jī)甚至可以是異構(gòu)的。而且它們不用內(nèi)核提供任何特別的服務(wù)。 qemu/bochs是硬件模擬器。
現(xiàn)代語言,如java,.net,Python,javascript都使用進(jìn)程虛擬機(jī),虛擬了CPU。它們的源碼會被編譯成一種虛擬的CPU使用的虛擬的匯編語言。這樣,只要在各個平臺上實現(xiàn)虛擬CPU的進(jìn)程虛擬機(jī)就可以實現(xiàn)跨平臺了。而且,進(jìn)程虛擬機(jī)執(zhí)行偽匯編代碼要比直接解釋源代碼高效的多!
不過,上述這些技術(shù)都是在進(jìn)程中又玩了一些花樣,因此不在本文的談?wù)摲秶畠?nèi),我就不說了。
】
進(jìn)程是不可以直接運行操作系統(tǒng),但虛擬化的定義應(yīng)該是虛擬硬件資源,沒規(guī)定一定要運行操作系統(tǒng)啊!
計算機(jī)執(zhí)行的大部分業(yè)務(wù)任務(wù)都是用戶空間的進(jìn)程實現(xiàn)的。內(nèi)核僅僅是為進(jìn)程提供服務(wù)的。進(jìn)程虛擬機(jī)直接使用內(nèi)核提供的服務(wù),當(dāng)然比在虛擬機(jī)內(nèi)部再運行一個操作系統(tǒng)高效的多。不管你XEN的準(zhǔn)虛擬化操作系統(tǒng)內(nèi)核多么牛逼,我根本沒這個對于的內(nèi)核,總比你高效吧!
使用相同內(nèi)核的虛擬機(jī),聽起來是不是和容器虛擬化(又叫:操作系統(tǒng)級虛化化)一樣?
容器虛擬化,我的映像是Sun的Solaris操作系統(tǒng)首先提出和實現(xiàn)的。一臺計算機(jī)上,可以提供上百個獨立的進(jìn)程組。這些進(jìn)程組的資源是隔絕的。進(jìn)程組叫做容器。
容器中的進(jìn)程無法看到容器外的資源。每個容器也不能使用超出限額的資源。
容器虛擬化技術(shù)在虛擬主機(jī)領(lǐng)域應(yīng)用非常廣泛。使用容器虛擬化,可以嚴(yán)格控制硬盤空間,網(wǎng)絡(luò)流量等。它比傳統(tǒng)的虛擬主機(jī)更加靈活。用戶想裝什么軟件就裝什么軟件。而且對資源的控制更強(qiáng)。很難出現(xiàn)占用他人資源的情況。
知道誰對云計算/虛擬化最起勁嗎?就是虛擬主機(jī)廠商。rackspace公司就是國際領(lǐng)先的虛擬主機(jī)廠商。有了云計算和虛擬化,它運營虛擬主機(jī)的成本就更省了!
進(jìn)程虛擬機(jī)和容器虛擬化
其實,容器虛擬化就是基于進(jìn)程虛擬機(jī)實現(xiàn)的。上面已經(jīng)說了,進(jìn)程是共用內(nèi)核的虛擬機(jī),共用了硬件資源。
實現(xiàn)容器虛擬化,關(guān)鍵的就是容器的實現(xiàn)。容器隔離了物理資源。有些資源別人用不了,有些資源用的比我少。
現(xiàn)在我就說說我猜測的實現(xiàn)原理。我就以我最熟悉的Linux為例來說明。
Linux的每一個進(jìn)程都有一個namespace對象。它保存的就是從root開始的文件系統(tǒng)。子進(jìn)程會繼承父進(jìn)程的這個對象。因此,一般情況下,整個linux操作系統(tǒng)只有一個namespace對象?吹降亩际窍嗤奈募到y(tǒng)。
但是,進(jìn)程也可以創(chuàng)建自己獨立的namespace對象。它創(chuàng)建的子進(jìn)程就會繼承這個namespace對象。
chroot命令可以切換到另一個linux根文件系統(tǒng)執(zhí)行,容器虛擬化使用的就是這個原理。
容器虛擬化也使用了這個原理。這樣,每一個容器中的進(jìn)程看到的文件系統(tǒng)就是不同的,看到的設(shè)備文件也是不同的。因此可以使用不同的硬件資源和文件。
linux的qutoa模塊可以實現(xiàn)對文件夾等的大小限制。這樣就不能使用超過限制的硬盤資源。
Linux支持tap/tun等機(jī)制實現(xiàn)的虛擬網(wǎng)卡。每一個容器可以使用自己獨有的虛擬網(wǎng)卡。內(nèi)核可以對虛擬網(wǎng)卡進(jìn)行帶寬和流浪的限制和統(tǒng)計。
Linux的進(jìn)程組也可以設(shè)置時間片,規(guī)定進(jìn)程只能運行在哪一個或者哪幾個CPU上。這樣就可以限制容器虛擬機(jī)對CPU的使用率。
Linux內(nèi)核還可以對不同進(jìn)程組/用戶的內(nèi)存的使用進(jìn)行限制。
總之,Linux內(nèi)核可以根據(jù)進(jìn)程組或者用戶對資源進(jìn)行種種限制。而namespace可以設(shè)置對文件系統(tǒng)和設(shè)備的使用限制。目前LXC等容器虛擬化軟件都向Linux內(nèi)核增加了模塊,用于實現(xiàn)更加復(fù)雜的容器虛擬化。
據(jù)說,LXC的overload只有1%-3%。這應(yīng)該比任何完全虛擬化技術(shù)都要少很多。
當(dāng)然,容器虛擬化也不是萬能的。容器虛擬化不提供操作系統(tǒng)虛擬化。一個容器只是一些進(jìn)程的集合而已。如果用戶需要和Host的內(nèi)核不同的以內(nèi)核安裝一些驅(qū)動,甚至需要不同的操作系統(tǒng),如在LXC上要跑Windows,那么就需要完全虛擬化技術(shù)了。如果使用虛擬主機(jī)提供商的產(chǎn)品,那就意味著需要花比容器虛擬化更多的錢。因為虛擬主機(jī)提供商的成本更高了。
不過,即使是需要完全虛擬化的場合,我依然不推薦XEN。如果沒有支持硬件虛擬化的CPU,那么它不能跑Windows等軟件。因為XEN無法修改Windows內(nèi)核源碼。
XEN需要定制版本的Host的Linux內(nèi)核和定制版本的VM的Linux內(nèi)核。這些版本的數(shù)量是很少的,而且定制版本的Linux內(nèi)核,會使很多驅(qū)動無法運行。如,我的電腦如果運行XEN內(nèi)核,那么顯卡驅(qū)動就無法運行了。對內(nèi)核限制太多,那還不如使用容器虛擬化呢!至少不用改內(nèi)核,不會導(dǎo)致驅(qū)動無法運行。
聲明:本網(wǎng)部份文章為轉(zhuǎn)載文章,在每篇文章底部有說明,文章的觀點和立場僅代表作者個人立場,不代表微網(wǎng)立場,若是文章轉(zhuǎn)載中有侵范您的權(quán)益,請發(fā)郵件到 [email protected]或致電13922854199通知刪除,謝謝!