什么是docker
Docker 在容器的基礎(chǔ)上,進行了進一步的封裝拱绑,從文件系統(tǒng)掘譬、網(wǎng)絡(luò)互聯(lián)到進程隔離等等,極大的簡化了容器的創(chuàng)建和維護。使得 Docker
技術(shù)比虛擬機技術(shù)更為輕便搁凸、快捷媚值。
Docker 和傳統(tǒng)虛擬化方式的不同之處:
- 傳統(tǒng)虛擬機技術(shù)是虛擬出一套硬件后,在其上運行一個完整操作系統(tǒng)护糖,在該系統(tǒng)上再運行所需應(yīng)用進程褥芒;
- 而容器內(nèi)的應(yīng)用進程直接運行于宿主的內(nèi)核,容器內(nèi)沒有自己的內(nèi)核嫡良,而且也沒有進行硬件虛擬锰扶。因此容器要比傳統(tǒng)虛擬機更為輕便。
Docker 包括三個基本概念
- 鏡像(Image)
- 容器(Container)
- 倉庫(Repository)
1.鏡像
操作系統(tǒng)分為 內(nèi)核 和 用戶空間寝受。對于 Linux
而言坷牛,內(nèi)核啟動后,會掛載 root
文件系統(tǒng)為其提供用戶空間支持很澄。而 Docker 鏡像(Image
)京闰,就相當(dāng)于是一個 root
文件系統(tǒng)。比如官方鏡像 ubuntu:18.04
就包含了完整的一套 Ubuntu 18.04 最小系統(tǒng)的 root
文件系統(tǒng)甩苛。
Docker 鏡像 是一個特殊的文件系統(tǒng)蹂楣,除了提供容器運行時所需的程序、庫讯蒲、資源痊土、配置等文件外,還包含了一些為運行時準備的一些配置參數(shù)(如匿名卷墨林、環(huán)境變量赁酝、用戶等)。鏡像 不包含 任何動態(tài)數(shù)據(jù)萌丈,其內(nèi)容在構(gòu)建之后也不會被改變赞哗。
因為鏡像包含操作系統(tǒng)完整的 root
文件系統(tǒng),其體積往往是龐大的辆雾,因此在 Docker 設(shè)計時,就充分利用 Union FS 的技術(shù)月劈,將其設(shè)計為分層存儲的架構(gòu)度迂。所以嚴格來說,鏡像并非是像一個 ISO
那樣的打包文件猜揪,鏡像只是一個虛擬的概念惭墓,其實際體現(xiàn)并非由一個文件組成,而是由一組文件系統(tǒng)組成而姐,或者說腊凶,由多層文件系統(tǒng)聯(lián)合組成。
鏡像構(gòu)建時,會一層層構(gòu)建钧萍,前一層是后一層的基礎(chǔ)褐缠。每一層構(gòu)建完就不會再發(fā)生改變,后一層上的任何改變只發(fā)生在自己這一層风瘦。比如队魏,刪除前一層文件的操作,實際不是真的刪除前一層的文件万搔,而是僅在當(dāng)前層標記為該文件已刪除胡桨。在最終容器運行的時候,雖然不會看到這個文件瞬雹,但是實際上該文件會一直跟隨鏡像昧谊。因此,在構(gòu)建鏡像的時候酗捌,需要額外小心揽浙,每一層盡量只包含該層需要添加的東西,任何額外的東西應(yīng)該在該層構(gòu)建結(jié)束前清理掉意敛。
分層存儲的特征還使得鏡像的復(fù)用馅巷、定制變的更為容易。甚至可以用之前構(gòu)建好的鏡像作為基礎(chǔ)層草姻,然后進一步添加新的層钓猬,以定制自己所需的內(nèi)容,構(gòu)建新的鏡像撩独。
2.容器
鏡像(Image
)和容器(Container
)的關(guān)系敞曹,就像是面向?qū)ο蟪绦蛟O(shè)計中的 類
和 實例
一樣,鏡像是靜態(tài)的定義综膀,容器是鏡像運行時的實體澳迫。容器可以被創(chuàng)建、啟動剧劝、停止橄登、刪除、暫停等讥此。
容器的實質(zhì)是進程拢锹,但與直接在宿主執(zhí)行的進程不同,容器進程運行于屬于自己的獨立的 命名空間萄喳。因此容器可以擁有自己的 root
文件系統(tǒng)卒稳、自己的網(wǎng)絡(luò)配置、自己的進程空間他巨,甚至自己的用戶 ID 空間充坑。容器內(nèi)的進程是運行在一個隔離的環(huán)境里减江,使用起來,就好像是在一個獨立于宿主的系統(tǒng)下操作一樣捻爷。這種特性使得容器封裝的應(yīng)用比直接在宿主運行更加安全辈灼。也因為這種隔離的特性,很多人初學(xué) Docker 時常常會混淆容器和虛擬機役衡。
前面講過鏡像使用的是分層存儲茵休,容器也是如此。每一個容器運行時手蝎,是以鏡像為基礎(chǔ)層榕莺,在其上創(chuàng)建一個當(dāng)前容器的存儲層,我們可以稱這個為容器運行時讀寫而準備的存儲層為 容器存儲層棵介。
容器存儲層的生存周期和容器一樣钉鸯,容器消亡時,容器存儲層也隨之消亡邮辽。因此唠雕,任何保存于容器存儲層的信息都會隨容器刪除而丟失。
按照 Docker 最佳實踐的要求吨述,容器不應(yīng)該向其存儲層內(nèi)寫入任何數(shù)據(jù)岩睁,容器存儲層要保持無狀態(tài)化。所有的文件寫入操作揣云,都應(yīng)該使用 數(shù)據(jù)卷(Volume)捕儒、或者 綁定宿主目錄,在這些位置的讀寫會跳過容器存儲層邓夕,直接對宿主(或網(wǎng)絡(luò)存儲)發(fā)生讀寫刘莹,其性能和穩(wěn)定性更高。
數(shù)據(jù)卷的生存周期獨立于容器焚刚,容器消亡点弯,數(shù)據(jù)卷不會消亡。因此矿咕,使用數(shù)據(jù)卷后抢肛,容器刪除或者重新運行之后,數(shù)據(jù)卻不會丟失痴腌。
3.倉庫
鏡像構(gòu)建完成后雌团,可以很容易的在當(dāng)前宿主機上運行,但是士聪,如果需要在其它服務(wù)器上使用這個鏡像,我們就需要一個集中的存儲猛蔽、分發(fā)鏡像的服務(wù)剥悟,Docker Registry 就是這樣的服務(wù)灵寺。
一個 Docker Registry 中可以包含多個 倉庫(Repository
);每個倉庫可以包含多個 標簽(Tag
)区岗;每個標簽對應(yīng)一個鏡像略板。
通常,一個倉庫會包含同一個軟件不同版本的鏡像慈缔,而標簽就常用于對應(yīng)該軟件的各個版本叮称。我們可以通過 <倉庫名>:<標簽>
的格式來指定具體是這個軟件哪個版本的鏡像。如果不給出標簽藐鹤,將以 latest
作為默認標簽瓤檐。
以 Ubuntu 鏡像 為例,ubuntu
是倉庫的名字娱节,其內(nèi)包含有不同的版本標簽挠蛉,如,16.04
, 18.04
肄满。我們可以通過 ubuntu:16.04
谴古,或者 ubuntu:18.04
來具體指定所需哪個版本的鏡像。如果忽略了標簽稠歉,比如 ubuntu
掰担,那將視為 ubuntu:latest
。
倉庫名經(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ù)允許用戶免費上傳、下載公開的鏡像穷躁,并可能提供收費服務(wù)供用戶管理私有鏡像耕肩。
最常使用的 Registry 公開服務(wù)是官方的 Docker Hub,這也是默認的 Registry问潭,并擁有大量的高質(zhì)量的 官方鏡像猿诸。除此以外,還有 Red Hat 的 Quay.io狡忙;Google 的 Google Container Registry梳虽,Kubernetes 的鏡像使用的就是這個服務(wù);代碼托管平臺 GitHub 推出的 ghcr.io灾茁。
由于某些原因窜觉,在國內(nèi)訪問這些服務(wù)可能會比較慢谷炸。國內(nèi)的一些云服務(wù)商提供了針對 Docker Hub 的鏡像服務(wù)(Registry Mirror
),這些鏡像服務(wù)被稱為 加速器禀挫。常見的有 阿里云加速器旬陡、DaoCloud 加速器 等。使用加速器會直接從國內(nèi)的地址下載 Docker Hub 的鏡像语婴,比直接從 Docker Hub 下載速度會提高很多描孟。在 安裝 Docker 一節(jié)中有詳細的配置方法。
國內(nèi)也有一些云服務(wù)商提供類似于 Docker Hub 的公開服務(wù)砰左。比如 網(wǎng)易云鏡像服務(wù)匿醒、DaoCloud 鏡像市場、阿里云鏡像庫 等菜职。
私有 Docker Registry
除了使用公開服務(wù)外青抛,用戶還可以在本地搭建私有 Docker Registry。Docker 官方提供了 Docker Registry 鏡像酬核,可以直接使用做為私有 Registry 服務(wù)蜜另。在 私有倉庫 一節(jié)中,會有進一步的搭建私有 Registry 服務(wù)的講解嫡意。
開源的 Docker Registry 鏡像只提供了 Docker Registry API 的服務(wù)端實現(xiàn)举瑰,足以支持 docker
命令,不影響使用蔬螟。但不包含圖形界面此迅,以及鏡像維護、用戶管理旧巾、訪問控制等高級功能耸序。
除了官方的 Docker Registry 外,還有第三方軟件實現(xiàn)了 Docker Registry API鲁猩,甚至提供了用戶界面以及一些高級功能坎怪。比如,Harbor 和 Sonatype Nexus廓握。