Docker三大核心部件
- Docker Image (鏡像)
用來(lái)創(chuàng)建容器的模版严卖,類似于OOP的類,鏡像是只讀的布轿。 - Docker Container (容器)
容器是獨(dú)立運(yùn)行的一個(gè)或一組應(yīng)用哮笆,類似于OOP的對(duì)象;
完全使用沙箱機(jī)制驮捍,相互之間無(wú)任何接口疟呐,性能開銷低;
容器在啟動(dòng)的時(shí)候創(chuàng)建一層可寫層作為最上層东且。 - Docker Repository (倉(cāng)庫(kù))
倉(cāng)庫(kù)是集中存放鏡像文件的場(chǎng)所启具,類似于git,包含多個(gè)鏡像珊泳;分為公開倉(cāng)庫(kù)和私有倉(cāng)庫(kù)鲁冯,最大的公開倉(cāng)庫(kù)是Docker Hub拷沸,國(guó)內(nèi)倉(cāng)庫(kù)有Docker Pool等;
倉(cāng)庫(kù)注冊(cè)服務(wù)器存放多個(gè)倉(cāng)庫(kù)薯演,類似于GitHub這樣的托管服務(wù)器撞芍。
Docker整體架構(gòu)
- Docker使用C/S架構(gòu)模式,非常松耦合的架構(gòu)跨扮。
一般運(yùn)行流程為:用戶在Docker Client端通過(guò)命令行發(fā)送請(qǐng)求到Docker Daemon序无,Docker Daemon中的Server收到請(qǐng)求后,Engine會(huì)創(chuàng)建一個(gè)工作任務(wù)job衡创,通過(guò)調(diào)用Driver模塊的各個(gè)驅(qū)動(dòng)分別執(zhí)行不同的任務(wù)帝嗡,比如需要鏡像就調(diào)用graphdriver從鏡像倉(cāng)庫(kù)下載鏡像,創(chuàng)建容器時(shí)也需要調(diào)用其它兩個(gè)驅(qū)動(dòng)來(lái)配置網(wǎng)絡(luò)和創(chuàng)建并維護(hù)容器璃氢。最后生成運(yùn)行中的容器或者上傳鏡像到鏡像倉(cāng)庫(kù)等哟玷。
Docker整體設(shè)計(jì)
Docker 架構(gòu)內(nèi)模塊分解
-
Docker Client
用戶通過(guò)Docker Client與Docker Daemon進(jìn)行通信,利用命令行發(fā)送創(chuàng)建鏡像一也、運(yùn)行容器之類的請(qǐng)求巢寡,接收到返回后做簡(jiǎn)單處理,Client的一次生命周期就結(jié)束了椰苟。
Docker Client可以通過(guò)以下三種方式和Docker Daemon建立通信:tcp://host:port抑月,unix://path_to_socket和fd://socketfd。
Docker Daemon
Docker Daemon是Docker架構(gòu)中一個(gè)常駐在后臺(tái)的系統(tǒng)進(jìn)程尊剔,接受并處理Docker Client發(fā)送的請(qǐng)求爪幻。該守護(hù)進(jìn)程在后臺(tái)啟動(dòng)了一個(gè)Server,Server負(fù)責(zé)接受Docker Client發(fā)送的請(qǐng)求须误;然后通過(guò)路由與分發(fā)調(diào)度挨稿,找到相應(yīng)的Handler來(lái)執(zhí)行請(qǐng)求。
- Server
在Docker的啟動(dòng)過(guò)程中京痢,通過(guò)包gorilla/mux奶甘,創(chuàng)建了一個(gè)mux.Router,提供請(qǐng)求的路由功能祭椰。在Golang中臭家,gorilla/mux是一個(gè)強(qiáng)大的URL路由器以及調(diào)度分發(fā)器。該mux.Router中添加了眾多的路由項(xiàng)方淤,每一個(gè)路由項(xiàng)由HTTP請(qǐng)求方法(PUT钉赁、POST、GET或DELETE)携茂、URL你踩、Handler三部分組成。
若Docker Client通過(guò)HTTP的形式訪問(wèn)Docker Daemon,創(chuàng)建完mux.Router之后带膜,Docker將Server的監(jiān)聽地址以及mux.Router作為參數(shù)吩谦,創(chuàng)建一個(gè)httpSrv=http.Server{},最終執(zhí)行httpSrv.Serve()為請(qǐng)求服務(wù)膝藕。
在Server的服務(wù)過(guò)程中式廷,Server在listener上接受Docker Client的訪問(wèn)請(qǐng)求,并創(chuàng)建一個(gè)全新的goroutine來(lái)服務(wù)該請(qǐng)求芭挽。在goroutine中滑废,首先讀取請(qǐng)求內(nèi)容,然后做解析工作览绿,接著找到相應(yīng)的路由項(xiàng)策严,隨后調(diào)用相應(yīng)的Handler來(lái)處理該請(qǐng)求穗慕,最后Handler處理完請(qǐng)求之后回復(fù)該請(qǐng)求饿敲。
需要注意的是:Docker Server的運(yùn)行在Docker的啟動(dòng)過(guò)程中,是靠一個(gè)名為”serveapi”的job的運(yùn)行來(lái)完成的逛绵。原則上怀各,Docker Server的運(yùn)行是眾多job中的一個(gè),但是為了強(qiáng)調(diào)Docker Server的重要性以及為后續(xù)job服務(wù)的重要特性术浪,將該”serveapi”的job單獨(dú)抽離出來(lái)分析瓢对,理解為Docker Server。
- Engine
Engine是Docker架構(gòu)中的運(yùn)行引擎胰苏,同時(shí)也Docker運(yùn)行的核心模塊硕蛹。它扮演Docker container存儲(chǔ)倉(cāng)庫(kù)的角色,并且通過(guò)執(zhí)行job的方式來(lái)操縱管理這些容器硕并。
在Engine數(shù)據(jù)結(jié)構(gòu)的設(shè)計(jì)與實(shí)現(xiàn)過(guò)程中法焰,有一個(gè)handler對(duì)象。該handler對(duì)象存儲(chǔ)的都是關(guān)于眾多特定job的handler處理訪問(wèn)倔毙。舉例說(shuō)明埃仪,Engine的handler對(duì)象中有一項(xiàng)為:{“create”: daemon.ContainerCreate,},則說(shuō)明當(dāng)名為”create”的job在運(yùn)行時(shí)陕赃,執(zhí)行的是daemon.ContainerCreate的handler卵蛉。
- Job
一個(gè)Job可以認(rèn)為是Docker架構(gòu)中Engine內(nèi)部最基本的工作執(zhí)行單元。Docker可以做的每一項(xiàng)工作么库,都可以抽象為一個(gè)job傻丝。例如:在容器內(nèi)部運(yùn)行一個(gè)進(jìn)程,這是一個(gè)job诉儒;創(chuàng)建一個(gè)新的容器葡缰,這是一個(gè)job,從Internet上下載一個(gè)文檔,這是一個(gè)job运准;包括之前在Docker Server部分說(shuō)過(guò)的幌氮,創(chuàng)建Server服務(wù)于HTTP的API,這也是一個(gè)job胁澳,等等该互。
Docker Registry
存儲(chǔ)容器鏡像的倉(cāng)庫(kù)。
在Docker的運(yùn)行過(guò)程中韭畸,Docker Daemon會(huì)與Docker Registry通信宇智,并實(shí)現(xiàn)搜索鏡像、下載鏡像胰丁、上傳鏡像三個(gè)功能随橘,這三個(gè)功能對(duì)應(yīng)的job名稱分別為”search”,”pull” 與 “push”锦庸。-
Graph
一方面机蔗,Graph存儲(chǔ)著本地具有版本信息的文件系統(tǒng)鏡像,另一方面也通過(guò)GraphDB記錄著所有文件系統(tǒng)鏡像彼此之間的關(guān)系甘萧。
其中萝嘁,GraphDB是一個(gè)構(gòu)建在SQLite之上的小型圖數(shù)據(jù)庫(kù),實(shí)現(xiàn)了節(jié)點(diǎn)的命名以及節(jié)點(diǎn)之間關(guān)聯(lián)關(guān)系的記錄扬卷。 Driver
Driver是Docker架構(gòu)中的驅(qū)動(dòng)模塊牙言。通過(guò)Driver驅(qū)動(dòng),Docker可以實(shí)現(xiàn)對(duì)Docker容器執(zhí)行環(huán)境的定制怪得。包含管理容器鏡像的graphdriver驅(qū)動(dòng)咱枉,配置容器內(nèi)網(wǎng)絡(luò)環(huán)境的networkdriver驅(qū)動(dòng),execdriver用來(lái)創(chuàng)建和維護(hù)容器徒恋。
-
graphdriver
在graphdriver的初始化過(guò)程之前蚕断,有4種文件系統(tǒng)或類文件系統(tǒng)在其內(nèi)部注冊(cè),它們分別是aufs因谎、btrfs基括、vfs和devmapper。而Docker在初始化之時(shí)财岔,通過(guò)獲取系統(tǒng)環(huán)境變量”DOCKER_DRIVER”來(lái)提取所使用driver的指定類型风皿。而之后所有的graph操作,都使用該driver來(lái)執(zhí)行匠璧。
-
networkdriver
networkdriver的用途是完成Docker容器網(wǎng)絡(luò)環(huán)境的配置桐款,其中包括Docker啟動(dòng)時(shí)為Docker環(huán)境創(chuàng)建網(wǎng)橋;Docker容器創(chuàng)建時(shí)為其創(chuàng)建專屬虛擬網(wǎng)卡設(shè)備夷恍;以及為Docker容器分配IP魔眨、端口并與宿主機(jī)做端口映射,設(shè)置容器防火墻策略等。networkdriver的架構(gòu)如下圖遏暴。
-
execdriver
execdriver是執(zhí)行驅(qū)動(dòng)侄刽,負(fù)責(zé)容器內(nèi)部進(jìn)程的真正運(yùn)行。負(fù)責(zé)創(chuàng)建容器運(yùn)行命名空間朋凉,負(fù)責(zé)容器資源使用的統(tǒng)計(jì)與限制等州丹。默認(rèn)使用native驅(qū)動(dòng),不依賴于LXC杂彭,具體體現(xiàn)在Daemon啟動(dòng)過(guò)程中加載的ExecDriverflag參數(shù)墓毒。這可以認(rèn)為是Docker在1.2版本上一個(gè)很大的改變,或者說(shuō)Docker實(shí)現(xiàn)跨平臺(tái)的一個(gè)先兆亲怠。
-
libcontainer
libcontainer是Docker架構(gòu)中一個(gè)使用Go語(yǔ)言設(shè)計(jì)實(shí)現(xiàn)的庫(kù)所计,設(shè)計(jì)初衷是希望該庫(kù)可以不依靠任何依賴,直接訪問(wèn)內(nèi)核中與容器相關(guān)的API团秽。
正是由于libcontainer的存在主胧,Docker可以直接調(diào)用libcontainer,而最終操縱容器的namespace徙垫、cgroups讥裤、apparmor、網(wǎng)絡(luò)設(shè)備以及防火墻規(guī)則等姻报。這一系列操作的完成都不需要依賴LXC或者其他包。
由于libcontainer使用Go這種跨平臺(tái)的語(yǔ)言開發(fā)實(shí)現(xiàn)间螟,且本身又可以被上層多種不同的編程語(yǔ)言訪問(wèn)吴旋,因此很難說(shuō),未來(lái)的Docker就一定會(huì)緊緊地和Linux捆綁在一起厢破。 -
Docker Container
運(yùn)行應(yīng)用程序的特定容器荣瑟,是容器服務(wù)的交付實(shí)體。
參考
https://blog.csdn.net/yanhongbin1993/article/details/81436849
https://www.cnblogs.com/zuxing/articles/8717415.html
https://www.runoob.com/docker/docker-architecture.html