掌握這些 Docker 原理知識,又可以在面試官面前好好吹一波了

在現代的開發流程中隨處可見 Docker 的身影,Docker 提供了環境隔離、應用打包等功能讓服務部署變得特別簡單,本文將會淺析 Docker 背後所使用的技術,閱讀完後,你可以搞清楚如下問題:

  • 1. 容器與虛擬機之間的差別
  • 2.Docker 資源隔離的原理
  • 3.Docker 資源限制的原理
  • 4.Docker 分層結構的原理

容器 vs 虛擬機

虛擬機(VM)是計算機系統的仿真器,通過軟件模擬具有完整硬件系統功能的、運行在一個完全隔離環境中的完整計算機系統,能提供物理計算機的功能。

虛擬機通過在當前的真實操作系統上通過 Hypervisor 技術進行虛擬機運行環境與體系的建立並通過該技術進行資源控制,一個性能較好的物理機通常可以承載多個虛擬機,每個虛擬機都會有自己操作系統,如圖 1.1 所示。

 

從圖中可以看出,虛擬機提供了物理機硬件級別的操作系統隔離,這讓不同虛擬機之間的隔離很徹底,但也需要消耗更多資源,而有時不需要這麼徹底的隔離,而更希望不消耗那麼多資源,此時就可以使用容器技術。

容器可以提供操作系統級別的進程隔離,以 Docker 爲例,當我們運行 Docker 容器時,此時容器本身只是操作系統中的一個進程,只是利用操作系統提供的各種功能實現了進程間網絡、空間、權限等隔離,讓多個 Docker 容器進程相互不知道彼此的存在,如圖 1.2 所示。

 

虛擬機技術與容器技術的最大區別在於:多個虛擬機使用多個操作系統內核,而多個容器共享宿主機操作系統內核

Docker 資源隔離:Linux Namespace

Linux Namespace(Linux 命名空間)是 Linux 內核(Kernel)提供的功能,它可以隔離一系列的系統資源,如 PID(進程 ID,Process ID)、User ID、Network、文件系統等。

如果你熟悉 Linux,你可能會聯想到 linux 中的 chroot 命令,該命令允許將當前目錄修改成根目錄(即根目錄 / 的掛載點切換了),相當於文件系統被隔離了,Namespace 也具有相似的功能,但更加強大。

目前 Linux 主要提供 6 種不同類型的 Namespace,如下表所示。

 

以一個具體的例子來解釋 Namespace 的作用,假設你有一臺性能非常好的計算機,你向用戶出售自己的計算機的資源,每個用戶買到一個 ssh 實例,爲了避免不同客戶之間相互干擾,你可能會對不同用戶進行權限限制,讓用戶只能訪問自己 ssh 實例下的資源。

但有些操作需要 root 權限,而我們不能將 root 權限提供給用戶,此時就可以使用 Namespae 了,通過 User Namespace 對 UID 進行隔離,具體而言,UID 爲 x 的用戶在該 Namespace 中具有 root 權限,但在真實物理機中,他依舊是 UID 爲 x 的用戶,這就解決了用戶間隔離的問題。

此外還可以通過 PID Namespace 對 PID 進行隔離,從該 Namespace 中的用戶角度看,Namespace 中就像一臺新的 Linux,有自己的 init 進程(初始進程,PID 爲 1),其他進程的 PID 在 init 進程 PID 上遞增,如圖 1.3 所示。

 

圖中,進程 3 在父命名空就中 PID 爲 3,而在子命名空間中,其 PID 爲 1,用戶在該子命名空間中內看進程 3 就像 init 進程一樣。

Linux 提供了 3 個系統 API 方便我們使用 Namespace:

  • clone () 創建新進程,根據系統調用 flags 來決定哪種類型 Namespace 將會被創建,而該進程的子進程也會包含這些 Namespace。
  • setns () 將進程加入到已存在的 Namespace 中。
  • unshare () 將進程移出某個 Namespace

Docker 利用 Linux Namespace 功能實現多個 Docker 容器相互隔離,具有獨立環境的功能,Go 語言對 Namespce API 進行了相應的封裝,從 Docker 源碼中可以看到相關的實現。

 

Docker 資源限制:Linux Cgroups

Docker 通過 Linux Namespace 幫進程隔離出自己單獨的空間 / 資源,那 Docker 如何限制進程對這些資源的使用呢?

Docker 容器本質依舊是一個進程,多個 Docker 容器運行時,如果其中一個 Docker 進程佔用大量 CPU 和內存就會導致其他 Docker 進程響應緩慢,爲了避免這種情況,可以通過 Linux Cgroups 技術對資源進行限制。

Linux Cgroups(Linux Contorl Groups,簡稱 Cgroups)可以對一組進程及這些進程的子進程進行資源限制、控制和統計的能力,其中包括 CPU、內存、存儲、網絡、設備訪問權限等,通過 Cgroups 可以很輕鬆的限制某個進程的資源佔用並且統計該進程的實時使用情況。

