亚洲全黄无码一级在线看_国产剧情久久久性色_无码av一区二区三区无码_亚洲成a×人片在线观看

當(dāng)前位置: 首頁(yè) > 科技新聞 >

一篇堪稱Docker經(jīng)典教科書的文章

時(shí)間:2020-06-29 16:48來(lái)源:網(wǎng)絡(luò)整理 瀏覽:
市面上已經(jīng)有很多優(yōu)秀的 Docker 教程,但是很多原理性的東西,筆者認(rèn)為那些教程對(duì)初學(xué)者而言還是很難理解,感覺(jué)沒(méi)有說(shuō)清楚(筆者自己都覺(jué)得挺

市面上已經(jīng)有很多優(yōu)秀的 Docker 教程,但是很多原理性的東西,筆者認(rèn)為那些教程對(duì)初學(xué)者而言還是很難理解,感覺(jué)沒(méi)有說(shuō)清楚(筆者自己都覺(jué)得挺懵逼的)。

為了讓初學(xué)者少走彎路,我將以我的學(xué)習(xí)經(jīng)歷以及作為一個(gè) CTF 的角度,編寫此套教程,來(lái)帶大家去了解并熟練運(yùn)用 Docker 。

Docker 是什么?

說(shuō)了這么多, Docker 到底是個(gè)什么東西呢?我們?cè)诶斫?Docker 之前,首先得先區(qū)分清楚兩個(gè)概念,容器和虛擬機(jī)。

可能很多讀者朋友都用過(guò)虛擬機(jī),而對(duì)容器這個(gè)概念比較的陌生。我們用的傳統(tǒng)虛擬機(jī)如 VMware , VisualBox 之類的需要模擬整臺(tái)機(jī)器包括硬件。

每臺(tái)虛擬機(jī)都需要有自己的操作系統(tǒng),虛擬機(jī)一旦被開啟,預(yù)分配給它的資源將全部被占用。

每一臺(tái)虛擬機(jī)包括應(yīng)用,必要的二進(jìn)制和庫(kù),以及一個(gè)完整的用戶操作系統(tǒng)。

而容器技術(shù)是和我們的宿主機(jī)共享硬件資源及操作系統(tǒng),可以實(shí)現(xiàn)資源的動(dòng)態(tài)分配。

容器包含應(yīng)用和其所有的依賴包,但是與其他容器共享內(nèi)核。容器在宿主機(jī)操作系統(tǒng)中,在用戶空間以分離的進(jìn)程運(yùn)行。

容器技術(shù)是實(shí)現(xiàn)操作系統(tǒng)虛擬化的一種途徑,可以讓您在資源受到隔離的進(jìn)程中運(yùn)行應(yīng)用程序及其依賴關(guān)系。

通過(guò)使用容器,我們可以輕松打包應(yīng)用程序的代碼、配置和依賴關(guān)系,將其變成容易使用的構(gòu)建塊,從而實(shí)現(xiàn)環(huán)境一致性、運(yùn)營(yíng)效率、開發(fā)人員生產(chǎn)力和版本控制等諸多目標(biāo)。

容器可以幫助保證應(yīng)用程序快速、可靠、一致地部署,其間不受部署環(huán)境的影響。

容器還賦予我們對(duì)資源更多的精細(xì)化控制能力,讓我們的基礎(chǔ)設(shè)施效率更高。

通過(guò)下面這幅圖,我們可以很直觀的反映出這兩者的區(qū)別所在:

一篇堪稱Docker經(jīng)典教科書的文章

Docker 屬于 Linux 容器的一種封裝,提供簡(jiǎn)單易用的容器使用接口。它是目前最流行的 Linux 容器解決方案。

而 Linux 容器是 Linux 發(fā)展出的另一種虛擬化技術(shù),簡(jiǎn)單來(lái)講, Linux 容器不是模擬一個(gè)完整的操作系統(tǒng),而是對(duì)進(jìn)程進(jìn)行隔離,相當(dāng)于是在正常進(jìn)程的外面套了一個(gè)保護(hù)層。

對(duì)于容器里面的進(jìn)程來(lái)說(shuō),它接觸到的各種資源都是虛擬的,從而實(shí)現(xiàn)與底層系統(tǒng)的隔離。

Docker 將應(yīng)用程序與該程序的依賴,打包在一個(gè)文件里面。運(yùn)行這個(gè)文件,就會(huì)生成一個(gè)虛擬容器。

程序在這個(gè)虛擬容器里運(yùn)行,就好像在真實(shí)的物理機(jī)上運(yùn)行一樣。有了 Docker ,就不用擔(dān)心環(huán)境問(wèn)題。

總體來(lái)說(shuō),Docker 的接口相當(dāng)簡(jiǎn)單,用戶可以方便地創(chuàng)建和使用容器,把自己的應(yīng)用放入容器。容器還可以進(jìn)行版本管理、復(fù)制、分享、修改,就像管理普通的代碼一樣。

Docker 的優(yōu)勢(shì)

Docker 相比于傳統(tǒng)虛擬化方式具有更多的優(yōu)勢(shì):

