2022-10-08 分類: 網(wǎng)站建設(shè)
在現(xiàn)代的開發(fā)流程中隨處可見 Docker 的身影,Docker 提供了環(huán)境隔離、應(yīng)用打包等功能讓服務(wù)部署變得特別簡單,本文將會(huì)淺析 Docker 背后所使用的技術(shù),閱讀完后,你可以搞清楚如下問題:
容器與虛擬機(jī)之間的差別 Docker 資源隔離的原理 Docker 資源限制的原理 Docker 分層結(jié)構(gòu)的原理容器 vs 虛擬機(jī)
虛擬機(jī)(VM)是計(jì)算機(jī)系統(tǒng)的仿真器,通過軟件模擬具有完整硬件系統(tǒng)功能的、運(yùn)行在一個(gè)完全隔離環(huán)境中的完整計(jì)算機(jī)系統(tǒng),能提供物理計(jì)算機(jī)的功能。
虛擬機(jī)通過在當(dāng)前的真實(shí)操作系統(tǒng)上通過 Hypervisor 技術(shù)進(jìn)行虛擬機(jī)運(yùn)行環(huán)境與體系的建立并通過該技術(shù)進(jìn)行資源控制,一個(gè)性能較好的物理機(jī)通??梢猿休d多個(gè)虛擬機(jī),每個(gè)虛擬機(jī)都會(huì)有自己操作系統(tǒng),如圖 1.1 所示。
從圖中可以看出,虛擬機(jī)提供了物理機(jī)硬件級(jí)別的操作系統(tǒng)隔離,這讓不同虛擬機(jī)之間的隔離很徹底,但也需要消耗更多資源,而有時(shí)不需要這么徹底的隔離,而更希望不消耗那么多資源,此時(shí)就可以使用容器技術(shù)。
容器可以提供操作系統(tǒng)級(jí)別的進(jìn)程隔離,以 Docker 為例,當(dāng)我們運(yùn)行 Docker 容器時(shí),此時(shí)容器本身只是操作系統(tǒng)中的一個(gè)進(jìn)程,只是利用操作系統(tǒng)提供的各種功能實(shí)現(xiàn)了進(jìn)程間網(wǎng)絡(luò)、空間、權(quán)限等隔離,讓多個(gè) Docker 容器進(jìn)程相互不知道彼此的存在,如圖 1.2 所示。
虛擬機(jī)技術(shù)與容器技術(shù)的大區(qū)別在于:多個(gè)虛擬機(jī)使用多個(gè)操作系統(tǒng)內(nèi)核,而多個(gè)容器共享宿主機(jī)操作系統(tǒng)內(nèi)核。
Docker 資源隔離:Linux Namespace
Linux Namespace(Linux 命名空間)是 Linux 內(nèi)核(Kernel)提供的功能,它可以隔離一系列的系統(tǒng)資源,如 PID(進(jìn)程 ID,Process ID)、User ID、Network、文件系統(tǒng)等。
如果你熟悉 Linux,你可能會(huì)聯(lián)想到 linux 中的 chroot 命令,該命令允許將當(dāng)前目錄修改成根目錄(即根目錄 / 的掛載點(diǎn)切換了),相當(dāng)于文件系統(tǒng)被隔離了,Namespace 也具有相似的功能,但更加強(qiáng)大。
目前 Linux 主要提供 6 種不同類型的 Namespace,如下表所示。
以一個(gè)具體的例子來解釋 Namespace 的作用,假設(shè)你有一臺(tái)性能非常好的計(jì)算機(jī),你向用戶出售自己的計(jì)算機(jī)的資源,每個(gè)用戶買到一個(gè) ssh 實(shí)例,為了避免不同客戶之間相互干擾,你可能會(huì)對(duì)不同用戶進(jìn)行權(quán)限限制,讓用戶只能訪問自己 ssh 實(shí)例下的資源。
但有些操作需要 root 權(quán)限,而我們不能將 root 權(quán)限提供給用戶,此時(shí)就可以使用 Namespae 了,通過 User Namespace 對(duì) UID 進(jìn)行隔離,具體而言,UID 為 x 的用戶在該 Namespace 中具有 root 權(quán)限,但在真實(shí)物理機(jī)中,他依舊是 UID 為 x 的用戶,這就解決了用戶間隔離的問題。
此外還可以通過 PID Namespace 對(duì) PID 進(jìn)行隔離,從該 Namespace 中的用戶角度看,Namespace 中就像一臺(tái)新的 Linux,有自己的 init 進(jìn)程(初始進(jìn)程,PID 為 1),其他進(jìn)程的 PID 在 init 進(jìn)程 PID 上遞增,如圖 1.3 所示。
圖中,進(jìn)程 3 在父命名空就中 PID 為 3,而在子命名空間中,其 PID 為 1,用戶在該子命名空間中內(nèi)看進(jìn)程 3 就像 init 進(jìn)程一樣。
Linux 提供了 3 個(gè)系統(tǒng) API 方便我們使用 Namespace:
clone () 創(chuàng)建新進(jìn)程,根據(jù)系統(tǒng)調(diào)用 flags 來決定哪種類型 Namespace 將會(huì)被創(chuàng)建,而該進(jìn)程的子進(jìn)程也會(huì)包含這些 Namespace。
setns () 將進(jìn)程加入到已存在的 Namespace 中。
unshare () 將進(jìn)程移出某個(gè) Namespace
Docker 利用 Linux Namespace 功能實(shí)現(xiàn)多個(gè) Docker 容器相互隔離,具有獨(dú)立環(huán)境的功能,Go 語言對(duì) Namespce API 進(jìn)行了相應(yīng)的封裝,從 Docker 源碼中可以看到相關(guān)的實(shí)現(xiàn)。
Docker 資源限制:Linux Cgroups
Docker 通過 Linux Namespace 幫進(jìn)程隔離出自己單獨(dú)的空間 / 資源,那 Docker 如何限制進(jìn)程對(duì)這些資源的使用呢?
Docker 容器本質(zhì)依舊是一個(gè)進(jìn)程,多個(gè) Docker 容器運(yùn)行時(shí),如果其中一個(gè) Docker 進(jìn)程占用大量 CPU 和內(nèi)存就會(huì)導(dǎo)致其他 Docker 進(jìn)程響應(yīng)緩慢,為了避免這種情況,可以通過 Linux Cgroups 技術(shù)對(duì)資源進(jìn)行限制。
Linux Cgroups(Linux Contorl Groups,簡稱 Cgroups)可以對(duì)一組進(jìn)程及這些進(jìn)程的子進(jìn)程進(jìn)行資源限制、控制和統(tǒng)計(jì)的能力,其中包括 CPU、內(nèi)存、存儲(chǔ)、網(wǎng)絡(luò)、設(shè)備訪問權(quán)限等,通過 Cgroups 可以很輕松的限制某個(gè)進(jìn)程的資源占用并且統(tǒng)計(jì)該進(jìn)程的實(shí)時(shí)使用情況。
Cgroups 由 3 個(gè)組件構(gòu)成,分別是 cgroup(控制組)、subsystem(子系統(tǒng))以及 hierarchy(層級(jí)樹),3 者相互協(xié)同作用。
cgroup 是對(duì)進(jìn)程分組管理的一種機(jī)制,一個(gè) cgroup 通常包含一組(多個(gè))進(jìn)程,Cgroups 中的資源控制都以 cgroup 為單位實(shí)現(xiàn)。
subsystem 是一組(多個(gè))資源控制的模塊,每個(gè) subsystem 會(huì)管理到某個(gè) cgroup 上,對(duì)該 cgroup 中的進(jìn)程做出相應(yīng)的限制和控制。
hierarchy 會(huì)將一組(多個(gè))cgroup 構(gòu)建成一個(gè)樹狀結(jié)構(gòu),Cgropus 可以利用該結(jié)構(gòu)實(shí)現(xiàn)繼承等功能
3 這具體如何相互協(xié)同作用?
Cgroups 會(huì)將系統(tǒng)進(jìn)程分組(cgroup)然后通過 hierachy 構(gòu)建成獨(dú)立的樹,樹的節(jié)點(diǎn)就是 cgroup(進(jìn)程組),每顆樹都可以與一個(gè)或多個(gè) subsystem 關(guān)聯(lián),subsystem 會(huì)對(duì)樹中對(duì)應(yīng)的組進(jìn)行操作。
有個(gè)幾個(gè)規(guī)則需要注意。
1. 一個(gè) subsystem 只能附加到一個(gè) hierarchy,而一個(gè) hierarchy 可以附加多個(gè) subsystem 2. 一個(gè)進(jìn)程可以作為多個(gè) cgroup 的成員,但這些 cgroup 只能在不同的 hierarchy 中 3. 一個(gè)進(jìn)程 fork 出子進(jìn)程,此時(shí)子進(jìn)程與父進(jìn)程默認(rèn)是在同一個(gè) cgroup 中,可以根據(jù)需要移動(dòng)到其他 cgroup
Docker 分層結(jié)構(gòu):Union File System
我們都知道 Docker 鏡像是一種分層結(jié)構(gòu),每一層構(gòu)建在其他層之上,從而實(shí)現(xiàn)增量增加內(nèi)容的功能,這是如何實(shí)現(xiàn)的?
要理解這個(gè)問題,首先需要理解 Union File System(簡稱,UnionFS),它是為 Linux 系統(tǒng)設(shè)計(jì)的將其他文件系統(tǒng)聯(lián)合到一個(gè)聯(lián)合掛載點(diǎn)的文件系統(tǒng)服務(wù)。UnionFS 使用 branch(分支)將不同文件系統(tǒng)的文件和目錄透明地疊加覆蓋,形成一個(gè)單一一致的文件系統(tǒng),此外 UnionFS 使用寫時(shí)復(fù)制(Copy on Write,簡稱,CoW)技術(shù)來提高合并后文件系統(tǒng)的資源利用。(后續(xù)的文章會(huì)介紹 CoW 技術(shù))
Docker 使用的第一種存儲(chǔ)驅(qū)動(dòng)為 AUFS(Advanced Multi-layered unification filesytem),AUFS 完全重寫了早期的 UnionFS,目的是提高其性能與可靠性,此外還引入了如 branch 負(fù)載均衡等新功能。
與 UnionFS 類似,AUFS 可以在基礎(chǔ)的文件系統(tǒng)上增量的增加新的文件系統(tǒng),通過疊加覆蓋的形式最終形成一個(gè)文件系統(tǒng)。通常 AUFS 最上層是可讀可寫層,而其他層只是只讀層,每一層都只是一個(gè)普通的文件系統(tǒng)。
Docker 鏡像分層、增量增加等功能正是通過利用 AUFS 的分層文件系統(tǒng)結(jié)構(gòu)、增量增加等功能實(shí)現(xiàn),這也導(dǎo)致了運(yùn)行 Docker 容器如果沒有指定 volume(數(shù)據(jù)卷)或 bind mount,則 Docker 容器結(jié)束后,運(yùn)行時(shí)產(chǎn)生的數(shù)據(jù)便丟失了。
Docker 存儲(chǔ)驅(qū)動(dòng)除了 AUFS 外,還有 OverlayFS、Devicemapper、Btrfs、ZFS 等,本文不多討論。
總結(jié)
至此,我們知道了 Docker 核心功能的基本原理,Docker 利用 Linux Namespace 進(jìn)行網(wǎng)絡(luò)、用戶、進(jìn)程等不同資源的隔離,使用 Linux Cgroups 技術(shù)對(duì)資源的使用進(jìn)行限制與監(jiān)控,通過 AUFS 等存儲(chǔ)驅(qū)動(dòng)實(shí)現(xiàn)分層結(jié)構(gòu)與增量更新等功能。
現(xiàn)實(shí)世界中的 Docker 還使用了很多其他技術(shù),但最核心且最基本的就是 Linux Namespace、Linux Cgrpus 與 AUFS。
Docker 在當(dāng)前的開發(fā)流程中已成必備工具,容器帶來的優(yōu)勢(shì)解放了運(yùn)維人員也避免了開發(fā)人員遇到開發(fā)環(huán)境與線上環(huán)境不一致時(shí)導(dǎo)致問題的情況。目前容器編排技術(shù)(K8s)快速發(fā)展,Docker 容器技術(shù)在未來也將會(huì)進(jìn)一步發(fā)展,它值得我們花時(shí)間與精力去了解其本質(zhì)。
當(dāng)前文章:掌握這些Docker原理知識(shí),出去吹牛逼再也不擔(dān)心了
網(wǎng)頁路徑:http://muchs.cn/news12/203662.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供關(guān)鍵詞優(yōu)化、網(wǎng)站設(shè)計(jì)、定制開發(fā)、搜索引擎優(yōu)化、自適應(yīng)網(wǎng)站、品牌網(wǎng)站設(shè)計(jì)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容