Cgroups 由 3 個組件構成,分別是 cgroup(控制組)、subsystem(子系統)以及 hierarchy(層級樹),3 者相互協同作用。

  • cgroup 是對進程分組管理的一種機制,一個 cgroup 通常包含一組(多個)進程,Cgroups 中的資源控制都以 cgroup 爲單位實現。
  • subsystem 是一組(多個)資源控制的模塊,每個 subsystem 會管理到某個 cgroup 上,對該 cgroup 中的進程做出相應的限制和控制。
  • hierarchy 會將一組(多個)cgroup 構建成一個樹狀結構,Cgropus 可以利用該結構實現繼承等功能

3 這具體如何相互協同作用?

Cgroups 會將系統進程分組(cgroup)然後通過 hierachy 構建成獨立的樹,樹的節點就是 cgroup(進程組),每顆樹都可以與一個或多個 subsystem 關聯,subsystem 會對樹中對應的組進行操作。

有個幾個規則需要注意。

1. 一個 subsystem 只能附加到一個 hierarchy,而一個 hierarchy 可以附加多個 subsystem 2. 一個進程可以作爲多個 cgroup 的成員,但這些 cgroup 只能在不同的 hierarchy 中 3. 一個進程 fork 出子進程,此時子進程與父進程默認是在同一個 cgroup 中,可以根據需要移動到其他 cgroup

 

Docker 分層結構:Union File System

我們都知道 Docker 鏡像是一種分層結構,每一層構建在其他層之上,從而實現增量增加內容的功能,這是如何實現的?

要理解這個問題,首先需要理解 Union File System(簡稱,UnionFS),它是爲 Linux 系統設計的將其他文件系統聯合到一個聯合掛載點的文件系統服務。UnionFS 使用 branch(分支)將不同文件系統的文件和目錄透明地疊加覆蓋,形成一個單一一致的文件系統,此外 UnionFS 使用寫時複製(Copy on Write,簡稱,CoW)技術來提高合併後文件系統的資源利用。(後續的文章會介紹 CoW 技術)

Docker 使用的第一種存儲驅動爲 AUFS(Advanced Multi-layered unification filesytem),AUFS 完全重寫了早期的 UnionFS,目的是提高其性能與可靠性,此外還引入瞭如 branch 負載均衡等新功能。

與 UnionFS 類似,AUFS 可以在基礎的文件系統上增量的增加新的文件系統,通過疊加覆蓋的形式最終形成一個文件系統。通常 AUFS 最上層是可讀可寫層,而其他層只是只讀層,每一層都只是一個普通的文件系統。

Docker 鏡像分層、增量增加等功能正是通過利用 AUFS 的分層文件系統結構、增量增加等功能實現,這也導致了運行 Docker 容器如果沒有指定 volume(數據卷)或 bind mount,則 Docker 容器結束後,運行時產生的數據便丟失了。

Docker 存儲驅動除了 AUFS 外,還有 OverlayFS、Devicemapper、Btrfs、ZFS 等,本文不多討論。

總結

至此,我們知道了 Docker 核心功能的基本原理,Docker 利用 Linux Namespace 進行網絡、用戶、進程等不同資源的隔離,使用 Linux Cgroups 技術對資源的使用進行限制與監控,通過 AUFS 等存儲驅動實現分層結構與增量更新等功能。

現實世界中的 Docker 還使用了很多其他技術,但最核心且最基本的就是 Linux Namespace、Linux Cgrpus 與 AUFS。

Docker 在當前的開發流程中已成必備工具,容器帶來的優勢解放了運維人員也避免了開發人員遇到開發環境與線上環境不一致時導致問題的情況。目前容器編排技術(K8s)快速發展,Docker 容器技術在未來也將會進一步發展,它值得我們花時間與精力去了解其本質。

給大家分享一份【Docker實戰】PDF資料

本書被分成3個部分。

第一部分介紹Docker和容器的特點,幫助你理解如何安裝和卸載Docker中發佈的軟件。你將學習如何運行、管理,並在不同的容器結構連接不同類型的軟件。第一部分介紹每一個Docker用戶需要的基本技能。

第2部分介紹Docker的封裝和軟件的分發,涵蓋了不同大小Docker鏡像的底層機制,以及對不同的封裝和分發方法所進行的調查。這一部分還包括對Docker Distribution項目的深入分析。

第3部分介紹多容器項目和多主機環境,覆蓋了Docker Compose、Machine和Swarm項目。這部分內容會知道構建和部署多個真實的實例,規模接近於大型的服務器軟件。

Docker目錄

轉發文章+關注作者,然後私信 “文檔” 即可獲得免費領取《Docker實戰》的免費領取方式!

第一部分——保持一臺整潔的機器

第1章丨歡迎來到Docker世界

 

第2章丨在容器中運行軟件

 

 


第3章丨軟件安裝的簡化

 


第4章丨持久化存儲和卷間狀態共享

 


第5章丨網絡訪問

 

 

第6章丨隔離——限制危險

 


第二部分——鏡像發佈:如何打包軟件

第7章丨在鏡像中打包軟件

 

第8章丨構建自動化和高級鏡像設置

 

第9章丨公有和私有軟件分發

 

第10章丨運行自定義Registy

 

第三部分——多容器和多主機環境

第11章丨Docker Compose聲明式環境

 

第12章丨Docker Machine和Swarm集羣

 

 

轉發文章+關注作者,然後私信 “文檔” 即可獲得免費領取《Docker實戰》的免費領取方式!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章