Docker 啟動(dòng)快速屬于秒級(jí)別。虛擬機(jī)通常需要幾分鐘去啟動(dòng)。Docker 需要的資源更少。Docker 在操作系統(tǒng)級(jí)別進(jìn)行虛擬化,Docker 容器和內(nèi)核交互,幾乎沒(méi)有性能損耗,性能優(yōu)于通過(guò) Hypervisor 層與內(nèi)核層的虛擬化。Docker 更輕量。Docker 的架構(gòu)可以共用一個(gè)內(nèi)核與共享應(yīng)用程序庫(kù),所占內(nèi)存極小。同樣的硬件環(huán)境,Docker 運(yùn)行的鏡像數(shù)遠(yuǎn)多于虛擬機(jī)數(shù)量,對(duì)系統(tǒng)的利用率非常高。與虛擬機(jī)相比,Docker 隔離性更弱。Docker 屬于進(jìn)程之間的隔離,虛擬機(jī)可實(shí)現(xiàn)系統(tǒng)級(jí)別隔離。安全性。Docker 的安全性也更弱,Docker 的租戶 Root 和宿主機(jī) Root 等同,一旦容器內(nèi)的用戶從普通用戶權(quán)限提升為 Root 權(quán)限,它就直接具備了宿主機(jī)的 Root 權(quán)限,進(jìn)而可進(jìn)行無(wú)限制的操作。虛擬機(jī)租戶 Root 權(quán)限和宿主機(jī)的 Root 虛擬機(jī)權(quán)限是分離的,并且虛擬機(jī)利用如 Intel 的 VT-d 和 VT-x 的 ring-1 硬件隔離技術(shù)。這種隔離技術(shù)可以防止虛擬機(jī)突破和彼此交互,而容器至今還沒(méi)有任何形式的硬件隔離,這使得容器容易受到攻擊??晒芾硇?。Docker 的集中化管理工具還不算成熟。各種虛擬化技術(shù)都有成熟的管理工具,例如 VMware vCenter 提供完備的虛擬機(jī)管理能力。高可用和可恢復(fù)性。Docker 對(duì)業(yè)務(wù)的高可用支持是通過(guò)快速重新部署實(shí)現(xiàn)的。虛擬化具備負(fù)載均衡,高可用,容錯(cuò),遷移和數(shù)據(jù)保護(hù)等經(jīng)過(guò)生產(chǎn)實(shí)踐檢驗(yàn)的成熟保障機(jī)制, VMware 可承諾虛擬機(jī) 99.999% 高可用,保證業(yè)務(wù)連續(xù)性??焖賱?chuàng)建、刪除。虛擬化創(chuàng)建是分鐘級(jí)別的,Docker 容器創(chuàng)建是秒級(jí)別的,Docker 的快速迭代性,決定了無(wú)論是開發(fā)、測(cè)試、部署都可以節(jié)約大量時(shí)間交付、部署。虛擬機(jī)可以通過(guò)鏡像實(shí)現(xiàn)環(huán)境交付的一致性,但鏡像分發(fā)無(wú)法體系化。Docker 在 Dockerfile 中記錄了容器構(gòu)建過(guò)程,可在集群中實(shí)現(xiàn)快速分發(fā)和快速部署。我們可以從下面這張表格很清楚地看到容器相比于傳統(tǒng)虛擬機(jī)的特性的優(yōu)勢(shì)所在:一篇堪稱Docker經(jīng)典教科書的文章

Docker 的三個(gè)基本概念

一篇堪稱Docker經(jīng)典教科書的文章

從上圖我們可以看到,Docker 中包括三個(gè)基本的概念:

Image(鏡像)Container(容器)Repository(倉(cāng)庫(kù))鏡像是 Docker 運(yùn)行容器的前提,倉(cāng)庫(kù)是存放鏡像的場(chǎng)所,可見鏡像更是 Docker 的核心。

Image(鏡像)

那么鏡像到底是什么呢?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ì)被改變。鏡像(Image)就是一堆只讀層(read-only layer)的統(tǒng)一視角,也許這個(gè)定義有些難以理解,下面的這張圖能夠幫助讀者理解鏡像的定義:

一篇堪稱Docker經(jīng)典教科書的文章

從左邊我們看到了多個(gè)只讀層,它們重疊在一起。除了最下面一層,其他層都會(huì)有一個(gè)指針指向下一層。這些層是 Docker 內(nèi)部的實(shí)現(xiàn)細(xì)節(jié),并且能夠在主機(jī)的文件系統(tǒng)上訪問(wèn)到。

統(tǒng)一文件系統(tǒng)(Union File System)技術(shù)能夠?qū)⒉煌膶诱铣梢粋€(gè)文件系統(tǒng),為這些層提供了一個(gè)統(tǒng)一的視角。

這樣就隱藏了多層的存在,在用戶的角度看來(lái),只存在一個(gè)文件系統(tǒng)。我們可以在圖片的右邊看到這個(gè)視角的形式。

Container(容器)

容器(Container)的定義和鏡像(Image)幾乎一模一樣,也是一堆層的統(tǒng)一視角,唯一區(qū)別在于容器的最上面那一層是可讀可寫的。

一篇堪稱Docker經(jīng)典教科書的文章

由于容器的定義并沒(méi)有提及是否要運(yùn)行容器,所以實(shí)際上,容器 = 鏡像 + 讀寫層。

Repository(倉(cāng)庫(kù))

Docker 倉(cāng)庫(kù)是集中存放鏡像文件的場(chǎng)所。鏡像構(gòu)建完成后,可以很容易的在當(dāng)前宿主上運(yùn)行。

但是, 如果需要在其他服務(wù)器上使用這個(gè)鏡像,我們就需要一個(gè)集中的存儲(chǔ)、分發(fā)鏡像的服務(wù),Docker Registry(倉(cāng)庫(kù)注冊(cè)服務(wù)器)就是這樣的服務(wù)。

有時(shí)候會(huì)把倉(cāng)庫(kù)(Repository)和倉(cāng)庫(kù)注冊(cè)服務(wù)器(Registry)混為一談,并不嚴(yán)格區(qū)分。

