Docker 簡介
什么是Docker
官方定義:Docker是以Docker容器為資源分割和調(diào)度的基本單位,封裝整個軟件運(yùn)行時環(huán)境,為開發(fā)者和系統(tǒng)管理員設(shè)計的,用于構(gòu)建、發(fā)布和運(yùn)行分布式應(yīng)用的平臺。
Docker使用Go語言進(jìn)行開發(fā)實現(xiàn),基于Linux內(nèi)核的cgroup,namespace等技術(shù),對進(jìn)程進(jìn)行封裝隔離,由于隔離的進(jìn)程獨立于宿主和其他隔離的進(jìn)程因此被稱為容器。最初實現(xiàn)是基于LXC,從0.7版本以后開始去除LXC轉(zhuǎn)而使用自行開發(fā)的libcontainer,從1.11開始則進(jìn)一步演化使用runC和containerd。
Docker版本發(fā)展史
- 2013年3月:Docker正式在github上發(fā)布0.1版本,遵從Apache 2.0開源協(xié)議
- 2014年6月:Docker1.0版本正式發(fā)布
- 2017年2月:發(fā)布1.13.1版本
- 2017年3月:docker團(tuán)隊宣布企業(yè)版Docker Enterprise Edition(EE)發(fā)布,而免費(fèi)的Docker Engine改名為Docker Community Edition(CE),并采用基于時間的版本號方案,同時發(fā)布了Docker EE和Docker CE的17.03版本,自此Docker CE/EE每個季度發(fā)布一次季度版本,每個月發(fā)布一次EDGE版本。
- 截止目前的最新版本為 19.03.5
為什么要用Docker
作為一個新興的虛擬化方式,Docker跟傳統(tǒng)的虛擬化方式想比較有眾多的優(yōu)勢:
持續(xù)部署與測試
容器消除了線上線下的環(huán)境差異,保證了應(yīng)用生命周期的環(huán)境一致性和標(biāo)準(zhǔn)化。開發(fā)人員使用鏡像實現(xiàn)標(biāo)準(zhǔn)開發(fā)環(huán)境的構(gòu)建,開發(fā)完成后通過封裝著完整環(huán)境和應(yīng)用的鏡像進(jìn)行遷移。因此測試和運(yùn)維人員可以直接部署軟件鏡像來進(jìn)行測試和發(fā)布,大大簡化了持續(xù)集成、測試和發(fā)布的過程
跨云平臺支持
容器帶來的好處之一就是其適用性,越來越多云平臺支持容器,用戶不用在擔(dān)心受到云平臺的捆綁,同時也讓應(yīng)用多平臺混合部署成為可能。
高資源利用率
由于容器不需要進(jìn)行硬件虛擬以及運(yùn)行完整操作系統(tǒng)的額外開銷,Docker對系統(tǒng)資源的利用率更高。無論是執(zhí)行速度、內(nèi)存損耗等都要比傳統(tǒng)虛擬機(jī)技術(shù)更加高效。
環(huán)境標(biāo)準(zhǔn)化和版本控制
基于容器提供的環(huán)境一致性和標(biāo)準(zhǔn)化,可以使用git等工具對容器鏡像進(jìn)行版本控制,想比較基于代碼的版本控制來說,你還可以對整個應(yīng)用運(yùn)行環(huán)境實現(xiàn)版本控制,一旦出現(xiàn)故障可以快速 回滾。
應(yīng)用鏡像倉庫
Docker官方構(gòu)建了一個鏡像倉庫,組織和管理形式類似與github,其上已經(jīng)積累了成千上萬的鏡像,因為Docker的跨平臺適配性,相當(dāng)于為用戶提供了一個非常有用的應(yīng)用商店,所有人都可以自由下載。
Docker的基本概念
Docker中包含三個基本概念:
- 鏡像 Image
- 容器 Container
-
倉庫 Repository
理解這三個基本概念就理解了Docker的整個生命周期。
三者的關(guān)系
Docker鏡像
Docker鏡像是一個特殊的文件系統(tǒng),除了提供容器運(yùn)行時所需的程序、庫、資源、配置等文件外,還包含一些為運(yùn)行時準(zhǔn)備的一些配置參數(shù),鏡像不包含任何動態(tài)數(shù)據(jù),其內(nèi)容在構(gòu)建之后也不會被改變。
例如官方鏡像ubuntu就包含了完整的一套u(yù)nbutu最小系統(tǒng)的root文件系統(tǒng)。
docker中鏡像并非是想一個ISO那樣打包文件,而是一個虛擬的概念其實際體現(xiàn)并非由一個文件組成,而是由一組文件系統(tǒng)組成。

