一、什么是Docker?
??提到容器化技術(shù),就必須提到docker,下面從歷史來(lái)源、功能作用、技術(shù)本質(zhì)幾方面談?wù)勈裁词荄ocker。
1、歷史來(lái)源
??Docker最初是dotCloud公司創(chuàng)始人Solomon Hykes在法國(guó)期間發(fā)起的一個(gè)公司內(nèi)部項(xiàng)目,它是基于dotCloud公司多年云服務(wù)技術(shù)的一次革新,并于2013年3月以Apache 2.0授權(quán)協(xié)議開(kāi)源,后來(lái)加入Linux基金會(huì),并推動(dòng)成立開(kāi)放容器聯(lián)盟(OCI)。
2、功能作用
??Docker中文網(wǎng)是這樣介紹Docker:“Docker是一個(gè)開(kāi)源的引擎,可以輕松地為任何應(yīng)用創(chuàng)建一個(gè)輕量級(jí)、可移植、自給自足的容器。開(kāi)發(fā)者在筆記本上編譯測(cè)試通過(guò)的容器可以批量地在生產(chǎn)環(huán)境中部署,包括VMs(虛擬機(jī))、bare metal、OpenStack集群和其他的基礎(chǔ)應(yīng)用平臺(tái)?!?/p>
??Docker通常用于如下場(chǎng)景:
- web應(yīng)用的自動(dòng)化打包和發(fā)布;
- 自動(dòng)化測(cè)試和持續(xù)集成、發(fā)布;
- 在服務(wù)型環(huán)境中部署和調(diào)整數(shù)據(jù)庫(kù)或其他的后臺(tái)應(yīng)用;
- 從頭編譯或者擴(kuò)展現(xiàn)有的OpenShift或Cloud Foundry平臺(tái)來(lái)搭建自己的PaaS環(huán)境
3、技術(shù)本質(zhì)
??Docker的前身是LXC(Linux Container),使用Go語(yǔ)言開(kāi)發(fā)實(shí)現(xiàn),基于Linux內(nèi)核的cgroup、namespace,以及AUFS累的Union FS等技術(shù),對(duì)進(jìn)程進(jìn)行封裝隔離,屬于操作系統(tǒng)層面的虛擬化技術(shù)。由于提供了輕量級(jí)的虛擬化,隔離了進(jìn)程和資源,而且不需要提供指令解釋機(jī)制以及全虛擬化的其他復(fù)雜性,因此被稱為容器。容器能有效地將由單個(gè)操作系統(tǒng)管理的資源劃分到孤立的組中,以更好地在孤立的組之間平衡有沖突的資源使用需求。
??Docker在容器的基礎(chǔ)上,進(jìn)行了進(jìn)一步的封裝,從文件系統(tǒng)、網(wǎng)絡(luò)互聯(lián)到進(jìn)程隔離等等,極大簡(jiǎn)化了容器的創(chuàng)建和維護(hù),使得Docker技術(shù)比傳統(tǒng)的虛擬機(jī)技術(shù)更為輕便、快捷。
??Docker 的容器利用了 LXC,管理利用了 namespaces 來(lái)做權(quán)限的控制和隔離,cgroups 來(lái)進(jìn)行資源的配置,并且還通過(guò) aufs 來(lái)進(jìn)一步提高文件系統(tǒng)的資源利用率,而這些技術(shù)都不是 Docker 獨(dú)創(chuàng)。
二、Docker和傳統(tǒng)虛擬機(jī)的對(duì)比
??容器與虛擬機(jī)有著類似的資源隔離和分配的優(yōu)點(diǎn),但不同的架構(gòu)方法使容器能夠更加便攜,高效等。
1、傳統(tǒng)虛擬機(jī)架構(gòu)
??使用虛擬機(jī)運(yùn)行多個(gè)互相隔離的應(yīng)用時(shí),如下圖:

??從下到上理解上圖:
基礎(chǔ)設(shè)施(Infrastructure):它可以是你得個(gè)人電腦、數(shù)據(jù)中心的服務(wù)器,或者是云主機(jī)。
主操作系統(tǒng)(Host Operating System):你的個(gè)人電腦智商,運(yùn)行的可能是Linux、Windows、MacOS。
虛擬機(jī)管理系統(tǒng)(Hypervisor):利用Hypervisor,可以在主操作系統(tǒng)智商運(yùn)行多個(gè)不同的從操作系統(tǒng),實(shí)現(xiàn)硬件資源虛擬化,常用的軟件有Virtual Box、VMware Workstation等。
從操作系統(tǒng)(Guest Operating System):假如需要運(yùn)行3個(gè)互相隔離的應(yīng)用,則需要使用Hypervisor啟動(dòng)3個(gè)從操作系統(tǒng),也就是3個(gè)虛擬機(jī)。通常虛擬機(jī)都非常大,小的有幾百M(fèi),大的有幾個(gè)G,同時(shí)運(yùn)行多個(gè)虛擬機(jī),可能會(huì)將你的主機(jī)的CPU和內(nèi)存資源全部耗盡。
各種依賴:每一個(gè)從操作系統(tǒng)都需要安裝許多依賴。如果你的應(yīng)用需要連接PostgreSQL的haunt,則需要安裝libpq-dev;如果使用Ruby的話,應(yīng)該需要安裝gems;如果使用其他編程語(yǔ)言,比如Python或者Node.js,都會(huì)需要安裝對(duì)應(yīng)的依賴庫(kù)。
應(yīng)用:安裝依賴之后,就可以在各個(gè)從操作系統(tǒng)分別運(yùn)行應(yīng)用了,這樣各個(gè)應(yīng)用就是互相隔離的。
??每個(gè)虛擬機(jī)都包括應(yīng)用程序、必要的二進(jìn)制文件和庫(kù)以及一個(gè)完整的客戶操作系統(tǒng)(Guest OS),盡管它們被分離,它們共享并利用主機(jī)的硬件資源,將近需要十幾個(gè) GB 的大小。
2、Docker架構(gòu)
??使用Docker容器運(yùn)行多個(gè)互相隔離的應(yīng)用時(shí),如下圖:

主操作系統(tǒng)(Host Operating System):所有主流的Linux發(fā)行版都可以運(yùn)行Docker。對(duì)于MacOS和Windows,也有一些辦法"運(yùn)行"Docker。
Docker守護(hù)進(jìn)程(Docker Daemon):Docker守護(hù)進(jìn)程取代了Hypervisor,運(yùn)行在docker容器上的程序直接使用的都是實(shí)際物理機(jī)的硬件資源。因此在CPU、內(nèi)存利用率上docker將會(huì)在效率上有明顯優(yōu)勢(shì)。它是運(yùn)行在操作系統(tǒng)之上的后臺(tái)進(jìn)程,負(fù)責(zé)管理Docker容器。
各種依賴:對(duì)于Docker,應(yīng)用的所有依賴都打包在Docker鏡像中,Docker容器是基于Docker鏡像創(chuàng)建的。
應(yīng)用:應(yīng)用的源代碼與它的依賴都打包在Docker鏡像中,不同的應(yīng)用需要不同的Docker鏡像。不同的應(yīng)用運(yùn)行在不同的Docker容器中,它們是相互隔離的。
docker比虛擬機(jī)快的原因:
??docker利用的是宿主機(jī)的內(nèi)核,而不需要Guest OS。因此,單新建一個(gè)容器時(shí),docker不需要和虛擬機(jī)一樣重新加載一個(gè)操作系統(tǒng)內(nèi)核。仍而避免引尋、加載操作系統(tǒng)內(nèi)核,這是個(gè)比較費(fèi)時(shí)費(fèi)資源的過(guò)程,當(dāng)新建一個(gè)虛擬機(jī)時(shí),虛擬機(jī)軟件需要加載Guest OS,這個(gè)新建過(guò)程是分鐘級(jí)別的。而docker由于直接利用宿主機(jī)的操作系統(tǒng),則忽略了這個(gè)過(guò)程,因此新建一個(gè)docker容器只需要幾秒鐘。
3、對(duì)比
??Docker守護(hù)進(jìn)程可以直接與主操作系統(tǒng)進(jìn)行通信,為各個(gè)Docker容器分配資源;它還可以將容器與主操作系統(tǒng)隔離,并將各個(gè)容器互相隔離。虛擬機(jī)啟動(dòng)需要數(shù)分鐘,而Docker容器可以在數(shù)毫秒內(nèi)啟動(dòng)。由于沒(méi)有臃腫的從操作系統(tǒng),Docker可以節(jié)省大量的磁盤空間以及其他系統(tǒng)資源。
| 特性 | 容器 | 虛擬機(jī) |
|---|---|---|
| 啟動(dòng) | 秒級(jí) | 分鐘級(jí) |
| 硬盤使用 | 一般MB | 一般GB |
| 性能 | 接近原生 | 弱于 |
| 系統(tǒng)支持量 | 單機(jī)支持上千個(gè)容器 | 一般幾十個(gè) |
??但是技術(shù)沒(méi)有好壞,只有使用的場(chǎng)景合不合適,虛擬機(jī)更擅長(zhǎng)與徹底隔離整個(gè)運(yùn)行環(huán)境。例如:云服務(wù)商通常采用虛擬機(jī)技術(shù)隔離不同的用戶;Docker通常用于隔離不同的應(yīng)用,例如前端、后端以及數(shù)據(jù)庫(kù)。