Docker 倉(cāng)庫(kù)的概念跟 Git 類似,注冊(cè)服務(wù)器可以理解為 GitHub 這樣的托管服務(wù)。

實(shí)際上,一個(gè) Docker Registry 中可以包含多個(gè)倉(cāng)庫(kù)(Repository),每個(gè)倉(cāng)庫(kù)可以包含多個(gè)標(biāo)簽(Tag),每個(gè)標(biāo)簽對(duì)應(yīng)著一個(gè)鏡像。

所以說(shuō),鏡像倉(cāng)庫(kù)是 Docker 用來(lái)集中存放鏡像文件的地方,類似于我們之前常用的代碼倉(cāng)庫(kù)。

通常,一個(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)簽。

倉(cāng)庫(kù)又可以分為兩種形式:

Public(公有倉(cāng)庫(kù))Private(私有倉(cāng)庫(kù))

Docker Registry 公有倉(cāng)庫(kù)是開放給用戶使用、允許用戶管理鏡像的 Registry 服務(wù)。

一般這類公開服務(wù)允許用戶免費(fèi)上傳、下載公開的鏡像,并可能提供收費(fèi)服務(wù)供用戶管理私有鏡像。

除了使用公開服務(wù)外,用戶還可以在本地搭建私有 Docker Registry。Docker 官方提供了 Docker Registry 鏡像,可以直接使用做為私有 Registry 服務(wù)。

當(dāng)用戶創(chuàng)建了自己的鏡像之后就可以使用 Push 命令將它上傳到公有或者私有倉(cāng)庫(kù),這樣下次在另外一臺(tái)機(jī)器上使用這個(gè)鏡像時(shí)候,只需要從倉(cāng)庫(kù)上 Pull 下來(lái)就可以了。

我們主要把 Docker 的一些常見概念如 Image,Container,Repository 做了詳細(xì)的闡述,也從傳統(tǒng)虛擬化方式的角度闡述了 Docker 的優(yōu)勢(shì)。

我們從下圖可以直觀地看到 Docker 的架構(gòu):

一篇堪稱Docker經(jīng)典教科書的文章

Docker 使用 C/S 結(jié)構(gòu),即客戶端/服務(wù)器體系結(jié)構(gòu)。Docker 客戶端與 Docker 服務(wù)器進(jìn)行交互,Docker服務(wù)端負(fù)責(zé)構(gòu)建、運(yùn)行和分發(fā) Docker 鏡像。

Docker 客戶端和服務(wù)端可以運(yùn)行在一臺(tái)機(jī)器上,也可以通過(guò) RESTful 、 Stock 或網(wǎng)絡(luò)接口與遠(yuǎn)程 Docker 服務(wù)端進(jìn)行通信。

一篇堪稱Docker經(jīng)典教科書的文章

這張圖展示了 Docker 客戶端、服務(wù)端和 Docker 倉(cāng)庫(kù)(即 Docker Hub 和 Docker Cloud ),默認(rèn)情況下 Docker 會(huì)在 Docker 中央倉(cāng)庫(kù)尋找鏡像文件。

這種利用倉(cāng)庫(kù)管理鏡像的設(shè)計(jì)理念類似于 Git ,當(dāng)然這個(gè)倉(cāng)庫(kù)是可以通過(guò)修改配置來(lái)指定的,甚至我們可以創(chuàng)建我們自己的私有倉(cāng)庫(kù)。

Docker 的安裝和使用

Docker 的安裝和使用有一些前提條件,主要體現(xiàn)在體系架構(gòu)和內(nèi)核的支持上。

對(duì)于體系架構(gòu),除了 Docker 一開始就支持的 X86-64 ,其他體系架構(gòu)的支持則一直在不斷地完善和推進(jìn)中。

Docker 分為 CE 和 EE 兩大版本。CE 即社區(qū)版,免費(fèi)支持周期 7 個(gè)月;EE 即企業(yè)版,強(qiáng)調(diào)安全,付費(fèi)使用,支持周期 24 個(gè)月。

我們?cè)诎惭b前可以參看官方文檔獲取最新的 Docker 支持情況,官方文檔在這里:

https://docs.docker.com/install/Docker 對(duì)于內(nèi)核支持的功能,即內(nèi)核的配置選項(xiàng)也有一定的要求(比如必須開啟 Cgroup 和 Namespace 相關(guān)選項(xiàng),以及其他的網(wǎng)絡(luò)和存儲(chǔ)驅(qū)動(dòng)等)。Docker 源碼中提供了一個(gè)檢測(cè)腳本來(lái)檢測(cè)和指導(dǎo)內(nèi)核的配置,腳本鏈接在這里:
https://raw.githubusercontent.com/docker/docker/master/contrib/check-config.sh

在滿足前提條件后,安裝就變得非常的簡(jiǎn)單了。

Docker CE 的安裝請(qǐng)參考官方文檔:

MacOS:https://docs.docker.com/docker-for-mac/install/Windows:https://docs.docker.com/docker-for-windows/install/Ubuntu:https://docs.docker.com/install/linux/docker-ce/ubuntu/Debian:https://docs.docker.com/install/linux/docker-ce/debian/CentOS:https://docs.docker.com/install/linux/docker-ce/centos/Fedora:https://docs.docker.com/install/linux/docker-ce/fedora/其他 Linux 發(fā)行版:https://docs.docker.com/install/linux/docker-ce/binaries/

這里我們以 CentOS 7 作為演示。

環(huán)境準(zhǔn)備:

阿里云服務(wù)器(1 核 2G,1M 帶寬)CentOS 7.4 64 位

由于 Docker-CE 支持 64 位版本的 CentOS 7 ,并且要求內(nèi)核版本不低于 3.10,首先我們需要卸載掉舊版本的 Docker:

$ sudo yum remove docker 
docker-client
docker-client-latest
docker-common
docker-latest
docker-latest-logrotate
docker-logrotate
docker-selinux
docker-engine-selinux
docker-engine
一篇堪稱Docker經(jīng)典教科書的文章

我們執(zhí)行以下安裝命令去安裝依賴包:

$ sudo yum install -y yum-utils 
device-mapper-persistent-data
lvm2

這里我事先已經(jīng)安裝過(guò)了,所以提示我已經(jīng)安裝了最新版本:

一篇堪稱Docker經(jīng)典教科書的文章

安裝 Docker

Docker 軟件包已經(jīng)包括在默認(rèn)的 CentOS-Extras 軟件源里。因此想要安裝 Docker,只需要運(yùn)行下面的 yum 命令:

$ sudo yum install docker當(dāng)然在測(cè)試或開發(fā)環(huán)境中 Docker 官方為了簡(jiǎn)化安裝流程,提供了一套便捷的安裝腳本,CentOS 系統(tǒng)上可以使用這套腳本安裝:
curl -fsSL get.docker.com -o get-docker.sh
sh get-docker.sh

具體可以參看 docker-install 的腳本:

https://github.com/docker/docker-install

執(zhí)行這個(gè)命令后,腳本就會(huì)自動(dòng)的將一切準(zhǔn)備工作做好,并且把 Docker CE 的 Edge 版本安裝在系統(tǒng)中。

安裝完成后,運(yùn)行下面的命令,驗(yàn)證是否安裝成功:

docker versionordocker info

返回 Docker 的版本相關(guān)信息,證明 Docker 安裝成功:

一篇堪稱Docker經(jīng)典教科書的文章

啟動(dòng) Docker-CE:

$ sudo systemctl enable docker$ sudo systemctl start docker

Docker 的簡(jiǎn)單運(yùn)用 Hello World

由于服務(wù)器日常崩潰了, Docker 出了點(diǎn)問(wèn)題,所以以下案例的演示是基于 Kali Linux 環(huán)境下進(jìn)行的。

我們通過(guò)最簡(jiǎn)單的 Image 文件 Hello World,感受一下 Docker 的魅力吧!

我們直接運(yùn)行下面的命令,將名為 hello-world 的 image 文件從倉(cāng)庫(kù)抓取到本地:

docker pull library/hello-world

docker pull images 是抓取 image 文件,library/hello-world 是 image 文件在倉(cāng)庫(kù)里面的位置,其中 library 是 image 文件所在的組,hello-world 是 image 文件的名字。

一篇堪稱Docker經(jīng)典教科書的文章

抓取成功以后,就可以在本機(jī)看到這個(gè) image 文件了:

docker images

我們可以看到如下結(jié)果:

一篇堪稱Docker經(jīng)典教科書的文章

現(xiàn)在,我們可以運(yùn)行 hello-world 這個(gè) image 文件:

docker run hello-world

我們可以看到如下結(jié)果:

一篇堪稱Docker經(jīng)典教科書的文章

輸出這段提示以后,hello world 就會(huì)停止運(yùn)行,容器自動(dòng)終止。有些容器不會(huì)自動(dòng)終止,因?yàn)樘峁┑氖欠?wù),比如 MySQL 鏡像等。

是不是很 Easy 呢?我們從上面可以看出,Docker 的功能是十分強(qiáng)大的,除此之外,我們還可以拉取一些 Ubuntu,Apache 等鏡像,在未來(lái)的教程中我們將會(huì)一一提到。

Docker 提供了一套簡(jiǎn)單實(shí)用的命令來(lái)創(chuàng)建和更新鏡像,我們可以通過(guò)網(wǎng)絡(luò)直接下載一個(gè)已經(jīng)創(chuàng)建好了的應(yīng)用鏡像,并通過(guò) Docker RUN 命令就可以直接使用。

當(dāng)鏡像通過(guò) RUN 命令運(yùn)行成功后,這個(gè)運(yùn)行的鏡像就是一個(gè) Docker 容器啦。

容器可以理解為一個(gè)輕量級(jí)的沙箱,Docker 利用容器來(lái)運(yùn)行和隔離應(yīng)用,容器是可以被啟動(dòng)、停止、刪除的,這并不會(huì)影響 Docker 鏡像。

我們可以看看下面這幅圖:

一篇堪稱Docker經(jīng)典教科書的文章

Docker 客戶端是 Docker 用戶與 Docker 交互的主要方式。當(dāng)您使用 Docker 命令行運(yùn)行命令時(shí),Docker 客戶端將這些命令發(fā)送給服務(wù)器端,服務(wù)端將執(zhí)行這些命令。

Docker 命令使用 Docker API 。Docker 客戶端可以與多個(gè)服務(wù)端進(jìn)行通信。

我們將剖析一下 Docker 容器是如何工作的,學(xué)習(xí)好 Docker 容器工作的原理,我們就可以自己去管理我們的容器了。

Docker 架構(gòu)

在上面的學(xué)習(xí)中,我們簡(jiǎn)單地講解了 Docker 的基本架構(gòu)。了解到了 Docker 使用的是 C/S 結(jié)構(gòu),即客戶端/服務(wù)器體系結(jié)構(gòu)。

