基于Kubernetes的容器云平臺(tái)實(shí)戰(zhàn)》——1.4.2 Docker原理

      網(wǎng)友投稿 664 2025-03-31

      1.4.2 Docker原理


      Docker是基于操作系統(tǒng)虛擬化技術(shù)實(shí)現(xiàn)的,這一點(diǎn)與基于硬件虛擬化的各種虛擬機(jī)產(chǎn)品有很大不同,但是兩者所要解決的問(wèn)題在很多方面卻有相似之處,比如,都希望為應(yīng)用提供一個(gè)虛擬、完整和獨(dú)占的運(yùn)行環(huán)境,都希望能夠提高這些虛擬環(huán)境之間的隔離度,也都希望能夠從管理的角度對(duì)這些虛擬環(huán)境占用的宿主機(jī)資源進(jìn)行方便的管控。在解釋為何使用Docker的時(shí)候已經(jīng)提到,Docker解決這些問(wèn)題的途徑是在共享宿主機(jī)內(nèi)核的基礎(chǔ)上包裝內(nèi)核提供的一系列API。具體到Linux操作系統(tǒng)上,內(nèi)核所提供的相關(guān)API涉及很多方面,其中被大家關(guān)注得最多也是最主要的是CGroup和namespace。另外,在實(shí)現(xiàn)分層鏡像和容器的根文件系統(tǒng)視圖時(shí),Docker使用了與虛擬文件系統(tǒng)相關(guān)的掛載和綁定掛載API,這些都不是新內(nèi)容,只是Docker這類容器化產(chǎn)品將它們進(jìn)行包裝并推動(dòng)了操作系統(tǒng)已有虛擬化能力的大眾化而已。

      下面就對(duì)這幾個(gè)Docker中應(yīng)用到的主要技術(shù)分別進(jìn)行簡(jiǎn)單的介紹。

      CGroup是Control Group的縮寫,它是Linux中的特有功能,首先由Google公司提交的內(nèi)核補(bǔ)丁實(shí)現(xiàn)。顧名思義,這個(gè)功能與控制、分組有關(guān)。其實(shí),如果單從功能角度來(lái)看的話,也許叫做Group Control更好一些。這主要是因?yàn)樵摴δ艿暮诵脑谟趯?duì)進(jìn)程進(jìn)行層次化分組,并能夠以每個(gè)組的粒度實(shí)現(xiàn)諸如資源限制和策略控制功能,而這正是前面提到的虛擬化目標(biāo)的基礎(chǔ)。每一個(gè)虛擬環(huán)境(或者稱之為“容器”)中的應(yīng)用進(jìn)程,以及后續(xù)加入該環(huán)境中的其他進(jìn)程都應(yīng)該受到同樣的策略管控,這是很容易理解的;但是在沒有這個(gè)基礎(chǔ)設(shè)施之前,單從已有的操作系統(tǒng)功能上看是無(wú)法實(shí)現(xiàn)的。而有了這種分層的分組功能之后,不僅是容器運(yùn)行時(shí),包括系統(tǒng)管理員,也可以方便地實(shí)現(xiàn)對(duì)容器中進(jìn)程占用的CPU、內(nèi)存等資源的限制。而這種控制功能,在CGroup中是由很多控制器來(lái)完成的,主要的控制器包括blkio、cpu、cpuacct、cpuset、devices、freezer、hugetlb、memory、net_cls、net_prio和perf_event等。

      這些控制器和不同的進(jìn)程組之間的關(guān)系在第一個(gè)版本的CGroup實(shí)現(xiàn)中是很靈活的。每個(gè)控制器可以對(duì)應(yīng)到單獨(dú)的一個(gè)組,以及由該組的子組所構(gòu)成的所謂“層次結(jié)構(gòu)”。這也是目前Docker所支持的實(shí)現(xiàn)方式。但是這種實(shí)現(xiàn)被認(rèn)為過(guò)于復(fù)雜,帶來(lái)了很多技術(shù)上的障礙,因此在第二個(gè)版本的實(shí)現(xiàn)中將這種“層次結(jié)構(gòu)”限定為只有一個(gè)。但是版本二的CGroup功能直到在4.15版本內(nèi)核中才完整實(shí)現(xiàn),目前可能還不成熟。

      不管是哪一個(gè)版本的CGroup實(shí)現(xiàn),對(duì)進(jìn)程分組的控制都是通過(guò)一個(gè)虛擬文件系統(tǒng)下的目錄節(jié)點(diǎn)和其中的節(jié)點(diǎn)文件來(lái)實(shí)現(xiàn)的,而各種控制器功能也是通過(guò)一些節(jié)點(diǎn)文件來(lái)實(shí)現(xiàn)。整個(gè)CGroup功能模塊的對(duì)外接口就是通過(guò)這個(gè)虛擬文件系統(tǒng)來(lái)暴露。在使用了systemd作為init的Linux系統(tǒng)上,這個(gè)CGroup虛擬文件系統(tǒng)的掛接點(diǎn)路徑為/sys/fs/cgroup。在下面的目錄列表中,cpu和cpuacct是指向“cpu,cpuacct”的符號(hào)鏈接,systemd目錄節(jié)點(diǎn)是systemd自己創(chuàng)建的一個(gè)“層次結(jié)構(gòu)”,與任何控制器無(wú)關(guān),只利用到CGroup核心的進(jìn)程分組管理功能。其他目錄節(jié)點(diǎn)和其下的子節(jié)點(diǎn)基本上每個(gè)都對(duì)應(yīng)著一種控制器。下面是systemd管理下默認(rèn)的CGroup層次結(jié)構(gòu)的根列表。

      # ls -p /sys/fs/cgroup

      blkio/? cpu? cpuacct? cpu,cpuacct/? cpuset/? devices/? freezer/? hugetlb/? memory/? net_cls/? perf_event/? systemd/

      默認(rèn)情況下,Docker在這每個(gè)層次結(jié)構(gòu)目錄下都創(chuàng)建了自己的節(jié)點(diǎn)子目錄,然后再為每個(gè)容器創(chuàng)建以容器ID為名稱的節(jié)點(diǎn)目錄,將所有容器相關(guān)的進(jìn)程都管理在這個(gè)“層次結(jié)構(gòu)”中。比如devices控制器是用來(lái)限定進(jìn)程組對(duì)設(shè)備文件的訪問(wèn)權(quán)限的,它對(duì)應(yīng)的層次結(jié)構(gòu)的頂層節(jié)點(diǎn)文件列表如下:

      # ls -p /sys/fs/cgroup/devices

      cgroup.clone_children? cgroup.procs? devices.allow? devices.list? devices.deny release_agent? notify_on_release? cgroup.event_control? cgroup.sane_behavior? tasks docker/? system.slice/? user.slice/

      《基于Kubernetes的容器云平臺(tái)實(shí)戰(zhàn)》——1.4.2 Docker原理

      其中與device控制器相關(guān)的節(jié)點(diǎn)文件以“devices.”開頭,如devices.allow和devices.deny,按照一定格式寫入設(shè)備號(hào)和權(quán)限控制串就能夠?qū)崿F(xiàn)設(shè)備訪問(wèn)控制,Docker中是以白名單方式來(lái)完成控制的。其他幾個(gè)文件和CGroup的進(jìn)程組管理功能有關(guān):tasks,可以向其寫入線程ID,將此線程納入該層次結(jié)構(gòu)內(nèi);cgroup.procs,可以向其寫入線程組ID,將線程組納入層次結(jié)構(gòu)內(nèi);notify_on_release,是控制當(dāng)前組銷毀時(shí)是否調(diào)用release_agent中登記的程序的開關(guān);release_agent,用于登記觸發(fā)程序,但是只有頂層才有此文件;cgroup.event_control,用于通過(guò)eventfd系統(tǒng)調(diào)用在用戶程序中得到控制器的事件通知;cgroup.clone_children,只用于cpuset控制器,控制子組是否在創(chuàng)建時(shí)復(fù)制父控制器的配置;cgroup.sane_behavior是一個(gè)過(guò)渡性文件,與是否啟用第二版CGroup功能有關(guān)。只要一個(gè)進(jìn)程被納入某個(gè)控制組,那么在后續(xù)的fork調(diào)用時(shí),新創(chuàng)建的進(jìn)程仍然在此控制組中,這樣就從進(jìn)程的角度確立了容器的邊界。

      Docker在每個(gè)層次結(jié)構(gòu)中都創(chuàng)建了自己的節(jié)點(diǎn)目錄,該節(jié)點(diǎn)目錄下也有與頂層類似的節(jié)點(diǎn)文件,而每個(gè)容器在默認(rèn)情況下都有自己的子節(jié)點(diǎn)目錄,其下同樣有該層次的對(duì)應(yīng)節(jié)點(diǎn)文件。頂層中除了docker節(jié)點(diǎn)目錄外的另外兩個(gè)節(jié)點(diǎn)目錄是由systemd創(chuàng)建的,用于管理宿主機(jī)上的服務(wù)和用戶會(huì)話。

      # ls -p /sys/fs/cgroup/devices/docker

      b61e023569ba3a0.../? tasks cgroup.procs notify_on_release cgroup.event_control? devices.allow? devices.list? cgroup.clone_children? devices.deny

      其他控制器與devices控制器一樣,也有自己的節(jié)點(diǎn)文件,限于篇幅,這里不再一一羅列,只簡(jiǎn)單說(shuō)明一下前面第一個(gè)列表中顯示出的各個(gè)控制器的主要功能:cpu,用于限制組中進(jìn)程的CPU使用量;cpuacct,用于對(duì)組中進(jìn)程的CPU使用進(jìn)行計(jì)量;cpuset,用于限定組中進(jìn)程可用的CPU和NUMA類型內(nèi)存節(jié)點(diǎn);memory,用于限定和報(bào)告組中進(jìn)程的內(nèi)存使用量;blkio,用于限制組中進(jìn)程對(duì)塊設(shè)備的I/O操作;freezer,用于掛起或者解凍組和子組中所有進(jìn)程;net_cls,用于設(shè)置組中進(jìn)程發(fā)送的網(wǎng)絡(luò)數(shù)據(jù)包的類別ID;net_prio,用于設(shè)置與該組相關(guān)網(wǎng)絡(luò)數(shù)據(jù)包的優(yōu)先級(jí);perf_event,用于控制是否對(duì)組中進(jìn)程執(zhí)行perf監(jiān)控;hugetlb,用于限制和報(bào)告組中進(jìn)程對(duì)大頁(yè)面的使用量。

      從上面的介紹中可以看出,CGroup功能劃定了容器的進(jìn)程組邊界,并且也能夠執(zhí)行一定資源限制功能,但是組中的進(jìn)程仍然可以看到與宿主機(jī)上進(jìn)程相同的東西,也就是這些組之間還沒有相互“隔離”。能夠支持“隔離”功能的是內(nèi)核中的命名空間(namespace)特性。

      已經(jīng)被Docker所利用的Linux內(nèi)核的命名空間特性包括:

      1)PID namespace:每當(dāng)在此命名空間中啟動(dòng)一個(gè)程序,內(nèi)核就為其分配一個(gè)唯一的ID,它與從宿主機(jī)中所見的不同。每個(gè)容器中的進(jìn)程都有自己?jiǎn)为?dú)的進(jìn)程ID空間。

      2)MNT namespace:每個(gè)容器都有自己的目錄掛載路徑的命名空間。

      3)NET namespace:每個(gè)容器都有自己?jiǎn)为?dú)的網(wǎng)絡(luò)棧,其中的socket和網(wǎng)卡設(shè)備都是其他容器不能訪問(wèn)的。

      4)UTS namespace:在此命名空間中的進(jìn)程擁有自己的主機(jī)名和NIS域名。

      5)IPC namespace:只有在相同的IPC命名空間中的進(jìn)程才可以利用共享內(nèi)存、信號(hào)量和消息隊(duì)列相互通信。

      6)User namespace:用戶命名空間被內(nèi)核用于隔離容器中用戶ID、組ID以及根目錄、key和capabilities,用戶還能通過(guò)配置來(lái)映射宿主機(jī)和容器中的用戶ID和組ID。

      與CGroup的實(shí)現(xiàn)不同,該特性的實(shí)現(xiàn)不是通過(guò)虛擬文件系統(tǒng)接口,而是通過(guò)實(shí)際的系統(tǒng)調(diào)用完成的。與此特性相關(guān)的系統(tǒng)調(diào)用有三個(gè):clone(fork函數(shù)實(shí)際是通過(guò)該系統(tǒng)調(diào)用實(shí)現(xiàn)的),在創(chuàng)建進(jìn)程的同時(shí)根據(jù)參數(shù)中的標(biāo)記為其新建命名空間,而沒有新建標(biāo)記時(shí),子進(jìn)程自動(dòng)繼承父進(jìn)程的命名空間,這樣由命名空間構(gòu)建的沙箱邊界在應(yīng)用中得到保持;setns,用于加入一個(gè)已經(jīng)存在的命名空間;unshare,根據(jù)參數(shù)標(biāo)記為調(diào)用進(jìn)程新建命名空間,并將調(diào)用進(jìn)程加入此空間中。由這些系統(tǒng)調(diào)用創(chuàng)建出的命名空間構(gòu)成樹形結(jié)構(gòu),宿主機(jī)初始命名空間是根,新建的MNT和UTS命名空間復(fù)制了父命名空間的內(nèi)容。對(duì)于setns調(diào)用來(lái)說(shuō),無(wú)疑需要一個(gè)已經(jīng)存在的命名空間的標(biāo)識(shí),而這是通過(guò)打開/proc//ns/目錄下的符號(hào)鏈接文件來(lái)得到的。每個(gè)內(nèi)核支持的命名空間在此目錄下有對(duì)應(yīng)的文件,文件名是確定的,如mnt、net、pid等。在Docker中不同容器共享某個(gè)命名空間正是通過(guò)打開這種文件來(lái)實(shí)現(xiàn)的。

      這些調(diào)用都是與進(jìn)程相關(guān)的,那么命名空間的生命周期是否完全與創(chuàng)建它的進(jìn)程綁定呢?其實(shí)只要將/proc//ns/目錄下的符號(hào)鏈接文件綁定掛載到另一個(gè)目錄下,那么即便該命名空間中的所有進(jìn)程都已經(jīng)銷毀,該命名空間還將繼續(xù)存在。Docker中創(chuàng)建的網(wǎng)絡(luò)命名空間也使用到這個(gè)特性。

      上面提到的各種命名空間引入內(nèi)核的時(shí)間并不相同,其中User namespace不僅引入最遲,并且直到4.15版本內(nèi)核還在進(jìn)行較大功能改進(jìn)。該特性與安全控制相關(guān),不僅語(yǔ)義復(fù)雜,而且還需借助一些特殊機(jī)制來(lái)減少漏洞,如User ID和Group ID映射。在創(chuàng)建用戶命名空間時(shí)可以對(duì)/proc//目錄下uid_map和gid_map文件執(zhí)行一次寫操作,寫入內(nèi)容是新命名空間中用戶或者組ID在父命名空間中的映射ID,以起始ID、起始映射ID加ID段長(zhǎng)度的格式寫入,4.15版本內(nèi)核之前只能寫入5行,4.15版本內(nèi)核開始支持340行。這個(gè)寫操作只能執(zhí)行一次。沒有被這些映射規(guī)則覆蓋的UID和GID自動(dòng)參考/proc/sys/kernel/下overflowuid和overflowgid中的值。當(dāng)創(chuàng)建文件時(shí)以映射后的用戶和組ID來(lái)執(zhí)行權(quán)限檢查。

      新建的網(wǎng)絡(luò)命名空間中除了loopback設(shè)備之外沒有任何網(wǎng)卡設(shè)備、路由表等資源,需要專門為其進(jìn)行配置。一個(gè)網(wǎng)卡設(shè)備只能歸屬于一個(gè)網(wǎng)絡(luò)命名空間,但是像veth這種虛擬網(wǎng)絡(luò)設(shè)備則可以提供類似于管道的功能,以溝通不同的網(wǎng)絡(luò)命名空間。

      雖然新建的MNT命名空間自動(dòng)復(fù)制了父命名空間的全部?jī)?nèi)容,但是在容器創(chuàng)建過(guò)程中,容器運(yùn)行時(shí)首先根據(jù)鏡像和配置參數(shù)為容器準(zhǔn)備好一個(gè)根文件系統(tǒng)的目錄樹,然后執(zhí)行pivot_root系統(tǒng)調(diào)用將新命名空間中的根文件系統(tǒng)切換到這個(gè)目錄樹上,再執(zhí)行umount調(diào)用卸載原有內(nèi)容,最終為容器環(huán)境準(zhǔn)備好一個(gè)隔離的文件系統(tǒng)視圖。

      接下來(lái)需要特別提到的是,Docker容器鏡像的構(gòu)建基于一系列的鏡像層,這些鏡像本身是只讀的,在容器運(yùn)行時(shí)根據(jù)鏡像創(chuàng)建容器時(shí)才為每個(gè)容器提供相互獨(dú)立的讀寫層。Docker引擎提供的容器鏡像構(gòu)建工具還可以將某個(gè)鏡像作為基礎(chǔ)鏡像來(lái)創(chuàng)建新鏡像,當(dāng)然這是分層技術(shù)的一個(gè)合理擴(kuò)展。從讀取的角度看,虛擬文件系統(tǒng)將多層鏡像中的目錄結(jié)構(gòu)匯聚起來(lái)向用戶提供單一的視圖,并且上層文件覆蓋下層;而從寫入角度看,實(shí)現(xiàn)這種鏡像分層的關(guān)鍵在于COW(Copy On Write)技術(shù),簡(jiǎn)單地說(shuō),就是虛擬文件系統(tǒng)在用戶更改某個(gè)文件時(shí),才將原本共享的只讀內(nèi)容復(fù)制到讀寫層,供用戶操作。這種通過(guò)堆棧式的只讀鏡像層來(lái)創(chuàng)建容器的方式帶來(lái)的明顯好處就是,在存儲(chǔ)和傳輸鏡像的時(shí)候,許多已經(jīng)被緩存的共享鏡像層就可以通過(guò)引用的形式來(lái)標(biāo)注,無(wú)需再占用存儲(chǔ)空間和網(wǎng)絡(luò)帶寬了。這種對(duì)資源的有效利用可以幫助Docker引擎更快地下載鏡像,也能夠幫助管理員在同一臺(tái)設(shè)備上規(guī)劃更多的應(yīng)用容器。

      對(duì)于容器的運(yùn)行來(lái)說(shuō),有時(shí)僅僅提供隔離性是不夠的。比如上面已經(jīng)提到的CGroup技術(shù),對(duì)它的管理是在宿主機(jī)上的/sys/fs/cgroup路徑下某些節(jié)點(diǎn)中進(jìn)行的,但是新建了MNT命名空間之后,這些節(jié)點(diǎn)路徑和容器文件系統(tǒng)視圖中的節(jié)點(diǎn)如何關(guān)聯(lián)呢?這就不能不提到Linux下mount系統(tǒng)調(diào)用中的綁定掛載功能。

      在Linux下可以采用綁定掛載的方式將一個(gè)文件或者目錄綁定到某個(gè)掛載點(diǎn)上,使得在那個(gè)掛載點(diǎn)上可以看到這個(gè)文件或者目錄的內(nèi)容。并且這種綁定處理的效果可以跨越文件系統(tǒng)和命名空間的邊界。顯然,容器運(yùn)行時(shí)正是利用了這個(gè)技術(shù)將容器內(nèi)外環(huán)境拼接起來(lái)。另外,這種綁定掛載功能設(shè)計(jì)中支持單向和雙向的共享設(shè)定,還能夠進(jìn)行遞歸性質(zhì)和多級(jí)模式的設(shè)定,這些設(shè)定被稱為傳播模式。目前的容器運(yùn)行時(shí)接口上已經(jīng)能夠完整支持這些參數(shù)設(shè)定。

      在Docker中得到運(yùn)用的不僅包括上述這些技術(shù),還集成了Capabilities設(shè)置、Seccomp、SELinux/AppArmor等其他與安全控制相關(guān)的技術(shù),它們都是操作系統(tǒng)通過(guò)一系列分離的API實(shí)現(xiàn)的,它們被Docker引擎通過(guò)標(biāo)準(zhǔn)化的配置和對(duì)外管理接口集成起來(lái),為用戶提供了一整套方便使用、持續(xù)演進(jìn)的容器化應(yīng)用構(gòu)建、發(fā)布和運(yùn)行工具。

      Docker 任務(wù)調(diào)度 容器 Kubernetes

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請(qǐng)聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請(qǐng)聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。

      上一篇:如何顯示變大小(電腦顯示變大怎么調(diào)小)
      下一篇:WPS怎么設(shè)計(jì)文檔封面?
      相關(guān)文章
      婷婷亚洲综合五月天小说在线| 亚洲性天天干天天摸| 亚洲视频手机在线| 亚洲AV无码成人专区片在线观看| 国产成人综合亚洲AV第一页| 亚洲精品97久久中文字幕无码| 亚洲精品无码少妇30P| 亚洲综合国产成人丁香五月激情| 亚洲手机中文字幕| 亚洲国语在线视频手机在线| 亚洲精品在线视频观看| 国产精品亚洲五月天高清| 亚洲国产中文字幕在线观看| 亚洲精品蜜夜内射| 亚洲第一综合天堂另类专| 亚洲AV成人精品一区二区三区| 亚洲中文字幕AV每天更新| 亚洲人成电影网站色www| 亚洲中文字幕一二三四区| 亚洲人成自拍网站在线观看| 亚洲国产成人AV在线播放| 色婷婷亚洲一区二区三区| 亚洲精品理论电影在线观看| 99亚洲乱人伦aⅴ精品| 婷婷综合缴情亚洲狠狠尤物| 国产精品自拍亚洲| 亚洲av手机在线观看| 国产国拍亚洲精品福利| 亚洲精品无码久久一线| 亚洲人成网亚洲欧洲无码久久| 国产aⅴ无码专区亚洲av| 亚洲国产国产综合一区首页| 亚洲综合色丁香麻豆| 亚洲AV无码精品蜜桃| 亚洲伊人久久大香线蕉AV| 国产亚洲人成在线播放| 久久久久亚洲AV成人网人人软件| 亚洲日本va在线视频观看| 蜜芽亚洲av无码精品色午夜| 亚洲伊人久久大香线焦| 亚洲国产高清国产拍精品|