docker的核心組件有哪些

docker有三大核心組件:1、鏡像(Image),一個linux的文件系統;2、容器(Container),鏡像的運行時實例;3、倉庫(Repository),集中存儲鏡像的地方。

docker的核心組件有哪些

本教程操作環境:linux5.9.8系統、docker-1.13.1版、Dell G3電腦。

Docker的三大核心組件

  • 鏡像(Image)

  • 容器(Container)

  • 倉庫(Repository)

鏡像(Image)

什么是Docker鏡像?

簡單地理解,Docker鏡像就是一個Linux的文件系統(Root Filesystem),這個文件系統里面包含可以運行在Linux內核的程序以及相應的數據。

談到這里,我們可能需要先補充一點與Linux操作系統相關的知識:

一般而言, Linux分為兩個部分:Linux內核(Linux Kernel)與用戶空間,而真正的Linux操作系統,是指Linux內核,我們常用的ubuntucentos等操作系統其實是不同廠商在Linux內核基礎上添加自己的軟件與工具集(tools)形成的發布版本(Linux Distribution)。

因此,我們也可以把鏡像看成是上面所說的用戶空間,當Docker通過鏡像創建一個容器時,就是將鏡像定義好的用戶空間作為獨立隔離的進程運行在宿主機的Linux內核之上。

這里要強調一下鏡像的兩個特征:

  • 鏡像是分層(Layer)的:即一個鏡像可以多個中間層組成,多個鏡像可以共享同一中間層,我們也可以通過在鏡像添加多一層來生成一個新的鏡像。

  • 鏡像是只讀的(read-only):鏡像在構建完成之后,便不可以再修改,而上面我們所說的添加一層構建新的鏡像,這中間實際是通過創建一個臨時的容器,在容器上增加或刪除文件,從而形成新的鏡像,因為容器是可以動態改變的。

通過下面的示意圖,我可以更好地理解Docker鏡像與Linux的關系:

docker的核心組件有哪些

操作鏡像的命令

Docker中與鏡像操作相關的命令都在docker image這條子命令下,通過docker image –help這條命令,可以看到docker image子命令的詳細文檔,如下:

Usage:??docker?image?COMMAND  Manage?images  Commands: build???????Build?an?image?from?a?Dockerfile(構建鏡像的命令) history?????Show?the?history?of?an?image(顯示鏡像構建歷史過程) import??????Import?the?contents?from?a?tarball?to?create?a?filesystem?image(導入一個由容器導出的鏡像) inspect?????Display?detailed?information?on?one?or?more?images(顯示一個鏡像的詳細信息) load????????Load?an?image?from?a?tar?archive?or?STDIN(從一個文件或標準輸入流中導入鏡像) ls??????????List?images(查看鏡像列表) prune???????Remove?unused?images(刪除虛懸鏡像) pull????????Pull?an?image?or?a?repository?from?a?registry(從倉庫拉取鏡像) push????????Push?an?image?or?a?repository?to?a?registry(推送鏡像到倉庫) rm??????????Remove?one?or?more?images(刪除鏡像) save????????Save?one?or?more?images?to?a?tar?archive(streamed?to?STDOUT?by?default)(保存鏡像到文件) tag?????????Create?a?tag?TARGET_IMAGE?that?refers?to?SOURCE_IMAGE(給鏡像打標簽)

獲取鏡像

在安裝了Docker之后,我們本地并沒有任何鏡像,當然我們可以自己構建,不過更方便還是從Docker官方提供的倉庫服務Docker Hub上拉取官方或第三方已經構建好的鏡像。

拉取鏡像可以使用docker image pull,其格式如下:

docker?image?pull?[OPTIONS]?NAME[:TAG|@DIGEST]

當然,docker image pull有更簡潔的用法:如:

docker?pull?[OPTIONS]?NAME[:TAG|@DIGEST]

要拉取鏡像,需要指定Docker Registry的URL和端口號,默認是Docker Hub,另外還需要指定倉庫名和標簽,倉庫名和標簽唯一確定一個鏡像,而標簽是可能省略,如果省略,則默認使用latest作為標簽名,而倉庫名則由作者名和軟件名組成。

所以,在省略了那么參數后,比如我們想拉取centos鏡像,可以使用下面簡單的命令從Docker Hub上拉到:

$?docker?pull?centos

查看本地鏡像

通過上面的方法我們將鏡像拉取到了本地,那要如何查看本地有哪些鏡像呢?通過下面的命令我們可以查看本地的全部鏡像:

$?docker?image?ls

當然Docker提供了更簡潔的寫法,如下:

$?docker?images

虛懸鏡像

我們知道Docker鏡像名由倉庫名和標簽組成,但有時候我們會看到倉庫名和標簽皆為的鏡像,我們稱為這種鏡像為虛懸鏡像,如下圖所示:

docker的核心組件有哪些

虛懸鏡像一般是當我們使用docker pull拉取最新鏡像時,生成的新的鏡像,所以倉庫名和標簽給了新的鏡像,舊的鏡像倉庫和標簽則被取消,成為虛懸鏡像。

我們可以使用下面的語句打印所有的虛懸鏡像:

$?docker?image?ls?-f?dangling=true

一般的虛懸鏡像已經沒有什么作用了,所以可以清理掉的,下面的命令可以清除所有的虛懸鏡像:

$?docker?image?prune

不過,如果我們想保留一些有用的虛擬鏡像時,可以使用docker tag命令重新給鏡像起個倉庫名和標簽:

$?docker?tag?621d57f27e93?"test:1.0"

鏡像導出與導入

如果想與別人共享某個鏡像,除了從鏡像服務倉庫中pull鏡像和把鏡像push到倉庫上去之外,其實我們還可以將本地構建好的鏡像直接導出并保存為文件發送給別人,如下:

$?docker?image?save?/tmp/test_image.tar.gz

而當你拿到別人導出的鏡像文件,你可以使用docker load命令把鏡像加載到本地的Docker鏡像列表中,如下:

$?docker?load?<p><span style="font-size: 18px;"><strong>刪除本地鏡像</strong></span></p><p>要刪除一個或多個本地的鏡像,可以使用下面的命令:<br></p><pre class="brush:js;toolbar:false;">docker?image?rm?[option]?IMAGE1,IMAGE2,...IMAGEn

也可以使用更簡潔的方式,如:

docker?rmi??[option]??IMAGE1,IMAGE2,...IMAGEn

可以使用鏡像的長ID、鏡像短ID、鏡像摘要以及鏡像名稱來刪除鏡像,如下:

$?docker?rmi?f7302e4ab3a8

一般更常用鏡像的短ID,如:

$?docker?rmi?f7302

使用鏡像的摘要也可以刪除鏡像,鏡像的摘要可以使用下面的命令查詢:

$?docker?image?ls?--digests

當然我們想要清除本地全部鏡像時,可以使用下面的命令,不過一般不建議使用。

$?docker?rmi?$(docker?images?-qa)

另外,一般如果鏡像已經被使用來創建容器,使用上面的命令刪除會報下面的錯誤,告訴我們該鏡像已經被使用,不允許刪除。

Error?response?from?daemon:?conflict:?unable?to?remove?repository?reference?"mysql:5.7"?(must?force)?-?container?ccd406c07a78?is?using?its?referenced?image?e1e1680ac726

對于已經被用于創建容器的鏡像,刪除方法有兩種,一種是先把容器刪除,再刪除鏡像,另一種則只需要在刪除鏡像的命令中跟一個-f參數便可,如:

$?docker?rim?-f?f7302

使用docker commit構建鏡像

上面的例子都是直接使用官方提供的鏡像,其實,除了從官方倉庫或其他鏡像倉庫拉取別人構建好的鏡像外,我們也可以構建自己的鏡像,一般有以下兩種構建方式。

使用docker commit命令,我們可以將修改過的容器重新提交為一個鏡像,如:

$?docker?commit?conntaner_id?my-hello:1.0

使用這種方式構建的鏡像,我們稱為黑箱鏡像,就是一個黑箱子一樣,別人并不知道我們對容器做了哪些修改和操作,所以會對其安全性有所質疑。

所以不推薦使用這種方式構建鏡像,下面我們介紹一種更加通用且方便的方式。

使用Dockerfile構建鏡像

一般推薦編寫Dockerfile來構建一種鏡像,Docker Hub上的鏡像都是采用這種方式構建的,采用這種方式的好處就是,我們不用把鏡像分發給別人,而只是把Dockerfile和相應需要寫入鏡像的資料發給別人,別人也能自己構建鏡像,安全透明。

編寫一個簡單的Got程序

package?main import?"fmt"  func?main(){ fmt.Println("Hello?Go") }

將Go程序編譯為可執行程序,如:

$?go?build?hello.go

編寫Dockerfile文件

下面我們編寫一個簡單的Dockerfile文件,構建自己的第一個鏡像,如下:

#?從一個空白的鏡像開始 FROM?stratch ADD?hello?/ #?執行 CMD?/hello

開始構建鏡像

編寫好Dockerfile文件后,需要使用docker build命令進行構建,docker build命令的格式如下:

$?docker?build?[OPTIONS]?PATH?|?URL?|?-
#?注意最后的點(.)表示當前目錄,即Dockerfile所在的目錄 $?docker?build?-t?"hello-go:1.0"?.

上面只是簡單演示了使用Dockerfile文件如何構建鏡像,關于Dockerfile,還有許多更加深入地用法,我們之后有機再談。

容器(Container)

容器與鏡像的關系,就如同面向編程中對象與類之間的關系。

因為容器是通過鏡像來創建的,所以必須先有鏡像才能創建容器,而生成的容器是一個獨立于宿主機的隔離進程,并且有屬于容器自己的網絡和命名空間

我們前面介紹過,鏡像由多個中間層(layer)組成,生成的鏡像是只讀的,但容器卻是可讀可寫的,這是因為容器是在鏡像上面添一層讀寫層(writer/read layer)來實現的,如下圖所示:

docker的核心組件有哪些

操作容器的相關命令

Usage:??docker?container?COMMAND  Manage?containers  Commands: attach??????Attach?local?standard?input,?output,?and?error?streams?to?a?runnin?????????????????????????????????????????????????????????????????????????????????????????????g?container commit??????Create?a?new?image?from?a?container's?changes(把容器保存為鏡像) cp??????????Copy?files/folders?between?a?container?and?the?local?filesystem create??????Create?a?new?container(創建一個新的容器) diff????????Inspect?changes?to?files?or?directories?on?a?container's?filesyste?????????????????????????????????????????????????????????????????????????????????????????????m exec????????Run?a?command?in?a?running?container(在一個運行的容器中執行命令) export??????Export?a?container's?filesystem?as?a?tar?archive inspect?????Display?detailed?information?on?one?or?more?containers kill????????Kill?one?or?more?running?containers(殺死一個或多個正在運行的容器) logs????????Fetch?the?logs?of?a?container ls??????????List?containers(顯示本地容器列表) pause???????Pause?all?processes?within?one?or?more?containers port????????List?port?mappings?or?a?specific?mapping?for?the?container prune???????Remove?all?stopped?containers rename??????Rename?a?container(重命名容器) restart?????Restart?one?or?more?containers(重啟一個或多個容器) rm??????????Remove?one?or?more?containers(刪除一個或多個容器) run?????????Run?a?command?in?a?new?container(運行一個新的容器) start???????Start?one?or?more?stopped?containers stats???????Display?a?live?stream?of?container(s)?resource?usage?statistics stop????????Stop?one?or?more?running?containers(停止一個或多個容器) top?????????Display?the?running?processes?of?a?container unpause?????Unpause?all?processes?within?one?or?more?containers update??????Update?configuration?of?one?or?more?containers wait????????Block?until?one?or?more?containers?stop,?then?print?their?exit?codes

啟動容器

啟動容器有幾種不同的方式,最常用的方法是使用docker run命令可以通過鏡像創建一個容器,如:

#?/bin/bash表示運行容器后要執行的命令 $?docker?run?-it?centos?/bin/bash

docker run命令有一些比較常用的參數,比如容器是一種提供服務的守護進程,那么通常需要開放端口供外部訪問,如:

$?docker?run?-p?80:80?nginx

也可以為容器指定一個名稱,如:

$?docker?run?-p?80:80?--name?webserver?nginx

另外一種則是使用docker start命令重新啟動已經停止運行的容器,如:

#?container_id表示容器的id $?docker?start?container_id

而對于正在運行的容器,也可以通過docker restart命令重新啟動,如:

#?container_id表示容器的id $?docker?restart?container_id

查看本地容器列表

運行容器后,我們可以通過下面的命令查看本地所有容器:

$?docker?container?ls

不過docker container ls也簡潔的寫法:

$?docker?ps

上面命令執行結果如下:

CONTAINER?ID????????IMAGE???????????????COMMAND??????????????????CREATED?????????????STATUS??????????????PORTS???????????????????????????????NAMES f4f184f5ffb9????????redis:latest????????"docker-entrypoint.s…"???6?seconds?ago???????Up?4?seconds????????0.0.0.0:6379-&gt;6379/tcp??????????????myredis f7d970e7d4ce????????mysql:5.7???????????"docker-entrypoint.s…"???7?seconds?ago???????Up?5?seconds????????0.0.0.0:3306-&gt;3306/tcp,?33060/tcp???docker-mysql

