引言
在解釋docker是什么之前,我們首先應該先了解的是容器化的概念。
什么是容器?就是一個沙箱,在這個沙箱中涵蓋了特定應用運行的一切依賴的內容。但他不是一個操作系統,且和底層的操作系統是隔離的。
什么是容器化?容器化就是將軟件和應用所需要的所有依賴打包到一個獨立的容器中,使得軟件能夠在不同的計算環境中,高效的、按照預期運行的技術。
先有容器化的概念還是先有的docker?先有的容器化概念,容器化最早提出是在1979年,貝爾實驗室發明了chroot,用于將一個進程的文件系統隔離起來,通常認為這是容器技術的開端。
和虛擬化技術有什么聯系?有關聯也有區別,參考下文“虛化技術”。
Docker 優勢
一項技術的優勢,通常是在說他解決了傳統技術的哪一項痛點,這也是技術持續迭代的一個動力。
傳統部署痛點
傳統的部署方式通常是在虛擬機上直接部署,如果你有部署過虛擬機服務,你會經歷過如下痛點:
1. 環境不一致
主要是設備、系統、工具等方面的差異,舉個例子:一般我們在服務器上都是使用Linux的相關版本,所以如果開發使用的是Linux系統,一些腳本等配置都可以無縫遷移,但如果使用windows,我們可能會經歷在本地能跑,但是部署到服務器卻因為缺少一些信息,無法啟動或調用失敗的問題。
2. 部署復雜
傳統的虛擬機手工部署,在首次部署時,需要安裝很多工具包,如果某個步驟出錯,就可能會需要我們從頭開始排查,耗費比較多的人力成本。后續的部署過程中,以war包為例,如果war包有問題,我們又需要趕緊重新部署舊的服務,否則服務掛了對用戶來說太痛了,這個時期的部署一般都選擇夜間用戶谷期進行。
當然,后來也演化除了一鍵部署等運維手段,但是依舊有跨環境部署的問題,因為生產環境限制永遠要比我們開發測試的環境更高。
3. 資源占用率很高
傳統虛擬化技術是模擬完整的操作系統實現相關的隔離,需要提前進行資源的“預分配”,所以這里的資源浪費是比較嚴重的,一臺服務器,可能部署3臺虛擬機就到頂了。
4. 擴容效率低
虛擬機部署方式下,我們如果遭遇到突發的大流量,比如某位名人空降微博熱搜,這種情況下,大概率是會宕機的(不是DDoS,勝似DDoS),等虛擬機的再擴容啟動(虛擬機啟動相對耗時較長),這波流量可能就過去了,吃不到。
Docker 的解決方法
對于以上的痛點,Docker 采取了“鏡像+容器”的方案來解決,實現了“一次構建,隨處運行”。
1. 鏡像的本質就是:應用運行時所需要的完整環境快照(包含程序、庫、資源、配置文件等),他不包含動態的數據,一旦構建完成,就不會再變了。
由于環境的固化,我們得以實現版本和配置差異的打平,解決了環境不一致的問題。同時由于鏡像分層存儲的架構設計,使得不同鏡像可以復用底層相同的層,從而避免“資源冗余”。
2. 容器的本質則是:一個具有Namespace的進程,它具有自己的文件系統、網絡和進程空間。
容器是一個輕量、隔離的執行環境,專門用于運行我們的鏡像而不需要考慮能否運行其他應用,同時由于共享操作系統內核,所以他沒有內核的開銷,不需要安裝完整的操作系統,再加上它本身也具有被創建、啟動、暫停、停止、刪除的能力,所以為什么不能說他是一個輕量化的虛擬機呢?
這些特點使得容器資源占用變低,啟動速度更快,從而也使得擴縮容的效率變高。
這里提供一下容器化和虛擬化技術的對比:
維度 | 容器化(Containerization) | 虛擬化(Virtualization) |
隔離級別 | 進程級(共享內核) | 系統級(每個VM有獨立內核) |
資源抽象 | 抽象應用層(運行時環境、依賴) | 抽象硬件層(CPU、內存、存儲、網絡) |
啟動速度 | 秒級(無需加載內核) | 分鐘級(需啟動完整操作系統) |
資源效率 | 高(輕量級) | 低(VM管理程序占用額外資源) |
密度 | 單主機可運行數百個容器 | 單主機通常運行數十個VM |
隔離強度 | 中等(依賴內核安全機制,存在容器逃逸風險) | 高(完全獨立的操作系統環境) |
適用場景 | 微服務、DevOps、彈性伸縮、CI/CD | 傳統應用遷移、關鍵業務系統、多租戶隔離 |
代表技術 | Docker,Kubernetes,containerd | VMware vSphere,Hyper-V,KVM,Xen |
Docker 引擎
上文說到容器的本質是一個進程,那么也就是說可以通過操作系統來直接 kill 掉對應的 docker 實例,也可以通過操作系統來啟停容器。
理論上來說是這樣,但是我們在創建一個 docker 容器的同時,需要需要一個工具幫我們去處理創建該進程所需要準備的東西,以及在創建完成后,可以幫助我們快速的去維護這些容器實例,所以,這樣一個工具,就是?Docker 引擎,他能做到的自然是不止我們現在說的這些內容。
從使用層面來說,Docker 引擎是 Docker 的核心組件,但是也不必過于害怕,這也就是一個普通的應用工具,和其他Linux命令一樣,只是他的能力聚焦于管理 Docker 核心資源:
鏡像(Image)、容器(Container)、網絡(Network)、存儲卷(Volume)。
Docker 引擎的工作主要是負責管理和運行容器,包含以下幾個部分:
- Docker 守護進程:Docker 引擎的后臺服務,負責持續運行并處理容器相關的請求,守護進程管理著整個容器的生命周期。
- Docker REST API:提供 HTTP 的 API 接口,通過 HTTP 請求和 Docker 引擎進行交互。
- Docker 命令行工具:cli 工具,可以在命令行直接輸入 Docker 命令與 Docker 引擎進行交互。
- 容器與鏡像管理:鏡像的創建和存儲、容器的生命周期管理、容器網絡管理。
但整體看下來,不難發現,Docker 引擎所處理的主要就是我們前文所說的兩件事情:資源管理和容器的生命周期管理。
在這里的“資源”所指代的范圍是比較大的,網絡也被認為是一種資源。
在目前的網絡上搜索 Docker ,大多數的文章基本是在進行 Docker 的命令行的使用及解釋,了解一下就行了,實際使用的時候翻閱也沒什么問題:
docker pull
docker run image
docker stop
docker ps
...
Docker 的輕量級
那么 Docker 的輕量級因何而來,為什么他就比虛擬機要輕量?
要理解這個問題,其實也就是一兩句話的事情:傳統的虛擬機是在一個硬件層之上運行的一個完整的操作系統,而 Docker 則是運行在應用層之上的。不妨想一下,啟動電腦快還是啟動應用快?
傳統虛擬機是通過虛擬化技術將底層的硬件虛擬化為硬件資源池,提供給上層的每個 VM (Virtual Machine,虛擬機)使用,讓每個 VM 都認為自己是獨立運行在物理機上的。
其后,每個 VM 又是運行的完整的操作系統,僅僅是操作系統+基礎服務就需要占用較多的資源,而且這些資源是被 VM 獨占的,不可被其他虛擬機復用。
虛擬機啟動時,會鎖定配置好的資源分配,如VM需要2c4g的基礎資源,則會預先鎖定,不讓其他 VM 使用該資源
這種虛擬化架構實際就是寄居虛擬化,主要分三層:宿主操作系統(Host OS) -> 虛擬機監控程序(Hypervisor) -> 虛擬機(Guest OS),下面是對應的架構圖,一個典型的應用就是我們熟知的 VMWare Workstation:
這就是傳統虛擬機重的由來。
Docker 的輕量級也并不是因為他解決了這些問題,而是因為他另辟蹊徑,不再去模擬一個完整的操作系統,而是基于 Linux 內核的 Namespace、Cgroups以及UnionFS技術,實現從系統級別的隔離轉換到了進程級別的隔離,從架構層面抹除了硬件模擬和虛擬機操作系統的開銷。
- Namespace 提供資源隔離機制:將 PID、Network、Mount、User 等資源進行命名空間層級的劃分,不同的 Namespace 的進程無法互相訪問到。
- Cgroups 進行配額限制:避免某一個進程組無限制的消耗資源,同時可以讓空閑資源被釋放。
- UnionFS 實現鏡像分層復用:不同的鏡像可復用底層鏡像,減少存儲的冗余。
這樣一來,Docker 虛擬化的架構就變成了:
沒有了 Hypervisor 和 Guest OS,同時由于 Docker 是基于 Linux 內核技術的,所以宿主操作系統也只能是 Linux。
Docker 與云原生
云原生本質是一種構建和運行應用程序的方法,是以 k8s 為代表的一套技術體系和方法論[3]。這套技術體系是由 “容器化技術、編排調度、服務治理、可觀測性” 等技術組成,而其中的容器化技術是云原生的 “基礎載體”。而 Docker 則是容器化技術的 “開創者與早期絕對主導者”,也是云原生的核心應用,他通過解決傳統部署的痛點問題,使得以容器為基礎去構建分布式應用成為可能,從而推動了云原生的普及落地,可以說,如果沒有 Docker,那云原生可能發展的不會如此迅速,還需要等待另一個“Docker”技術來推動其發展。
此外,Docker 定義的容器鏡像標準,也成為了云原生應用的一個交付載體標準。目前的云原生應用的 CI/CD 標準流程是:代碼提交→自動構建 Docker 鏡像→鏡像推送到倉庫→編排工具拉取鏡像部署,可以看到,在這個過程中,鏡像就是代碼到運行時的中間載體,也是我們交付的一個產物標準。
目前 k8s (1.20 以后的版本)已經棄用了對 Docker 的直接支持,轉為原生支持 CRI 標準的容器運行時,但是這并不代表著 Docker 已經過時,只是 k8s 從以 Docker 主導轉變為了基于 Docker 標準,多工具的生態協同。
總結
Docker 不僅是一項技術創新,更重塑了軟件產業的協作模式。Docker 將 Linux 內核的 Namespace、Cgroups、UnionFS 等技術封裝成簡單易用的工具鏈條,通過“鏡像-容器 ”架構解決了傳統部署的行業痛點問題,標準化了應用交付格式,為 k8s 等編排平臺提供了基礎載體,重塑了軟件開發流程,實現“一次構建,到處運行”的理想態,推動了云原生的迅速發展。
未來,隨著云原生技術持續演進,Docker 可能也不再是容器領域的唯一焦點,但其倡導的 "標準化、輕量化、可移植" 理念已深刻影響整個行業。無論是作為開發者日常工具,還是云原生基礎設施的重要組成部分,Docker 仍會在上云浪潮中扮演關鍵角色。