鏡像是一堆只讀層的統(tǒng)一視角,上圖左邊我們看到多個只讀層,他們重疊在一起,除了最下面一層,其他層都會有一個指針指向下一層。這些層是Docker內(nèi)部的實現(xiàn)細(xì)節(jié),并且能夠在主機(jī)的文件系統(tǒng)上訪問到。統(tǒng)一文件系統(tǒng)技術(shù)能夠?qū)⒉煌膶诱铣梢粋€文件系統(tǒng),為這些層提供了一個統(tǒng)一的視角,這樣就隱藏了多層的存在,在用戶的角度來看,只存在一個文件系統(tǒng)。就是上圖右側(cè)所示。
Docker容器
鏡像和容器的關(guān)系,就像是面向?qū)ο缶幊讨械念惡蛯嵗粯?,鏡像是靜態(tài)的定義,容器是鏡像的運(yùn)行的實體,容器可以被創(chuàng)建、啟動、停止、刪除等。
容器的實質(zhì)是進(jìn)程,但與直接在宿主執(zhí)行的進(jìn)程不同,容器進(jìn)程運(yùn)行于屬于自己的獨立的命名空間。因此容器可以擁有自己的root文件系統(tǒng)、自己的網(wǎng)絡(luò)配置、自己的進(jìn)程空間甚至自己的用戶ID空間。容器內(nèi)的進(jìn)程是運(yùn)行在一個隔離的環(huán)境里,使用起來就像在一個獨立于宿主的系統(tǒng)下操作一樣。這種特性使得容器封裝的應(yīng)用比直接在宿主運(yùn)行更加安全。

容器的定義和鏡像幾乎一樣,也是一堆層的統(tǒng)一視角,唯一區(qū)別在于容器的最上面的那一層是可讀可寫的。這個最上面的一層是以鏡像為基礎(chǔ)層創(chuàng)建的,被稱為容器存儲層,容器存儲層的生存周期和容器一樣,容器消亡時,容器存儲層也隨之消亡。因此,任何保存于容器存儲層的信息也會隨著容器刪除而丟失。
所以根據(jù)Docker最佳實踐要求,容器不應(yīng)該向其向其存儲層內(nèi)寫入任何數(shù)據(jù),容器存儲層要保持無狀態(tài)化。所有的文件寫入操作,都應(yīng)該使用數(shù)據(jù)卷、或者綁定宿主目錄,在這些位置的讀寫會跳過容器存儲層,直接對宿主(或網(wǎng)絡(luò)存儲)發(fā)生讀寫,其性能和穩(wěn)定性更高。
數(shù)據(jù)卷的生存周期獨立于容器,容器消亡,數(shù)據(jù)卷不會消亡。因此,使用數(shù)據(jù)卷后,容器刪除或者重新運(yùn)行之后,數(shù)據(jù)卻不會丟失。
Docker Registry
鏡像構(gòu)建完成后,可以很容易的在當(dāng)前宿主機(jī)上運(yùn)行,但是如果需要在其他服務(wù)器上使用這個鏡像,我們就需要一個集中的存儲、分發(fā)鏡像的服務(wù),Docker Registry就是這樣的服務(wù)。
一個Docker Registry中可以包含多個倉庫(Repository),每個倉庫可以包含多個標(biāo)簽(Tag),每個標(biāo)簽對應(yīng)一個鏡像。
通常,一個倉庫會包含一個軟件不同版本的鏡像,而標(biāo)簽就常用與對應(yīng)該軟件的各個版本。我們可以通過 <倉庫名>:<標(biāo)簽> 的格式來指定具體是這個軟件哪個版本的鏡像。如果不給出標(biāo)簽,將以latest作為默認(rèn)標(biāo)簽。
以Ubuntu鏡像為例,ubuntu是倉庫的名字,其內(nèi)包含有不同的版本標(biāo)簽,如果16.04我們可以通過ubuntu:16.04來制定鏡像。
倉庫名經(jīng)常以兩段式路徑形式出現(xiàn),比如 jwilder/nginx-proxy ,前者往往意味著Docker Registry多用戶環(huán)境下的用戶名,后者往往是對應(yīng)的軟件名。但這并非絕對,取決于所使用的具體Docker Registry的軟件或服務(wù)。
Docker Registry公開服務(wù)
Docker Registry公開服務(wù)是開放給用戶使用、允許用戶管理鏡像的Registry服務(wù)。一般這類公開服務(wù)允許用戶免費(fèi)上傳、下載公開的鏡像,并可能提供收費(fèi)服務(wù)用戶管理私有鏡像。
最常使用的Registry公開服務(wù)是官方的Docker Hub,這也是默認(rèn)的Registry,并擁有大量的高質(zhì)量的官方鏡像。此外由于某些原因,在國內(nèi)訪問這些服務(wù)會比較慢,國內(nèi)的一些云服務(wù)商提供了針對Docker Hub的鏡像服務(wù),這些鏡像服務(wù)被稱為加速器,常用的有阿里云、網(wǎng)易云、DaoCloud等。
總結(jié)
Docker使用C/S結(jié)構(gòu),Docker客戶端與Docker服務(wù)器進(jìn)行交互,Docker服務(wù)端負(fù)責(zé)構(gòu)建、運(yùn)行和分發(fā)Docker鏡像。Docker客戶端和服務(wù)端可以運(yùn)行在一臺機(jī)器上,也可以通過RESTful、stock或網(wǎng)絡(luò)接口與遠(yuǎn)程Docker服務(wù)端進(jìn)行通信。

