资源隔离的两种虚拟化技术——虚拟机容器 容器技术的资源隔离
文章目錄
- 資源隔離的兩種主要方案
- 虛擬機(jī)VS容器
- 容器技術(shù)的資源隔離
- 從容器到Docker
資源隔離的兩種主要方案
??在服務(wù)器或者大型計(jì)算機(jī)集群中,往往需要運(yùn)行大量作業(yè)和應(yīng)用,為保證這些作業(yè)和應(yīng)用的進(jìn)程之間互不干擾,人們嘗試使用了資源隔離技術(shù)來(lái)為各個(gè)應(yīng)用進(jìn)程劃定固定的資源空間,使得進(jìn)程運(yùn)行范圍被限制在有限空間內(nèi),由此就保證了進(jìn)程的運(yùn)行不受其他進(jìn)程的干擾。這其中被廣泛使用的技術(shù)包括虛擬機(jī)技術(shù)和容器技術(shù),這兩種技術(shù)都屬于虛擬化的范疇,但是實(shí)現(xiàn)的機(jī)理和運(yùn)行效率卻相差懸殊,下面我們將對(duì)這兩種技術(shù)作以簡(jiǎn)單介紹,并將著重介紹容器技術(shù)涉及到的資源隔離。
虛擬機(jī)VS容器
??虛擬化技術(shù)分為主機(jī)級(jí)虛擬化和容器級(jí)虛擬化,分別對(duì)應(yīng)虛擬機(jī)和容器,而主機(jī)級(jí)虛擬化又分為兩種,具體分類情況大致列舉如下:
- 主機(jī)級(jí)虛擬化
- Type1:直接在硬件平臺(tái)(host machine)上裝一個(gè)虛擬機(jī)管理器(virtual machine monitor,縮寫為 VMM,eg. Hypervisor),在此之上安裝使用虛擬機(jī)(guest machine)。
- Type2:硬件平臺(tái)先安裝主機(jī)操作系統(tǒng)(host os),在此之上安裝VMM(虛擬機(jī)管理器),在這個(gè)軟件之上創(chuàng)建使用虛擬機(jī)。eg. VM,workstation,virtual Box
- 容器級(jí)虛擬化
- 容器級(jí)虛擬化即在內(nèi)核中的一個(gè)邏輯級(jí)別能夠設(shè)置相互隔離的區(qū)域,彼此之間互不干擾,由此就可以僅在用戶空間實(shí)現(xiàn)一組隔離的組件。在這個(gè)用戶空間實(shí)現(xiàn)的組件就稱為“容器”,每個(gè)容器都容納了一堆的進(jìn)程和用戶賬號(hào)文件等等。
??上圖展示了主機(jī)級(jí)虛擬化(以Type2為例)和容器級(jí)虛擬化的層次結(jié)構(gòu)圖,二者的區(qū)別就在于容器技術(shù)抽離了虛擬機(jī)中的客戶操作系統(tǒng)內(nèi)核,為何如此,我們以下就來(lái)作以簡(jiǎn)單分析。
??傳統(tǒng)的虛擬化方式的的確確可以在一組硬件平臺(tái)之上實(shí)現(xiàn)跨系統(tǒng)環(huán)境的隔離,調(diào)式等等,也可以實(shí)現(xiàn)資源的充分利用,但是其帶來(lái)的資源開銷也不容忽視。我們從上圖可以看出,傳統(tǒng)主機(jī)級(jí)虛擬化,存在兩層調(diào)度和資源分配。在第一級(jí)內(nèi)核層,要實(shí)現(xiàn)內(nèi)存虛擬化、CPU調(diào)度、I/O管理等等;而在第二級(jí)內(nèi)核層,即在宿主機(jī)內(nèi)核管理的抽象層,還需再次調(diào)度。這套機(jī)制的運(yùn)行將嚴(yán)重浪費(fèi)時(shí)間,造成額外開銷。 很多時(shí)候,創(chuàng)建虛擬機(jī)的目的是運(yùn)行有限的幾個(gè)生產(chǎn)進(jìn)程,而為此付出較大的代價(jià),顯得得不償失。因此減少中間層,減少開銷,提升效率尤為重要。
??由此,人們想到抽離虛擬機(jī)中進(jìn)程之下的內(nèi)核層,其實(shí)質(zhì)也就變成了容器技術(shù)。容器技術(shù)的目的在于:在系統(tǒng)內(nèi)核之上,提供隔離的用戶空間,使得用戶運(yùn)行進(jìn)程不受其他進(jìn)程干擾,進(jìn)程運(yùn)行所能看到的邊界就是自己所在用戶空間的邊界。運(yùn)行虛擬機(jī)的目的不只是為了運(yùn)行進(jìn)程,還有隔離等等。所以,雖然抽離了內(nèi)核層,但是隔離效果依然要存在,那么接下來(lái)我們就來(lái)了解一下容器技術(shù)中的隔離是如何實(shí)現(xiàn)的。
容器技術(shù)的資源隔離
??這里,我們首先來(lái)介紹Linux中的Namespace機(jī)制,Namespace(命名空間)是Linux提供的一種內(nèi)核級(jí)別環(huán)境隔離的方法。讀者應(yīng)該了解Linux系統(tǒng)中的chroot命令,chroot,即change root directory,通過(guò)修改分目錄把用戶jail到一個(gè)特定目錄下。chroot提供了一種簡(jiǎn)單的隔離模式:chroot內(nèi)部的文件系統(tǒng)無(wú)法訪問(wèn)外部的內(nèi)容。而Linux Namespace在此基礎(chǔ)之上,又提供了對(duì)UTS、mount、IPC、PID、User和Net等的隔離機(jī)制。
| UTS Namespace | 提供對(duì)主機(jī)名的隔離能力 |
| Mount Namespace | 提供對(duì)磁盤掛載點(diǎn)和文件系統(tǒng)的隔離能力 |
| IPC Namespace | 提供對(duì)進(jìn)程間通信的隔離能力 |
| PID Namespace | 提供對(duì)進(jìn)程的隔離能力 |
| User Namespace | 提供對(duì)用戶的隔離能力 |
| Network Namespace | 提供對(duì)網(wǎng)絡(luò)的隔離能力 |
- UTS Namespace
- UTS,即UNIX Time-sharing System namespace,提供了主機(jī)名和域名的隔離,使得子進(jìn)程有獨(dú)立的主機(jī)名和域名(hostname)。不難理解,運(yùn)行在同一主機(jī)上的多個(gè)容器,從用戶角度來(lái)看,著多個(gè)容器就是多臺(tái)可以獨(dú)立使用的主機(jī),那么從系統(tǒng)角度來(lái)看,要對(duì)這多個(gè)讓其進(jìn)行區(qū)分隔離,那他們就必須擁有自己獨(dú)一無(wú)二的名字,因此Linux Namespace提供了對(duì)主機(jī)名、域名的隔離。默認(rèn)情況下,容器的hostname就是它的短ID,用戶也可以在容器啟動(dòng)時(shí)設(shè)定一個(gè)名字,也通過(guò)-h或–hostname參數(shù)設(shè)置。
- Mount Namespace
- Mount Namespace為進(jìn)程提供獨(dú)立的文件系統(tǒng)試圖,讓容器看上去擁有整個(gè)文件系統(tǒng),即擁有/、/bin、/sbin、/etc等目錄。簡(jiǎn)單來(lái)講,mount namespace就是隔離文件系統(tǒng)的掛載點(diǎn),這樣進(jìn)程就只能看到自己的mount namespace中的文件系統(tǒng)掛載點(diǎn)。因此,在容器中對(duì)文件系統(tǒng)進(jìn)行的相關(guān)操作,并不能影響到host和其他容器的文件系統(tǒng)。
- IPC Namespace
- IPC,即Inter-Process Communication,是Unix/Linux中進(jìn)程間通信的一種方式,IPC有共享內(nèi)存、信號(hào)量、消息隊(duì)列等方法。每個(gè)用戶空間都有自己的IPC,所以,為了保證同一用戶空間進(jìn)程之間可以通信而跨用戶空間的進(jìn)程之間無(wú)法通信,也需要對(duì)IPC進(jìn)行隔離。IPC需要有一個(gè)全局的ID,既然是全局的,那么就意味著Namespace需要對(duì)這個(gè)ID進(jìn)行隔離,不能讓別的Namespace的進(jìn)程看到。
- PID Namespace
- PID,即Process ID。在所有用戶空間中,每個(gè)進(jìn)程都應(yīng)從屬于一個(gè)進(jìn)程,因?yàn)槊恳粋€(gè)進(jìn)程都由其父進(jìn)程創(chuàng)建,否則,該進(jìn)程則為init進(jìn)程。一個(gè)系統(tǒng)運(yùn)行要有兩棵樹的存在,即進(jìn)程樹和文件系統(tǒng)樹,既然對(duì)于當(dāng)前用戶空間,若讓其以為自身為當(dāng)前系統(tǒng)中唯一一個(gè)用戶空間,那么其中的進(jìn)程就必須明確自己從屬于某一init進(jìn)程或者自己就是init進(jìn)程。但一個(gè)實(shí)際的系統(tǒng)中,只存在一個(gè)init進(jìn)程,于是為每一個(gè)用戶空間創(chuàng)建的所謂的“init”進(jìn)程,對(duì)于該用戶空間來(lái)說(shuō)是一個(gè)特殊的進(jìn)程,但對(duì)于系統(tǒng)來(lái)說(shuō),并非init進(jìn)程。當(dāng)該特殊進(jìn)程結(jié)束時(shí),那么該用戶空間也將消失。照此理解,namespace也對(duì)PID進(jìn)行了隔離。
- User Namespace
- 所有的用戶進(jìn)程,都應(yīng)隸屬于某一真實(shí)用戶,不同應(yīng)用空間可能存在用戶ID相同,而用戶名不同的情況。一個(gè)系統(tǒng)只應(yīng)存在一個(gè)root用戶,而每一個(gè)用戶空間也需要一個(gè)“root”用戶,這也就意味著對(duì)于用戶空間而言的“root”用戶對(duì)于系統(tǒng)而言只是一個(gè)普通用戶,而對(duì)于所處用戶空間而言,可以將該用戶ID偽裝為ID為0的用戶,該用戶只能在自身用戶空間之內(nèi)為所欲為。照此理解,namespace亦實(shí)現(xiàn)了對(duì)用戶的隔離。
- Network Namespace
- 對(duì)于Network的隔離,即讓容器擁有自己獨(dú)立的網(wǎng)卡、IP、路由等資源,因而,兩個(gè)容器既可以通過(guò)網(wǎng)絡(luò)通信。
??在主機(jī)內(nèi)核級(jí)別,所有的資源都獨(dú)立只有一組,原本只支持單個(gè)用戶空間的運(yùn)行,后來(lái),因?yàn)橛羞@種運(yùn)行jail/vserver的需要,就在內(nèi)核級(jí)別將這些資源進(jìn)行了虛擬化,即將資源切分為多個(gè)互相隔離的環(huán)境(namespace),在同一內(nèi)核創(chuàng)建多個(gè)名稱空間,每個(gè)名稱空間有自己獨(dú)立的主機(jī)名。
??所有容器機(jī)制的實(shí)現(xiàn),Linux內(nèi)核已經(jīng)在內(nèi)核級(jí)通過(guò)一個(gè)namespace的機(jī)制對(duì)以上6中需要隔離的資源原生支持,可以直接通過(guò)系統(tǒng)調(diào)用向外輸出。容器級(jí)虛擬化技術(shù),可以在總體用戶空間上實(shí)現(xiàn)資源按比例分配,也可以在單一用戶空間上實(shí)現(xiàn)固定數(shù)量的資源(eg. num. of cores )綁定,而這一操作是借助cgroups(Control Groups,控制組)實(shí)現(xiàn)的。控制組就是一組按照某種標(biāo)準(zhǔn)劃分的進(jìn)程。Cgroups中的資源控制都是以控制組為單位實(shí)現(xiàn)。一個(gè)進(jìn)程可以加入到某個(gè)控制組,也從一個(gè)進(jìn)程組遷移到另一個(gè)控制組。一個(gè)進(jìn)程組的進(jìn)程可以使用cgroups以控制組為單位分配的資源,同時(shí)受到cgroups以控制組為單位設(shè)定的限制。
從容器到Docker
??從以上的介紹,我們知道在Linux中,容器技術(shù)主要通過(guò)namespace和Cgroups來(lái)實(shí)現(xiàn),但困難的是通過(guò)系統(tǒng)調(diào)用才能實(shí)現(xiàn)容器技術(shù),能做到這一點(diǎn)的人很少,因此將其打包作為一組工具,可以極大簡(jiǎn)化用戶的使用,由此誕生了LXC(Linux Container)。
??LXC雖然極大簡(jiǎn)化了使用,但在面臨容器分發(fā),大規(guī)模部署時(shí),依然存在大量的工作需要人為完成,因此,又在此基礎(chǔ)上誕生了Docker。
??容器時(shí)Linux內(nèi)核中的一項(xiàng)技術(shù),而Docker只是把這種技術(shù)的使用得以簡(jiǎn)化,使其得以普及。
??由于筆者可能存在理解或表述錯(cuò)誤,敬請(qǐng)讀者批評(píng)指正,也歡迎各位同仁一起交流學(xué)習(xí),共同進(jìn)步!
總結(jié)
以上是生活随笔為你收集整理的资源隔离的两种虚拟化技术——虚拟机容器 容器技术的资源隔离的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 陶哲轩实分析 附录 A 习题解答
- 下一篇: 二级下拉菜单缓慢渐变