概述
Docker 是一個(gè)用于開發(fā)贩挣、部署和運(yùn)行應(yīng)用的開源平臺(tái)。它意在使你能更快地進(jìn)行應(yīng)用分發(fā)。
使用 Docker 可以將應(yīng)用系統(tǒng)和基礎(chǔ)設(shè)施分離纳击,并且可以用管理應(yīng)用系統(tǒng)類似的方式對(duì)基礎(chǔ)設(shè)施進(jìn)行管理朱灿。
Docker 使用了內(nèi)核的容器功能 + 工作流程 + 工具來助我們管理和部署應(yīng)用昧识。
什么是 Docker 平臺(tái)
Docker 內(nèi)核能將應(yīng)用安全地運(yùn)行于一個(gè)個(gè)容器中。同時(shí)盗扒,它的容器是輕量級(jí)的跪楞,因而可以在一臺(tái)主機(jī)上同時(shí)運(yùn)行很多個(gè)容器。
圍繞容器還提供了相關(guān)的工具和平臺(tái):
- 將應(yīng)用(及其相關(guān)組件)放到一個(gè) Docker 容器中
- 將容器打包發(fā)送給團(tuán)隊(duì)成員進(jìn)行再一步的開發(fā)和測試
- 將應(yīng)用部署到生產(chǎn)環(huán)境中侣灶,無論部署到本地還是云中
什么是 Docker 引擎
Docker 引擎是一個(gè) CS 框架的應(yīng)用程序甸祭,有下面幾個(gè)主要組件:
- 服務(wù)端 server 是一個(gè)一直在后臺(tái)運(yùn)行的進(jìn)程
- REST API 是客戶端及其它程序與服務(wù)端交互的接口
- 一個(gè)命令行客戶端 CLI
CLI 以腳本或直接命令的形式,利用 Docker REST API 和 Docker 后臺(tái)進(jìn)程交互褥影。而其它的 Docker 應(yīng)用也會(huì)使用 REST API 和 CLI池户。
后臺(tái)對(duì) Docker 對(duì)象進(jìn)行創(chuàng)建和管理。Docker 對(duì)象包括 images, containers, networks, data volumnes 等。
Docker 的用途
更快分發(fā)
在本地煞檩,開發(fā)人員將應(yīng)用代碼和運(yùn)行所需的相關(guān)服務(wù)一起放置在一個(gè)本地 Docker 容器中处嫌,并將其(包含代碼及所有開發(fā)堆棧)發(fā)送給同事。開發(fā)完成后斟湃,他們可以將代碼及開發(fā)堆棧推送到一個(gè)測試環(huán)境中進(jìn)行測試熏迹。在測試環(huán)境中,又可以將 Docker images 推送到生產(chǎn)環(huán)境中進(jìn)行部署凝赛。
更加容易部署和擴(kuò)展
其基于輕量級(jí)容器的特性使得它非常容易進(jìn)行擴(kuò)展注暗。 Docker 容器可以運(yùn)行在開發(fā)者機(jī)器上,數(shù)據(jù)中心的物理或虛擬機(jī)上墓猎,或者云上捆昏。
由于容器與低層基礎(chǔ)設(shè)施分離,可以實(shí)現(xiàn)實(shí)時(shí)的升配和降配毙沾。
實(shí)現(xiàn)高密度計(jì)算骗卜,承擔(dān)更多負(fù)荷
性能上相比虛擬機(jī)高效地多。
Docker 的體系結(jié)構(gòu)
CS 框架左胞。Docker 后臺(tái)進(jìn)程負(fù)責(zé)創(chuàng)建寇仓、運(yùn)行和發(fā)布 Docker 容器。Docker 客戶端和后臺(tái)進(jìn)程即可以運(yùn)行在同一個(gè)機(jī)器上烤宙,也可以運(yùn)行在不同的機(jī)器上遍烦。Docker 客戶端通過 sockets 或 REST API 與后臺(tái)進(jìn)程通訊。
Docker 后臺(tái)進(jìn)行
運(yùn)行于服務(wù)器上躺枕,用戶通過 Docker 客戶端與其交互服猪。
Docker 客戶端
即二進(jìn)制程序 docker,它接受用戶命令拐云,將命令傳給 Docker 后臺(tái)進(jìn)程罢猪,然后將命令結(jié)果返回給用戶。
Docker 的內(nèi)部機(jī)制
要理解 Docker 的內(nèi)部機(jī)理叉瘩,要知道三種資源:
- Docker images
- Docker registers
- Docker containers
Docker images (Docker 映像)
Docker image 是一個(gè)只讀模板坡脐。例如,一個(gè) Docker image 可以包含一個(gè) Ubuntu 操作系統(tǒng)房揭、Apache 及你安裝的程序备闲。Image 用來創(chuàng)建 Docker 容器。Docker 可以非常容易地創(chuàng)建新 image 或者更新現(xiàn)成的 image捅暴,或者你也可以下載別人制作的 image恬砂。
Docker image 是 Docker 的 構(gòu)建 組件。
Docker registries (Docker 登記中心)
Docker registries 保存 Docker images蓬痒。它就是一個(gè)倉庫泻骤,即有私有的也有公共的,可以從中上傳或下載 images。公共 Docker registry 是 Docker Hub狱掂。Docker registries 是 Docker 的 分發(fā) 組件演痒。
Docker containers (Docker 容器)
Docker 容器類似目錄。一個(gè)容器包含所需運(yùn)行程序的所有依賴趋惨。每個(gè)容器都根據(jù)一個(gè) Docker image 創(chuàng)建鸟顺。Docker 容器可以被運(yùn)行、開啟器虾、停止讯嫂、移動(dòng)或者刪除。每個(gè)容器都是一個(gè)隔離地安全的應(yīng)用平臺(tái)兆沙。Docker 容器是 Docker 的 運(yùn)行 平臺(tái)欧芽。
Docker image 工作原理
每個(gè) image 包含一系列的層。Docker 利用 union file systems 將這些層合并到一個(gè) image 中葛圃。UnionFS 允許不同文件系統(tǒng)(被稱作分支)的文件和目錄進(jìn)行透明的層疊千扔,從而形成一個(gè)單一的一致的文件系統(tǒng)。
采用層是 Docker 輕量級(jí)的一個(gè)原因库正。例如曲楚,當(dāng)你對(duì)應(yīng)用進(jìn)行了升級(jí)后,就會(huì)創(chuàng)建一個(gè)新的層诀诊,從而完成對(duì) image 的修改。無需對(duì)整個(gè) image 進(jìn)行重建阅嘶,只需添加或更新相關(guān)的層即可属瓣。在分發(fā)時(shí),也只需分發(fā)更新了的層讯柔。
每個(gè) image 都開始于一個(gè)最基本的 image 抡蛙,如 ubuntu,然后在些基礎(chǔ)上構(gòu)建新的 image魂迄。
在基 image 之后粗截,通過運(yùn)行一組步驟(稱為指令)來創(chuàng)建出新的 image。每個(gè)指令在我們的 image 上創(chuàng)建一個(gè)新的層捣炬。
指令動(dòng)作包含:
- 運(yùn)行命令
- 添加文件或目錄
- 創(chuàng)建環(huán)境變量
- 加載容器時(shí)運(yùn)行哪個(gè)進(jìn)程
這些指令保存在 Dockerfile 文件中熊昌。Dockerfile 是一個(gè)腳本文件,包含了從基 image 創(chuàng)建所需 image 的所有指令和命令湿酸。
Docker registry 工作原理
Docker registry 是 Docker images 的倉庫婿屹。當(dāng)創(chuàng)建了一個(gè) Docker image 后,可以將它 push 到公共 registry 上如 Docker Hub 中推溃。
通過 Docker 客戶端昂利,可以搜索已發(fā)布的 image, 然后將它 pull 到 Docker 主機(jī)上,最后根據(jù)它啟動(dòng)容器。
容器工作原理
一個(gè)容器包含一個(gè)操作系統(tǒng)蜂奸,用戶添加的文件及元數(shù)據(jù)犁苏。容器創(chuàng)建自一個(gè) image。image 告訴 Docker 一個(gè)容器中都包含什么內(nèi)容扩所,當(dāng)容器加載時(shí)要運(yùn)行哪個(gè)進(jìn)程围详,以及其它的配置數(shù)據(jù)。Docker image 是只讀的碌奉。而當(dāng) Docker 根據(jù)一個(gè) image 開啟了一個(gè)容器后短曾,它將在 image 之上添加一個(gè)讀寫層,而我們的應(yīng)用就運(yùn)行于其之上赐劣。
當(dāng)運(yùn)行一個(gè)容器時(shí)發(fā)生的事情
運(yùn)行一個(gè)容器:
$ docker run -i -t ubuntu /bin/bash
上面的命令中:
- 指定了從 ubuntu 這個(gè) image 創(chuàng)建出一個(gè)窗口
- 當(dāng)加載容器后嫉拐,在容器中運(yùn)行 /bin/bash
運(yùn)行該命令時(shí) Docker 引擎依次執(zhí)行了如下操作:
- Pull ubuntu image: 如果該 image 沒有在本地緩存,則從 Docker Hub 上 pull 下來
- 創(chuàng)建一個(gè)新的容器
- 分配文件系統(tǒng)并添加一個(gè)讀寫層魁兼。容器在該文件系統(tǒng)中創(chuàng)建婉徘,并將一個(gè)讀寫層添加到該 image 上
- 分配網(wǎng)絡(luò)/橋接接口:創(chuàng)建一個(gè)網(wǎng)絡(luò)接口使得容器能與本地主機(jī)通訊
- 設(shè)置 IP 地址:從池中查找并關(guān)聯(lián)一個(gè) IP 地址
- 執(zhí)行指定的進(jìn)程:如 /bin/bash
- 獲取應(yīng)用的輸出。
低層技術(shù)
使用 Go 編寫咐汞,并利用了以下幾個(gè)內(nèi)核功能盖呼。
Namespaces
運(yùn)行容器時(shí),Docker 會(huì)為該容器創(chuàng)建一組 namespaces化撕,從而容器中的每個(gè)部件都運(yùn)行于獨(dú)立的 namespace 中几晤,互不干擾。
Linux 上的 Docker 引擎用到的 namespaces:
- pid namespace: 進(jìn)程隔離
- net namespace: 管理網(wǎng)絡(luò)接口
- ipc namespace: 管理 IPC 資源訪問
- mnt namespace: 管理掛載點(diǎn)
- uts namespace: 隔離內(nèi)核及版本標(biāo)識(shí)(UTS:Unix Timesharing System)
Control Groups 或 cgroups
Docker 引擎利用它實(shí)現(xiàn)容器間的硬件資源共享植阴,并設(shè)置限制和約束蟹瘾。例如限制某個(gè)容器的內(nèi)存使用量。
Union file systems
Docker 引擎可以使用幾個(gè) ufs 的變種掠手,如 AUFS, btrfs, vfs 和 DeviceMapper憾朴。
Container format
Docker 引擎將這些組件合并成一個(gè)封閉體叫一個(gè) container format,默認(rèn)的 container format 叫 libcontainer喷鸽。
參考文獻(xiàn): Undering docker