上面的命令只會顯示正在運行的容器,如果要顯示全部容器,包含退出執行的,可以加參數-a,如:

$?docker?ps?-a

有時候,我們只想查到容器的ID,可以用下面的命令:

$?docker?ps?-aq

執行結果:

f4f184f5ffb9 f7d970e7d4ce

停止容器

對于已經不需要的容器,可以使用docker stop命令停止其運行,如:

$?docker?stop?container_id1,container_id2...

批量停止容器,如:

$?docker?stop?$(docker?ps?-qa)

容器的三種運行模式

概括而言,Docker容器大體上有三種運行模式,如下:

運行后退出

下面語句創建的容器,在運行后會退出。

$?docker?run?centos?echo?"hellowrold"

常駐內存,就是守護進程的模式

如果容器中運行一個守護進程,則容器會一直處于運行狀態,如:

$?docker?run?-d?-p?80:80?nginx

交互式

我們也可以在運行容器時,直接與容器交互。

$?docker?run?-it?centos?/bin/bash

刪除容器

$?docker?container?rm?container_id

刪除容器的命令也有簡潔的寫法,如下:

$?docker?rm?container_id

也可以像上面批量停止容器一樣,我們也可以批量刪除容器,如:

$?docker?rm?$(docker?ps?-qa)

進入容器

對于正在運行的容器,我們也可以通過docker exec命令再次進入容器,如:

$?docker?exec?-it?f4f184f5ffb9?/bin/bash

需要指定容器的id或name,上面的命令我們用的是ID。

導出容器為鏡像

$?docker?export?-o?./image.tar.gz?f4f184f5ffb9

將容器導出后,我們可以另外一臺有安裝Docker的電腦中將文件包導入成為鏡像,如:

$?docker?import?image.tar.gz

上面講的是容器的概念和一些常用的命令,關于容器,還可以設置數據卷和網絡空間,這些我們有機會后面再談。

倉庫(Repository)

倉庫(Repository)是集中存儲鏡像的地方,這里有個概念要區分一下,那就是倉庫與倉庫服務器(Registry)是兩回事,像我們上面說的Docker Hub,就是Docker官方提供的一個倉庫服務器,不過其實有時候我們不太需要太過區分這兩個概念。

公共倉庫

公共倉庫一般是指Docker Hub,前面我們已經多次介紹如何從Docker Hub獲取鏡像,除了獲取鏡像外,我們也可以將自己構建的鏡像存放到Docker Hub,這樣,別人也可以使用我們構建的鏡像。

不過要將鏡像上傳到Docker Hub,必須先在Docker的官方網站上注冊一個賬號,注冊界面如下,按要求填寫必要的信息就可以注冊了,很簡單的。

docker的核心組件有哪些

注冊好了之后,可以在本地使用命令登錄到Dokcer Hub了,過程如下:

#?在命令行中輸入 $?docker?login

docker的核心組件有哪些

在輸入賬號密碼登錄到Docker Hub之后,便可以使用docker push命令把鏡像推送到Docker Hub。

$?docker?push?test:1.0

私有倉庫

有時候自己部門內部有一些鏡像要共享時,如果直接導出鏡像拿給別人又比較麻煩,使用像Docker Hub這樣的公共倉庫又不是很方便,這時候我們可以自己搭建屬于自己的私有倉庫服務,用于存儲和分布我們的鏡像。

Docker官方提供了registry這個鏡像,可以用于搭建私有倉庫服務,我們把鏡像拉到本地之后,用下面命令創建該鏡像的容器便可以搭建一個倉庫服務,如下:

$?docker?run?-d?-p?5000:5000?--restart=always?--name?registry?registry

假設我們把一臺IP為192.168.0.100的服務器作為倉庫服務,并運行上面的語句,那么我們可以下面的語句重新構建上面的鏡像,如:

$?docker?build?-t?"192.168.0.100/hello-go:1.0"?.

然后使用下面的語句推送到自己的私有倉庫服務器:

$?docker?push?192.168.0.100/hello-word:1.0

小結

鏡像是靜態的概念,構建完成之后便不能再修改,而容器則是一個動態的概念,使用Docker可以簡單輕松地創建或刪除容器,鏡像與容器的關系,就如同面向對象編程中的類與對象的關系,而倉庫則是存儲和分發鏡像的地方。

推薦學習:《docker視頻教程

以上就是

? 版權聲明
THE END
喜歡就支持一下吧
點贊10 分享