在前面的文章,我提出一個核心觀點:容器就是進程。然而,對於虛擬機比較熟悉的讀者可能會產生一個疑問:”虛擬機不也是進程嗎?”
這個問題在寫作時,讓我花了很多時間思考,甚至一度考慮拿掉虛擬機的內容,以避免讀者混淆。然而如果不討論虛擬機,文章會有所遺漏,所以還是放回去了。因此為了釐清這些概念,在這邊對虛擬化技術進行更深入的討論。
在容器技術大規模採納之前,虛擬化技術一般是直接跟虛擬機畫上等號,但事實上,虛擬化技術早就存在於作業系統當中,而其中最具代表性的就是進程。
隨著科技發展,電腦的運算資源越來越多,作業系統作為硬體資源的管理者,利用進程來分配資源,使程式「以為」自己獨佔了 CPU。實際上,作業系統通過 Time slicing(時間片分配)和 Scheduler(排程器)讓多個進程在同一個物理 CPU 上輪流執行,模擬出一個虛擬 CPU 的效果。這種方式實現了每個應用程式共享物理 CPU,同時給它們提供了獨佔 CPU 的錯覺。
這種通過虛擬化共享資源的方式,讓每個程式“以為”自己獨佔資源的技術,就是我們所說的虛擬化。
虛擬化的目的是共享資源,所以共享什麼資源以及隔離方法,就是比較虛擬化技術的關鍵所在。
虛擬機:
進程:
容器:
因為虛擬機的進程是共享 Hypervisor 並由 Hypervisor 隔離,而容器的進程是 共享作業系統 Kernel 並由 namespace 隔離,這兩者有極大的不同。
介紹容器時經常需要拿虛擬機做比較,說先有虛擬機再有容器,但這樣的敘事架構容易造成一種誤解,誤解容器技術優於虛擬機技術,但事實上,因為容器和虛擬機的架構不同,所以應用場景不同,彼此不是互相替代的技術。
雖然虛擬機的模擬作業系統的開銷經常被視為缺點,但是對特定應用程式反而是必要的。例如,在實務中,虛擬機技術經常被用於 RDBMS 的部署,因為這些系統通常需要調整作業 Kernel 參數(例如 Huge Pages)來獲得最佳效能。
然而,這些為特定應用程式調整的 Kernel 參數,對其他應用程式可能會降低效能。在這樣的場景中,虛擬機的架構使得它可以在同一個宿主機上,為不同應用程式提供不同的 Kernel 參數。