明白了 Docker 客戶端與 Docker 服務(wù)器進(jìn)行交互時(shí),Docker 服務(wù)端負(fù)責(zé)構(gòu)建、運(yùn)行和分發(fā) Docker 鏡像。

知道了 Docker 客戶端和服務(wù)端可以運(yùn)行在一臺(tái)機(jī)器上,我們可以通過(guò) RESTful 、Stock 或網(wǎng)絡(luò)接口與遠(yuǎn)程 Docker 服務(wù)端進(jìn)行通信。

我們從下圖可以很直觀的了解到 Docker 的架構(gòu):

一篇堪稱Docker經(jīng)典教科書的文章

Docker 的核心組件包括:

Docker ClientDocker DaemonDocker ImageDocker RegistryDocker Container

Docker 采用的是 Client/Server 架構(gòu)??蛻舳讼蚍?wù)器發(fā)送請(qǐng)求,服務(wù)器負(fù)責(zé)構(gòu)建、運(yùn)行和分發(fā)容器。

客戶端和服務(wù)器可以運(yùn)行在同一個(gè) Host 上,客戶端也可以通過(guò) Socket 或 REST API 與遠(yuǎn)程的服務(wù)器通信。

可能很多朋友暫時(shí)不太理解一些東西,比如 REST API 是什么東西等,不過(guò)沒(méi)關(guān)系,在后面的文章中會(huì)一一給大家講解清楚。

Docker Client

Docker Client ,也稱 Docker 客戶端。它其實(shí)就是 Docker 提供命令行界面(CLI)工具,是許多 Docker 用戶與 Docker 進(jìn)行交互的主要方式。

客戶端可以構(gòu)建,運(yùn)行和停止應(yīng)用程序,還可以遠(yuǎn)程與 Docker_Host 進(jìn)行交互。

最常用的 Docker 客戶端就是 Docker 命令,我們可以通過(guò) Docker 命令很方便地在 Host 上構(gòu)建和運(yùn)行 Docker 容器。

一篇堪稱Docker經(jīng)典教科書的文章

Docker Daemon

Docker Daemon 是服務(wù)器組件,以 Linux 后臺(tái)服務(wù)的方式運(yùn)行,是 Docker 最核心的后臺(tái)進(jìn)程,我們也把它稱為守護(hù)進(jìn)程。

它負(fù)責(zé)響應(yīng)來(lái)自 Docker Client 的請(qǐng)求,然后將這些請(qǐng)求翻譯成系統(tǒng)調(diào)用完成容器管理操作。

該進(jìn)程會(huì)在后臺(tái)啟動(dòng)一個(gè) API Server ,負(fù)責(zé)接收由 Docker Client 發(fā)送的請(qǐng)求,接收到的請(qǐng)求將通過(guò) Docker Daemon 內(nèi)部的一個(gè)路由分發(fā)調(diào)度,由具體的函數(shù)來(lái)執(zhí)行請(qǐng)求。

一篇堪稱Docker經(jīng)典教科書的文章

我們大致可以將其分為以下三部分:

Docker ServerEngineJob

Docker Daemon 的架構(gòu)如下所示:

一篇堪稱Docker經(jīng)典教科書的文章

Docker Daemon 可以認(rèn)為是通過(guò) Docker Server 模塊接受 Docker Client 的請(qǐng)求,并在 Engine 中處理請(qǐng)求,然后根據(jù)請(qǐng)求類型,創(chuàng)建出指定的 Job 并運(yùn)行。

Docker Daemon 運(yùn)行在 Docker Host 上,負(fù)責(zé)創(chuàng)建、運(yùn)行、監(jiān)控容器,構(gòu)建、存儲(chǔ)鏡像。

運(yùn)行過(guò)程的作用有以下幾種可能:

向 Docker Registry 獲取鏡像。通過(guò) graphdriver 執(zhí)行容器鏡像的本地化操作。通過(guò) networkdriver 執(zhí)行容器網(wǎng)絡(luò)環(huán)境的配置。通過(guò) execdriver 執(zhí)行容器內(nèi)部運(yùn)行的執(zhí)行工作。

由于 Docker Daemon 和 Docker Client 的啟動(dòng)都是通過(guò)可執(zhí)行文件 Docker 來(lái)完成的,因此兩者的啟動(dòng)流程非常相似。

Docker 可執(zhí)行文件運(yùn)行時(shí),運(yùn)行代碼通過(guò)不同的命令行 Flag 參數(shù),區(qū)分兩者,并最終運(yùn)行兩者各自相應(yīng)的部分。

啟動(dòng) Docker Daemon 時(shí),一般可以使用以下命令來(lái)完成:

docker --daemon = truedocker –d
docker –d = true

再由 Docker 的 main() 函數(shù)來(lái)解析以上命令的相應(yīng) Flag 參數(shù),并最終完成 Docker Daemon 的啟動(dòng)。

下圖可以很直觀地看到 Docker Daemon 的啟動(dòng)流程:

一篇堪稱Docker經(jīng)典教科書的文章

默認(rèn)配置下,Docker Daemon 只能響應(yīng)來(lái)自本地 Host 的客戶端請(qǐng)求。如果要允許遠(yuǎn)程客戶端請(qǐng)求,需要在配置文件中打開 TCP 監(jiān)聽。

我們可以照著如下步驟進(jìn)行配置:

①編輯配置文件/etc/systemd/system/multi-user.target.wants/docker.service,在環(huán)境變量 ExecStart 后面添加 -H tcp://0.0.0.0,允許來(lái)自任意 IP 的客戶端連接。

一篇堪稱Docker經(jīng)典教科書的文章

②重啟 Docker Daemon:

systemctl daemon-reload
systemctl restart docker.service

③我們通過(guò)以下命令即可實(shí)現(xiàn)與遠(yuǎn)程服務(wù)器通信:

docker -H 服務(wù)器IP地址 info

-H 是用來(lái)指定服務(wù)器主機(jī),info 子命令用于查看 Docker 服務(wù)器的信息。

Docker Image

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ì)被改變。我們可將 Docker 鏡像看成只讀模板,通過(guò)它可以創(chuàng)建 Docker 容器。

鏡像有多種生成方法:

從無(wú)到有開始創(chuàng)建鏡像下載并使用別人創(chuàng)建好的現(xiàn)成的鏡像在現(xiàn)有鏡像上創(chuàng)建新的鏡像

我們可以將鏡像的內(nèi)容和創(chuàng)建步驟描述在一個(gè)文本文件中,這個(gè)文件被稱作 Dockerfile ,通過(guò)執(zhí)行 docker build <docker-file>命令可以構(gòu)建出 Docker 鏡像。

Docker Registry

Docker Registry 是存儲(chǔ) Docker Image 的倉(cāng)庫(kù),它在 Docker 生態(tài)環(huán)境中的位置如下圖所示:

一篇堪稱Docker經(jīng)典教科書的文章

運(yùn)行 docker push、docker pull、docker search 時(shí),實(shí)際上是通過(guò) Docker Daemon 與 Docker Registry 通信。

Docker Container

Docker 容器就是 Docker 鏡像的運(yùn)行實(shí)例,是真正運(yùn)行項(xiàng)目程序、消耗系統(tǒng)資源、提供服務(wù)的地方。

Docker Container 提供了系統(tǒng)硬件環(huán)境,我們可以使用 Docker Images 這些制作好的系統(tǒng)盤,再加上我們所編寫好的項(xiàng)目代碼,Run 一下就可以提供服務(wù)啦。

Docker 組件是如何協(xié)作運(yùn)行容器

看到這里,我相信各位讀者朋友們應(yīng)該已經(jīng)對(duì) Docker 基礎(chǔ)架構(gòu)熟悉的差不多了,我們還記得運(yùn)行的第一個(gè)容器嗎?

現(xiàn)在我們?cè)偻ㄟ^(guò) hello-world 這個(gè)例子來(lái)體會(huì)一下 Docker 各個(gè)組件是如何協(xié)作的。

容器啟動(dòng)過(guò)程如下:

Docker 客戶端執(zhí)行 docker run 命令。Docker Daemon 發(fā)現(xiàn)本地沒(méi)有 hello-world 鏡像。Daemon 從 Docker Hub 下載鏡像。下載完成,鏡像 hello-world 被保存到本地。Docker Daemon 啟動(dòng)容器。

具體過(guò)程可以看如下這幅演示圖:

一篇堪稱Docker經(jīng)典教科書的文章

我們可以通過(guò) Docker Images 可以查看到 hello-world 已經(jīng)下載到本地:

一篇堪稱Docker經(jīng)典教科書的文章

我們可以通過(guò) Docker Ps 或者 Docker Container ls 顯示正在運(yùn)行的容器,我們可以看到,hello-world 在輸出提示信息以后就會(huì)停止運(yùn)行,容器自動(dòng)終止,所以我們?cè)诓榭吹臅r(shí)候沒(méi)有發(fā)現(xiàn)有容器在運(yùn)行。

一篇堪稱Docker經(jīng)典教科書的文章

我們把 Docker 容器的工作流程剖析的十分清楚了,我們大體可以知道 Docker 組件協(xié)作運(yùn)行容器可以分為以下幾個(gè)過(guò)程:

Docker 客戶端執(zhí)行 docker run 命令。Docker Daemon 發(fā)現(xiàn)本地沒(méi)有我們需要的鏡像。Daemon 從 Docker Hub 下載鏡像。下載完成后,鏡像被保存到本地。Docker Daemon 啟動(dòng)容器。

了解了這些過(guò)程以后,我們?cè)賮?lái)理解這些命令就不會(huì)覺(jué)得很突兀了,下面我來(lái)給大家講講 Docker 常用的一些命令操作吧。

Docker 常用命令

我們可以通過(guò) docker -h 去查看命令的詳細(xì)的幫助文檔。在這里我只會(huì)講一些日常我們可能會(huì)用的比較多的一些命令。

一篇堪稱Docker經(jīng)典教科書的文章

例如,我們需要拉取一個(gè) Docker 鏡像,我們可以用如下命令:

docker pull image_name

image_name 為鏡像的名稱,而如果我們想從 Docker Hub 上去下載某個(gè)鏡像,我們可以使用以下命令:

docker pull centos:latest

cento:lastest 是鏡像的名稱,Docker Daemon 發(fā)現(xiàn)本地沒(méi)有我們需要的鏡像,會(huì)自動(dòng)去 Docker Hub 上去下載鏡像,下載完成后,該鏡像被默認(rèn)保存到 /var/lib/docker 目錄下。

接著我們?nèi)绻氩榭粗鳈C(jī)下存在多少鏡像,我們可以用如下命令:

docker images

我們要想知道當(dāng)前有哪些容器在運(yùn)行,我們可以用如下命令:

docker ps -a

-a 是查看當(dāng)前所有的容器,包括未運(yùn)行的。我們?cè)撊绾稳?duì)一個(gè)容器進(jìn)行啟動(dòng),重啟和停止呢?

我們可以用如下命令:

docker start container_name/container_id
docker restart container_name/container_id
docker stop container_name/container_id

