進程、容器與虛擬機
參考:關于進程、容器與虛擬機的區別,你想知道的都在這!
進程、容器與虛擬機的結構圖
進程 介紹
進程是一個正在運行的程序,它是一個個可執行文件的實例。當一個可執行文件從硬盤加載到內存中的時候,一個進程就被創建出來了。 所以說,一個進程包括一堆它占用的內存空間以及額外的數據結構,操作系統內核使用這些數據結構來存儲關于該程序的一些類似狀態的重要信息。
一個程序本質上是一堆指令和數據結構,而單個 CPU 同一時間只能執行一條指令,同時 CPU 的頻率非常快,一秒可以執行數億條指令, 因此為了充分榨取 CPU 資源,必須在多個運行的程序之間共享 CPU 執行時間,也就是每個程序每隔一定時間,都可以分配到一些 CPU 執行時間,用來執行該程序的指令,而由于 CPU 執行速度非常快,CPU 切換執行程序的間隔時間非常短,用戶是察覺不出來的。 而在 CPU 切換執行程序的時候,當前程序的執行狀態必須保存在某個地方,因為很快 CPU 會切換回來繼續在剛才的那條指令處接著執行。 進程就是存儲了正在運行的程序的運行狀態的抽象。
操作系統對進程隔離了哪些資源?
默認情況下,操作系統對進程的限制非常少,基本上所有操作系統資源對進程都是可見的。少數的幾個限制比如:當將多個進程綁定在同一個端口上的時候, 只有第一個會成功,后續的都會失敗。對進程的隔離主要有兩個方面:
- 一個進程只能訪問自己的內存空間,它無法訪問到其他進程的內存空間。
- 一個進程只擁有受限的權限,這些權限取決于創建該進程的用戶。比如,
/etc/shadow
文件僅 root 用戶可以看,當用 root 用戶執行一個程序的時候,該程序就可以讀寫/etc/shadow
文件,而非 root 用戶訪問就會直接報錯。
容器技術 介紹
當容器技術在 2013 年興起的時候,很多人將容器視作一個輕量級虛擬機,這個觀點受到很多人的追捧, 因為容器就是為了替換虛擬機而被發明出來的。但從技術的角度看,一個容器更像一個進程,而非虛擬機。
容器的定義在網上有很多版本:
Wikipedia
的定義:容器是操作系統級別虛擬化的一個通用術語,業界有很多對容器的實現:Docker, lxc 和 rkt 等等。Unix/Linux System Admin
一書中這樣描述容器:容器是隔離出來的一組進程,這些進程被限制在一個私有的的根文件系統和進程命名空間內。Docker 官網
這樣介紹容器:容器是一個標準單元,它打包了應用程序的源代碼和這些代碼的所有依賴項,以便能夠讓應用程序在多個計算環境中快速部署。
個人對容器的理解是:容器是一組進程,操作系統內核提供了一些強大的功能,能夠讓這些進程假裝運行在一個單獨的機器上面。而在操作系統看來,這些進程跟系統上的其他進程沒有任何區別。以下就是讓這一切成為可能的內核功能:
-
Namespaces: Namespaces 技術能夠讓容器看起來像運行在一臺單獨的機器上那樣。
Linux
man
手冊對 namespace 有一個很棒的描述:Namespace 對全局系統資源進行了抽象,讓身處 namespace 中的進程認為它們獨立擁有這些全局資源。Linux 提供了七種不同類型的 namespaces,每種用來隔離不同的資源類型。七種 namespaces 分別對七種不同的全局系統資源進行了抽象、隔離:
- cgroups - 隔離根目錄
- IPC - 隔離進程間通信
- Network - 隔離網絡棧
- Mount - 隔離掛載點
- PID - 隔離進程 id
- User - 隔離用戶 id 和用戶組 id
- UTS - 隔離主機名
-
Cgroups:Cgroups 能夠限制一組進程能夠使用的硬件資源。Google 2006年開發了該技術,一開始被稱為進程容器。
-
Capabilities:一個權限點列表,用來控制進程的權限級別。
容器解決了什么問題?
容器能夠讓多個應用同時部署在一臺服務器上的多個隔離的環境中,但是這種隔離是偽隔離,容器假裝擁有自己獨立的操作系統,它可以運行多個進程, 從容器的角度來看,它處于一臺獨立的機器上。相比虛擬機,容器消耗更少的系統資源,這意味著相同的服務上,能夠部署更多的容器,更高的資源利用率。
容器總結
創建容器時,Namespaces 負責將容器中的進程隔離在一個單獨的環境中,Cgroups 負責限制容器能夠使用的硬件資源,例如:CPU, 內存等等。 這樣,容器就能像一臺單獨的虛擬機那樣運行,同時也不會濫用宿主機資源,影響其他進程或容器的運行。
虛擬機(VM)介紹
虛擬機的最原始定義為:一個高效的,隔離出來的真實計算機的副本。
虛擬機代表的是一種計算機虛擬化技術,通常來說,包括兩個部分:
- hypervisor:一個運行虛擬機的軟件,它在計算機硬件和虛擬機(VM)之間建立一層抽象,以便帶來更高的靈活性和更高效的資源利用率。
- 虛擬機(VM):指的就是虛擬機本身
虛擬機解決了什么問題?
-
虛擬機最主要的用途,就是在同一臺機器上安裝多個不同的操作系統。
例如,國內政府部門的網站,銀行發的各種設備基本只能在 Windows 中使用,這個對與 Mac 用戶太不友好了。這時,最優的解決方案就是在 MacOS 上面安裝一個虛擬機軟件,然后安裝一個 Windows 的操作系統。
-
虛擬機能夠在同一臺機器上同時運行多個應用,這些應用之間徹底隔離,互相不影響,非常的安全。同時能更充分地使用系統資源,避免浪費。
-
宏觀來說,虛擬化技術最主要的作用在于將單體的硬件資源轉變為可供多個個體共享的資源使用模式,最終目的還是提高系統資源使用效率。
在虛擬機出現以前,商業公司在每臺服務器上一般只運行一個應用,而當該應用不工作的時候,服務器資源就被白白浪費掉了。虛擬化技術使得一臺服務器上可以跑多個虛擬機,每個虛擬機可以被不同的用戶使用,這種方式大大降低了硬件資源的空置率。
現在上云的時代,購買的云服務器基本上都是虛擬機。
虛擬機中的隔離
虛擬機是完全跟宿主機操作系統隔離開來的,它們共享硬件資源,也就是說,虛擬機的隔離發生在硬件層面。(現在也可以在宿主機操作系統中創建虛擬機) 這個層面的隔離相比進程和容器來看,更加的徹底和安全。因為進程和容器都依賴宿主機操作系統。
但是,這種徹底隔離的代價,就是會占用物理機器更多的資源,畢竟虛擬機內部有一個完整的操作系統需要運行。
進程、容器與虛擬機的異同
實際應用中,容器既類似虛擬機,也可以說完全不是一類東西,這取決于從哪些角度來看待它們。
從技術的實現原理,宿主機的隔離機制來看(微觀):
- 進程在操作系統中只有很少的隔離,主要是獨立的內存空間和用戶權限。
- 容器本質上就是一組進程,相比宿主機中的其他進程,容器中的進程運行在自己獨立的 namespace 中,也不能無限制的使用宿主機資源,但是相比虛擬機,在安全性方面有所欠缺。
- 虛擬機在操作系統層面擁有完全的隔離,完全是一個獨立的環境,擁有一個構建于硬件之上的完整的操作系統。缺點是會占用較多的硬件資源。
從技術要解決的問題,技術的應用場景來看(宏觀):
- 進程的出現,是因為 CPU 需要一個對象,用來存儲程序運行期間的狀態、執行上下文等信息。
- 容器的發明,是為了在操作系統上創建隔離的環境,來同時運行多個應用程序。
- 虛擬機的出現,讓我們能夠在同一臺機器上面運行多個完全不同的操作系統,或者是創建多個絕對隔離的環境用來運行應用程序。
總結:
- **從技術的實現原理,宿主機的隔離機制來看:**容器更像進程,而非虛擬機。
- **從技術要解決的問題,技術的應用場景來看:**容器跟虛擬機非常相似,它們解決的是同樣的問題,也就是在同一臺 機器上,創建隔離的環境運行多個應用程序,提高機器的資源使用率。
- 通過上面的分析,可以了解到容器是一個非常強大的技術,它吸取了虛擬機的優點,但是輕量得等同于一組進程,同時也很好的控制了這層抽象帶來的資源消耗。