三、docker的優(yōu)勢(shì)
更高效地利用系統(tǒng)資源
不需要運(yùn)行完整操作系統(tǒng),按需使用,最大程度節(jié)省資源。更快速的啟動(dòng)時(shí)間
傳統(tǒng)的虛擬機(jī)技術(shù)啟動(dòng)應(yīng)用服務(wù)往往需要數(shù)分鐘,而 Docker 容器應(yīng)用,由于直接運(yùn)行于宿主內(nèi)核,無(wú)需啟動(dòng)完整的操作系統(tǒng),因此可以做到秒級(jí)、甚至毫秒級(jí)的啟動(dòng)時(shí)間。大大的節(jié)約了開(kāi)發(fā)、測(cè)試、部署的時(shí)間。一致的運(yùn)行環(huán)境
開(kāi)發(fā)過(guò)程中一個(gè)常見(jiàn)的問(wèn)題是環(huán)境一致性問(wèn)題。由于開(kāi)發(fā)環(huán)境、測(cè)試環(huán)境、生產(chǎn)環(huán)境不一致,導(dǎo)致有些 bug 并未在開(kāi)發(fā)過(guò)程中被發(fā)現(xiàn)。而 Docker 的鏡像提供了除內(nèi)核外完整的運(yùn)行時(shí)環(huán)境,確保了應(yīng)用運(yùn)行環(huán)境一致性,從而不會(huì)再出現(xiàn) 「這段代碼在我機(jī)器上沒(méi)問(wèn)題啊」 這類問(wèn)題。持續(xù)交付和部署
對(duì)開(kāi)發(fā)和運(yùn)維(DevOps)人員來(lái)說(shuō),最希望的就是一次創(chuàng)建或配置,可以在任意地方正常運(yùn)行。
?使用 Docker 可以通過(guò)定制應(yīng)用鏡像來(lái)實(shí)現(xiàn)持續(xù)集成、持續(xù)交付、部署。開(kāi)發(fā)人員可以通過(guò)Dockerfile 來(lái)進(jìn)行鏡像構(gòu)建,并結(jié)合 持續(xù)集成(Continuous Integration) 系統(tǒng)進(jìn)行集成測(cè)試,而運(yùn)維人員則可以直接在生產(chǎn)環(huán)境中快速部署該鏡像,甚至結(jié)合 持續(xù)部署(ContinuousDelivery/Deployment) 系統(tǒng)進(jìn)行自動(dòng)部署。
?而且使用 Dockerfile 使鏡像構(gòu)建透明化,不僅僅開(kāi)發(fā)團(tuán)隊(duì)可以理解應(yīng)用運(yùn)行環(huán)境,也方便運(yùn)維團(tuán)隊(duì)理解應(yīng)用運(yùn)行所需條件,幫助更好的生產(chǎn)環(huán)境中部署該鏡像。
更輕松的轉(zhuǎn)移
由于 Docker 確保了執(zhí)行環(huán)境的一致性,使得應(yīng)用的遷移更加容易。Docker 可以在很多平臺(tái)上運(yùn)行,無(wú)論是物理機(jī)、虛擬機(jī)、公有云、私有云,甚至是筆記本,其運(yùn)行結(jié)果是一致的。因此用戶可以很輕易的將在一個(gè)平臺(tái)上運(yùn)行的應(yīng)用,遷移到另一個(gè)平臺(tái)上,而不用擔(dān)心運(yùn)行環(huán)境的變化導(dǎo)致應(yīng)用無(wú)法正常運(yùn)行的情況。更輕松的維護(hù)和擴(kuò)展
Docker 使用的分層存儲(chǔ)以及鏡像的技術(shù),使得應(yīng)用重復(fù)部分的復(fù)用更為容易,也使得應(yīng)用的維護(hù)更新更加簡(jiǎn)單,基于基礎(chǔ)鏡像進(jìn)一步擴(kuò)展鏡像也變得非常簡(jiǎn)單。此外,Docker 團(tuán)隊(duì)同各個(gè)開(kāi)源項(xiàng)目團(tuán)隊(duì)一起維護(hù)了一大批高質(zhì)量的 官方鏡像,既可以直接在生產(chǎn)環(huán)境使用,又可以作為基礎(chǔ)進(jìn)一步定制,大大的降低了應(yīng)用服務(wù)的鏡像制作成本。
四、舉個(gè)栗子
??服務(wù)器好比運(yùn)輸碼頭:擁有場(chǎng)地和各種設(shè)備(服務(wù)器硬件資源)
??服務(wù)器虛擬化好比作碼頭上的倉(cāng)庫(kù):擁有獨(dú)立的空間堆放各種貨物或集裝箱(倉(cāng)庫(kù)之間完全獨(dú)立,獨(dú)立的應(yīng)用系統(tǒng)和操作系統(tǒng))
??Docker比作集裝箱:各種貨物的打包(將各種應(yīng)用程序和他們所依賴的運(yùn)行環(huán)境打包成標(biāo)準(zhǔn)的容器,容器之間隔離)
??Docker有著小巧、遷移部署快速、運(yùn)行高效等特點(diǎn),但隔離性比服務(wù)器虛擬化差:不同的集裝箱屬于不同的運(yùn)單(Docker上運(yùn)行不同的應(yīng)用實(shí)例),相互獨(dú)立(隔離)。但由同一個(gè)庫(kù)管人員管理(主機(jī)操作系統(tǒng)內(nèi)核),因此通過(guò)庫(kù)管人員可以看到所有集裝箱的相關(guān)信息(因?yàn)楣蚕聿僮飨到y(tǒng)內(nèi)核,因此相關(guān)信息會(huì)共享)。
??服務(wù)器虛擬化就好比在碼頭上(物理主機(jī)及虛擬化層),建立了多個(gè)獨(dú)立的“小碼頭”—倉(cāng)庫(kù)(虛擬機(jī))。其擁有完全獨(dú)立(隔離)的空間,屬于不同的客戶(虛擬機(jī)所有者)。每個(gè)倉(cāng)庫(kù)有各自的庫(kù)管人員(當(dāng)前虛擬機(jī)的操作系統(tǒng)內(nèi)核),無(wú)法管理其它倉(cāng)庫(kù)。不存在信息共享的情況
??因此,我們需要根據(jù)不同的應(yīng)用場(chǎng)景和需求采用不同的方式使用Docker技術(shù)或使用服務(wù)器虛擬化技術(shù)。例如一個(gè)典型的Docker應(yīng)用場(chǎng)景是當(dāng)主機(jī)上的Docker實(shí)例屬于單一用戶的情況下,在保證安全的同時(shí)可以充分發(fā)揮Docker的技術(shù)優(yōu)勢(shì)。對(duì)于隔離要求較高的環(huán)境如混合用戶環(huán)境,就可以使用服務(wù)器虛擬化技術(shù)。
五、Docker基本概念
1、鏡像(image)
??操作系統(tǒng)分為內(nèi)核和用戶空間。對(duì)于Linux而言,內(nèi)核啟動(dòng)后,會(huì)掛載root文件系統(tǒng)為其提供用戶空間支持,而Docker鏡像(image),就相當(dāng)于是一個(gè)root文件系統(tǒng)。
??Docker鏡像是一個(gè)特殊的文件系統(tǒng),除了提供容器運(yùn)行時(shí)所需的程序、庫(kù)、資源、配置等文件外,還包含了一些為運(yùn)行時(shí)準(zhǔn)備的一些配置參數(shù)(如匿名卷、環(huán)境變量、用戶等),鏡像不包含任何動(dòng)態(tài)數(shù)據(jù),其內(nèi)容在構(gòu)建之后也不會(huì)被改變。
鏡像分層存儲(chǔ)
??因?yàn)殓R像包含操作系統(tǒng)完整的root文件系統(tǒng),其體積往往是龐大的,因此在Docker設(shè)計(jì)時(shí)將其設(shè)計(jì)為分層存儲(chǔ)的架構(gòu)。鏡像只是一個(gè)虛擬的概念,其實(shí)際體現(xiàn)并非由一個(gè)文件組成,而是由一組文件系統(tǒng)組成,或者說(shuō),由多層文件系統(tǒng)聯(lián)合組成。
??鏡像構(gòu)建時(shí),會(huì)一層層構(gòu)建,前一層是后一層的基礎(chǔ)。每一層構(gòu)建完后就不會(huì)再發(fā)生改變,后一層上的任何改變只發(fā)生在自己這一層。在構(gòu)建鏡像的時(shí)候,需要格外小心,每一層盡量只包含該層需要添加的東西,任何額外的東西應(yīng)該在該層構(gòu)建結(jié)束前清理掉。
??分層存儲(chǔ)的特征還使得鏡像的復(fù)用、定制變得更為容易。甚至可以用之前構(gòu)建好的鏡像作為基礎(chǔ)層,然后進(jìn)一步添加新的層,以定制自己所需的內(nèi)容,構(gòu)建新的鏡像。
2、容器(container)
??鏡像(Image)和容器(Container)的關(guān)系,就像Java中的類和實(shí)例一樣,鏡像是靜態(tài)的定義,容器是鏡像運(yùn)行時(shí)的實(shí)體。容器可以被創(chuàng)建、啟動(dòng)、停止、刪除、暫停等。
??前面講過(guò)鏡像使用的是分層存儲(chǔ),容器也是如此。每一個(gè)容器運(yùn)行時(shí),是以鏡像為基礎(chǔ)層,在其上創(chuàng)建一個(gè)當(dāng)前容器的存儲(chǔ)層,我們可以稱這個(gè)為容器運(yùn)行時(shí)讀寫而準(zhǔn)備的存儲(chǔ)層為容器存儲(chǔ)層。
??容器存儲(chǔ)層的生存周期和容器一樣,容器消亡時(shí),容器存儲(chǔ)層也隨之消亡。因此,任何保存于容器存儲(chǔ)層的信息都會(huì)隨容器刪除而丟失。
??按照Docker最佳實(shí)踐的要求,容器不應(yīng)該向其存儲(chǔ)層內(nèi)寫入任何數(shù)據(jù),容器存儲(chǔ)層要保持無(wú)狀態(tài)化。所有文件寫入操作,都應(yīng)該使用Volume數(shù)據(jù)卷、或者綁定宿主目錄,在這些位置的讀寫會(huì)跳過(guò)容器存儲(chǔ)層,直接對(duì)宿主(或網(wǎng)絡(luò)存儲(chǔ))發(fā)生讀寫,其性能和穩(wěn)定性更高。
??數(shù)據(jù)卷的生存周期獨(dú)立于容器,容器消亡,數(shù)據(jù)卷不會(huì)消亡。因此,使用數(shù)據(jù)卷后,容器刪除或者重新運(yùn)行之后,數(shù)據(jù)不會(huì)丟失。
3、倉(cāng)庫(kù)(repository)
??鏡像構(gòu)建完成后,可以很容易地在當(dāng)前宿主機(jī)上運(yùn)行,但是,如果需要在其他服務(wù)器上使用這個(gè)鏡像,我們就需要一個(gè)集中的存儲(chǔ)、分發(fā)鏡像的服務(wù),Docker Registry就是這樣的服務(wù)。
??一個(gè)Docker Registry中可以包含多個(gè)倉(cāng)庫(kù)(Repository),每個(gè)倉(cāng)庫(kù)可以包括多個(gè)標(biāo)簽(Tag),每個(gè)標(biāo)簽對(duì)應(yīng)一個(gè)鏡像。
??通常,一個(gè)倉(cāng)庫(kù)會(huì)包含同一個(gè)軟件不同版本的鏡像,而標(biāo)簽就常用于對(duì)應(yīng)該軟件的各個(gè)版本。我們可以通過(guò)<倉(cāng)庫(kù)名>:<標(biāo)簽>的格式來(lái)指定具體是這個(gè)軟件哪個(gè)版本的鏡像。如果不給出標(biāo)簽,將以latest作為默認(rèn)標(biāo)簽。
??以centos鏡像為例,centos是倉(cāng)庫(kù)的名字,其內(nèi)包含有不同的版本標(biāo)簽,如:6.9、7.5。我們可以通過(guò)centos:6.9,或者centos:7.5來(lái)具體指定所需哪個(gè)版本的鏡像。如果忽略了標(biāo)簽,比如centos,那將視為centos:latest。
??倉(cāng)庫(kù)名經(jīng)常以兩段式路徑形式出現(xiàn),比如study/nginx,前者往往意味著Docker Registry多用戶環(huán)境下的用戶名,后者往往是對(duì)應(yīng)的軟件名。但這并非絕對(duì),取決于所使用的具體Docker Registry的軟甲和服務(wù)。
- 公有Docker Registry
??常用的Registry是官方的Docker Hub,這也是默認(rèn)的Registry。初次之外,還有CoreOS的Quay.io,CoreOS相關(guān)的鏡像存儲(chǔ)在這里;Google的Google Container Registry,Kubernetes的鏡像使用的就是這個(gè)服務(wù)。
??國(guó)內(nèi)的一些云服務(wù)商提供了針對(duì)Docker Hub的鏡像服務(wù),這些鏡像服務(wù)被成為加速器。常見(jiàn)的有阿里云加速器、DaoCloud加速器等。使用加速器會(huì)直接從國(guó)內(nèi)的地址下載Docker Hub的鏡像,比直接從Docker Hub下載速度會(huì)提高很多。
??國(guó)內(nèi)也有一些云服務(wù)商提供類似于Docker Hub的公開(kāi)服務(wù)。比如網(wǎng)易云鏡像服務(wù)、DaoCloud鏡像市場(chǎng)、阿里云鏡像庫(kù)等。
-
私有Docker Registry
??除了使用公開(kāi)服務(wù)外,用戶還可以在本地搭建私有Docker Reistry。Docker官方提供了Docker Registry鏡像,可以直接使用作為私有Registry服務(wù)。
??開(kāi)源的Docker Registry鏡像只提供了Docker Registry API的服務(wù)端實(shí)現(xiàn),足以支持docker命令,不影響使用。但不包含圖形界面,以及鏡像維護(hù)、用戶管理、訪問(wèn)控制等高級(jí)功能。在官方的商業(yè)化版本Docker Trusted Registry中,提供了這些高級(jí)功能。
??除了官方的Docker Registry外,還有第三方軟件實(shí)現(xiàn)了Docker Registry API,甚至提供了用戶界面以及一些高級(jí)功能。比如,VMWare Harbor和Sonatype Nexus。