這個(gè)時(shí)候我們?nèi)绻脒M(jìn)入到這個(gè)容器中,我們可以使用 attach 命令:

docker attach container_name/container_id

那如果我們想運(yùn)行這個(gè)容器中的鏡像的話,并且調(diào)用鏡像里面的 bash ,我們可以使用如下命令:

docker run -t -i container_name/container_id /bin/bash

那如果這個(gè)時(shí)候,我們想刪除指定鏡像的話,由于 Image 被某個(gè) Container 引用(拿來(lái)運(yùn)行),如果不將這個(gè)引用的 Container 銷毀(刪除),那 Image 肯定是不能被刪除。

我們首先得先去停止這個(gè)容器:

docker ps

docker stop container_name/container_id

然后我們用如下命令去刪除這個(gè)容器:

docker rm container_name/container_id

然后這個(gè)時(shí)候我們?cè)偃h除這個(gè)鏡像:

docker rmi image_name

此時(shí),常用的 Docker 相關(guān)的命令就講到這里為止了,我們?cè)诤罄m(xù)的文章中還會(huì)反復(fù)地提到這些命令。

Dockerfile 是什么

前面我們已經(jīng)提到了 Docker 的一些基本概念。以 CTF 的角度來(lái)看,我們可以去使用 Dockerfile 定義鏡像,依賴鏡像來(lái)運(yùn)行容器,可以去模擬出一個(gè)真實(shí)的漏洞場(chǎng)景。

因此毫無(wú)疑問(wèn)的說(shuō), Dockerfile 是鏡像和容器的關(guān)鍵,并且 Dockerfile 還可以很輕易的去定義鏡像內(nèi)容,說(shuō)了這么多,那么 Dockerfile 到底是個(gè)什么東西呢?

Dockerfile 是自動(dòng)構(gòu)建 Docker 鏡像的配置文件,用戶可以使用 Dockerfile 快速創(chuàng)建自定義的鏡像。Dockerfile 中的命令非常類似于 Linux 下的 Shell 命令。

我們可以通過(guò)下面這幅圖來(lái)直觀地感受下 Docker 鏡像、容器和 Dockerfile 三者之間的關(guān)系:

一篇堪稱Docker經(jīng)典教科書的文章

我們從上圖中可以看到,Dockerfile 可以自定義鏡像,通過(guò) Docker 命令去運(yùn)行鏡像,從而達(dá)到啟動(dòng)容器的目的。Dockerfile 是由一行行命令語(yǔ)句組成,并且支持已 # 開頭的注釋行。

一般來(lái)說(shuō),我們可以將 Dockerfile 分為四個(gè)部分:

基礎(chǔ)鏡像(父鏡像)信息指令 FROM。維護(hù)者信息指令 MAINTAINER。鏡像操作指令 RUN 、EVN 、ADD 和 WORKDIR 等。容器啟動(dòng)指令 CMD 、ENTRYPOINT 和 USER 等。

下面是一段簡(jiǎn)單的 Dockerfile 的例子:

FROM python:2.7MAINTAINER Angel_Kitty <angelkitty6698@gmail.com>COPY . /app
WORKDIR /app
RUN pip install -r requirements.txt
EXPOSE 5000ENTRYPOINT ["python"]CMD ["app.py"]

我們可以分析一下上面這個(gè)過(guò)程:

從 Docker Hub 上 Pull 下 Python 2.7 的基礎(chǔ)鏡像。顯示維護(hù)者的信息。Copy 當(dāng)前目錄到容器中的 /App 目錄下 復(fù)制本地主機(jī)的 <src> ( Dockerfile 所在目錄的相對(duì)路徑)到容器里 <dest>。指定工作路徑為 /App。安裝依賴包。暴露 5000 端口。啟動(dòng) App。

這個(gè)例子是啟動(dòng)一個(gè) Python Flask App 的 Dockerfile ( Flask 是 Python 的一個(gè)輕量的 Web 框架),相信大家從這個(gè)例子中能夠稍微理解了 Dockfile 的組成以及指令的編寫過(guò)程。

Dockerfile 常用的指令

根據(jù)上面的例子,我們已經(jīng)差不多知道了 Dockerfile 的組成以及指令的編寫過(guò)程,我們?cè)賮?lái)理解一下這些常用命令就會(huì)得心應(yīng)手了。

由于 Dockerfile 中所有的命令都是以下格式:INSTRUCTION argument ,指令(INSTRUCTION)不分大小寫,但是推薦大寫和 SQL 語(yǔ)句是不是很相似呢?下面我們正式來(lái)講解一下這些指令集吧。

FROM

FROM 是用于指定基礎(chǔ)的 images ,一般格式為 FROM <image> or FORM <image>:<tag>。

所有的 Dockerfile 都應(yīng)該以 FROM 開頭,F(xiàn)ROM 命令指明 Dockerfile 所創(chuàng)建的鏡像文件以什么鏡像為基礎(chǔ),F(xiàn)ROM 以后的所有指令都會(huì)在 FROM 的基礎(chǔ)上進(jìn)行創(chuàng)建鏡像。

可以在同一個(gè) Dockerfile 中多次使用 FROM 命令用于創(chuàng)建多個(gè)鏡像。比如我們要指定 Python 2.7 的基礎(chǔ)鏡像,我們可以像如下寫法一樣:

FROM python:2.7 

MAINTAINER

MAINTAINER 是用于指定鏡像創(chuàng)建者和聯(lián)系方式,一般格式為 MAINTAINER <name>。

這里我設(shè)置成我的 ID 和郵箱:

MAINTAINER Angel_Kitty <angelkitty6698@gmail.com> 

COPY

COPY 是用于復(fù)制本地主機(jī)的 <src> (為 Dockerfile 所在目錄的相對(duì)路徑)到容器中的 <dest>。

當(dāng)使用本地目錄為源目錄時(shí),推薦使用 COPY 。一般格式為 COPY <src><dest> 。

例如我們要拷貝當(dāng)前目錄到容器中的 /app 目錄下,我們可以這樣操作:

COPY . /app

WORKDIR

WORKDIR 用于配合 RUN,CMD,ENTRYPOINT 命令設(shè)置當(dāng)前工作路徑。

可以設(shè)置多次,如果是相對(duì)路徑,則相對(duì)前一個(gè) WORKDIR 命令。默認(rèn)路徑為/。一般格式為 WORKDIR /path/to/work/dir。

例如我們?cè)O(shè)置 /app 路徑,我們可以進(jìn)行如下操作:

WORKDIR /app 

RUN

RUN 用于容器內(nèi)部執(zhí)行命令。每個(gè) RUN 命令相當(dāng)于在原有的鏡像基礎(chǔ)上添加了一個(gè)改動(dòng)層,原有的鏡像不會(huì)有變化。一般格式為 RUN <command> 。

例如我們要安裝 Python 依賴包,我們做法如下:

RUN pip install -r requirements.txt 

EXPOSE

EXPOSE 命令用來(lái)指定對(duì)外開放的端口。一般格式為 EXPOSE <port> [<port>...]。

例如上面那個(gè)例子,開放5000端口:

EXPOSE 5000

ENTRYPOINT

ENTRYPOINT 可以讓你的容器表現(xiàn)得像一個(gè)可執(zhí)行程序一樣。一個(gè) Dockerfile 中只能有一個(gè) ENTRYPOINT,如果有多個(gè),則最后一個(gè)生效。

ENTRYPOINT 命令也有兩種格式:

ENTRYPOINT ["executable", "param1", "param2"] :推薦使用的 Exec 形式。ENTRYPOINT command param1 param2 :Shell 形式。

例如下面這個(gè),我們要將 Python 鏡像變成可執(zhí)行的程序,我們可以這樣去做:

ENTRYPOINT ["python"] 

CMD

CMD 命令用于啟動(dòng)容器時(shí)默認(rèn)執(zhí)行的命令,CMD 命令可以包含可執(zhí)行文件,也可以不包含可執(zhí)行文件。

不包含可執(zhí)行文件的情況下就要用 ENTRYPOINT 指定一個(gè),然后 CMD 命令的參數(shù)就會(huì)作為 ENTRYPOINT 的參數(shù)。

CMD 命令有三種格式:

CMD ["executable","param1","param2"]:推薦使用的 exec 形式。CMD ["param1","param2"]:無(wú)可執(zhí)行程序形式。CMD command param1 param2:Shell 形式。

一個(gè) Dockerfile 中只能有一個(gè) CMD,如果有多個(gè),則最后一個(gè)生效。而 CMD 的 Shell 形式默認(rèn)調(diào)用 /bin/sh -c 執(zhí)行命令。

CMD 命令會(huì)被 Docker 命令行傳入的參數(shù)覆蓋:docker run busybox /bin/echo Hello Docker 會(huì)把 CMD 里的命令覆蓋。

例如我們要啟動(dòng) /app ,我們可以用如下命令實(shí)現(xiàn):

CMD ["app.py"]

當(dāng)然還有一些其他的命令,我們?cè)谟玫降臅r(shí)候再去一一講解一下。

構(gòu)建 Dockerfile

我們大體已經(jīng)把 Dockerfile 的寫法講述完畢,我們可以自己動(dòng)手寫一個(gè)例子:

mkdir static_web
cd static_web
touch Dockerfile

然后 vi Dockerfile 開始編輯該文件,輸入 i 開始編輯。以下是我們構(gòu)建的 Dockerfile 內(nèi)容:

FROM nginx
MAINTAINER Angel_Kitty <angelkitty6698@gmail.com>
RUN echo \\'<h1>Hello, Docker!</h1>\\' > /usr/share/nginx/html/index.html

編輯完后按 esc 退出編輯,然后 :wq寫入,退出。

我們?cè)?Dockerfile 文件所在目錄執(zhí)行:

docker build -t angelkitty/nginx_web:v1 .

我們解釋一下:

-t 是為新鏡像設(shè)置倉(cāng)庫(kù)和名稱angelkitty 為倉(cāng)庫(kù)名nginx_web 為鏡像名:v1 為標(biāo)簽(不添加為默認(rèn) latest )

我們構(gòu)建完成之后,使用 Docker Images 命令查看所有鏡像,如果存在 REPOSITORY 為 Nginx 和 TAG 是 v1 的信息,就表示構(gòu)建成功。

接下來(lái)使用 docker run 命令來(lái)啟動(dòng)容器:

docker run --name nginx_web -d -p 8080:80 angelkitty/nginx_web:v1

這條命令會(huì)用 Nginx 鏡像啟動(dòng)一個(gè)容器,命名為 nginx_web ,并且映射了 8080 端口。

這樣我們可以用瀏覽器去訪問(wèn)這個(gè) Nginx 服務(wù)器:http://localhost:8080/ 或者 http://本機(jī)的 IP 地址:8080/,頁(yè)面返回信息:

一篇堪稱Docker經(jīng)典教科書的文章

作者:Angel_Kitty

原文出處:https://www.cnblogs.com/ECJTUACM-873284962/

推薦內(nèi)容