第一口docker的感覺——初識(shí)docker相見恨晚

前言

前一陣的工作,大多數(shù)是與部署相關(guān)的,通過將項(xiàng)目打包,然后利用docker,部署在AWS上去。就在這一段時(shí)間里面我便對(duì)docker產(chǎn)生了濃厚的興趣,這也就激發(fā)我去深入研究的一個(gè)動(dòng)力。那么下面開始我們的docker之旅。

什么是docker

我們可以首先通過以下網(wǎng)址對(duì)docker有一個(gè)認(rèn)識(shí):docker的講解。簡(jiǎn)單來說docker可以讓我們的部署變得更加簡(jiǎn)潔。(這里我就不做那么更詳細(xì)的解釋了,因?yàn)槲矣X得它總結(jié)的要比我總結(jié)好的多。)

為什么用docker

在沒出現(xiàn)docker的時(shí)候,我們完成的java web項(xiàng)目需要打成一個(gè)war。然后得在服務(wù)器中配置各種各樣的參數(shù),例如說jdk,tomcat,數(shù)據(jù)庫等。配置的周期相當(dāng)?shù)娜唠s并且繁瑣。但是現(xiàn)在有了docker,我們不但可以使用一個(gè)空的鏡像,從頭開始構(gòu)建,還可以使用之前各種大牛已經(jīng)build好的鏡像,直接使用。而且在項(xiàng)目需要遷移的時(shí)候,我們只需要在需要部署的地方,直接使用之前項(xiàng)目使用的docker放置好自己的項(xiàng)目即可,方便快捷。

docker的基本概念

docker最重要的三個(gè)概念是:鏡像(image),容器(container),倉庫(repository),在這三個(gè)概念中,鏡像是最重要的概念。

  • 鏡像
    我們可以把鏡像理解為一個(gè)文件系統(tǒng),并且是一個(gè)只讀的文件系統(tǒng)。鏡像是由一層層的只讀層構(gòu)造起來的,但是從使用者的角度來看我們只有一個(gè)鏡像而已。那么問題就來了,鏡像是只讀的,那么我們?cè)谑褂盟倪^程中,如果需要對(duì)它進(jìn)行修改,該怎么辦呢,別著急,這個(gè)就得看我們的容器了。
  • 容器
    容器是鏡像的一個(gè)運(yùn)行實(shí)例,可以不準(zhǔn)確的把鏡像當(dāng)作類,容器當(dāng)作對(duì)象。容器其實(shí)他的結(jié)構(gòu)是與鏡像相類似的,底部也是一層層的只讀層,只不過在最上層會(huì)存在一個(gè)存儲(chǔ)層,我們可以在這一層定制化我們的這個(gè)容器,還可以通過build命令,把容器打包成我們自己需要的鏡像。另外鏡像啟動(dòng)后會(huì)形成一個(gè)容器,容器在計(jì)算機(jī)中是一個(gè)進(jìn)程,但這個(gè)進(jìn)程對(duì)其他進(jìn)程并不可見。
    容器的啟動(dòng)過程:
    檢查鏡像是否在本地存在,如果不存在去遠(yuǎn)程倉庫下載
    ==>利用鏡像創(chuàng)建一個(gè)容器
    ==>啟動(dòng)剛剛創(chuàng)建的容器
    ==>分配一個(gè)文件系統(tǒng)給容器,并且在鏡像層外掛載一個(gè)可讀可寫層
    ==>從宿主主機(jī)的網(wǎng)橋接口中橋接一個(gè)給容器
    ==>從網(wǎng)橋中分一個(gè)ip地址給容器
    ==>執(zhí)行用戶指定的應(yīng)用程序
    ==>執(zhí)行完畢后容器自動(dòng)終止
  • 倉庫
    這個(gè)理解起來就很簡(jiǎn)單了,大家應(yīng)該有使用過git,他是有一個(gè)遠(yuǎn)程的倉庫,這個(gè)倉庫記錄著我們的代碼,和每一次我們提交的記錄。但是在這里,把docker的倉庫比做maven倉庫更加恰當(dāng),就相當(dāng)于我們可以去maven遠(yuǎn)程倉庫取我們需要的依賴,多個(gè)依賴構(gòu)成了我們的整個(gè)項(xiàng)目,這個(gè)思想同樣適用于docker。默認(rèn)情況下,我們都是從docker hub中取得的鏡像(http://registry.hub.docker.com/

使用docker

實(shí)踐是檢驗(yàn)真理最好的方式,我會(huì)在不斷的實(shí)踐中給大家講解docker命令。
本人使用mac,所以所有操作都會(huì)在mac進(jìn)行。如果使用docker的話,強(qiáng)烈不推薦搭建使用windows系統(tǒng),因?yàn)閐ocker對(duì)于windows很不友好,用起來十分不方便,那怎么辦呢,win的同學(xué),可以在電腦上安裝虛擬機(jī),然后安裝一個(gè)linux系統(tǒng)(centos,red hat,ubantu)。
下面給出安裝的鏈接:
Mac:mac安裝docker的方法
Linux:centos安裝docker的方法
在使用docker之前,如果是不熟悉linux命令的,推薦強(qiáng)烈去學(xué)一下,因?yàn)槲易约焊杏X這對(duì)于docker的學(xué)習(xí)是很有幫助的。
安裝好docker,那就開始我們的表演。

1.docker search <鏡像名稱>

當(dāng)我們?cè)趯?duì)docker的鏡像一無所知的時(shí)候,我們可以通過查詢鏡像,看看自己想要的鏡像存不存在。例如說我們這里可以docker search tomcat。


docker search.png

2.docker pull <鏡像名稱>:<鏡像版本>

其實(shí)我們的版本都可以不用填寫,默認(rèn)情況下是latest,也就是去取最新的版本。


docker pull.png

3.docker run -d -p <外部端口>:<內(nèi)部端口> <鏡像名稱>:<鏡像的tag>

打開terminal終端,在終端中輸入:docker run -d -p 8080:8080 tomcat 這里啟動(dòng)一個(gè)tomcat鏡像作為演示。熟悉tomcat的應(yīng)該知道,默認(rèn)的端口號(hào)為8080,所以我這里使用了默認(rèn)端口。這里解釋一下外部/內(nèi)部端口,這個(gè)很容易理解,docker在運(yùn)行的時(shí)候,會(huì)啟動(dòng)一個(gè)tomcat,這個(gè)tomcat的端口為8080。外部端口指的就是宿主電腦的端口。就是我們可以通過我們的電腦訪問的端口。

  • -d <指的是后臺(tái)運(yùn)行容器>
  • -p <指的是指定端口>
  • --link <連接的容器名稱>:<連接的別名>
    可以使容器和容器之間相互連接
  • -v <掛載到容器的目錄>
  • --volumes-from <可以掛載的數(shù)據(jù)卷容器名稱> (通過啟動(dòng)一個(gè)新容器,使用 -v 命令掛載一個(gè)目錄,然后通過這個(gè)命令把容器掛載到數(shù)據(jù)卷容器上,可以多個(gè)容器掛載同一個(gè)數(shù)據(jù)卷容器上,而且數(shù)據(jù)卷容器本身可以不是啟動(dòng)的狀態(tài)。)
  • -v <本地已有的目錄>(這個(gè)路徑必須是絕對(duì)路徑):<容器的目錄>。如下,我自己創(chuàng)建了一個(gè)宿主機(jī)與容器中的文件夾映射,然后創(chuàng)建了一個(gè)文件,宿主機(jī)相應(yīng)的也產(chǎn)生了文件。


    docker run -v.png

    local file.png

    (Tips:其實(shí)我們本可以不使用pull進(jìn)行下載鏡像,因?yàn)閐ocker鏡像在啟動(dòng)的時(shí)候,如果放下這個(gè)鏡像不存在,那么自己會(huì)去下載鏡像。)如果想的話,可以添加上 -- name 作為這個(gè)啟動(dòng)容器的名稱,如果我們不定義名稱,可以通過容器的id操縱這個(gè)容器。并且docker run 是一個(gè)組合命令,實(shí)際上組合的是 create+start


    docker run.png

4.docker create --name <容器名稱> <鏡像名稱>:<鏡像tag>

5.docker start <容器的id>

這里把create 以及start一起講一下,create命令就是在鏡像的只讀層的最上面加上一個(gè)存儲(chǔ)的可讀可寫層。上面的 -d 與 -p 的option 都是create命令的,創(chuàng)建一個(gè)容器可配的option相當(dāng)?shù)亩?,這里就不詳細(xì)說明了。create命令后,容器是處于stop狀態(tài)的,得需要start命令啟動(dòng)。start命令則是給容器分配一個(gè)進(jìn)程,然后啟動(dòng)起來。

6.docker images

查看本地已經(jīng)有的docker鏡像。
通過 docker images - -format [.ID]:[.Repository]指定顯示鏡像id以及名稱


docker image.png

7.docker rmi <容器名稱>:<容器tag>

移除已經(jīng)存在的指定的容器。


docker rmi.png

8.docker ps -a

查看所有的容器。
當(dāng)把-a換成-qa的時(shí)候就是查看所有容器的id。


docker ps -a.png

9.docker exec -it <容器Id> /bin/bash

進(jìn)入docker 容器 docker exec -it(后面可以接上容器id或者容器名稱) /bin/bash

  • -it 是 -i以及-t。
  • -i是保持標(biāo)準(zhǔn)輸入打開
  • -t是表示分配一個(gè)偽終端。


    docker exec.png

10.docker tag <已有鏡像名>:<已有鏡像版本> <新鏡像名>:<新鏡像版本>

我們可以使用docker tag tomcat:latest mytomcat:latest。這樣就會(huì)新生成一個(gè)鏡像名字叫做mytomcat,版本為latest,只有別名不同而已,但是同樣指向了同一個(gè)鏡像。

11.docker inspect <鏡像名稱>:<鏡像版本>

顯示鏡像的詳細(xì)信息,包括制作者,適應(yīng)框架,各層的數(shù)字摘要。

12.docker history <鏡像名稱>:<鏡像版本>

前面已經(jīng)說過,既然鏡像是一層一層構(gòu)成的,那么我們肯定可以看到,各層的記錄,使用此命令,可以看出鏡像發(fā)生的變化。過長(zhǎng)的信息會(huì)被自動(dòng)攔截我們可以使用 --no-trunc顯示信息完整的信息。

13.docker commit <進(jìn)程號(hào)>/<容器名稱> <鏡像名稱>:<版本號(hào)>

基于現(xiàn)有鏡像,形成自己的鏡像 。原理就是在原有的鏡像基礎(chǔ)上增加自己修改過的存儲(chǔ)層,疊加為一個(gè)新的鏡像,保存下來。成功后,會(huì)返回一個(gè) sha256的碼作為鏡像的唯一標(biāo)實(shí)。
形成新的自己的鏡像,一共有三個(gè)方法:

  • 通過 commit 命令
  • 通過模版進(jìn)行構(gòu)建
    我們可以通過openVZ為我們提供的模板進(jìn)行創(chuàng)建,也可以通過自己導(dǎo)出的模板進(jìn)行創(chuàng)建,openvz網(wǎng)址 openvz模板下載地址。
    我們以u(píng)bantu的模板為例。命令為cat ubuntu-x86_64-minimal.tar.gz | docker import ubuntu:14.04。執(zhí)行完以上命令,就可以通過docker images 看到我們的鏡像了。
  • 通過Dockerfile文件進(jìn)行構(gòu)建。
    但是docker commit 需要慎用,因?yàn)榫唧w做了什么修改任何人都是看到的,完全就是一個(gè)黑盒操作。而且進(jìn)行的刪除操作,并不是真正意義上的刪除,每一次的修改都是在上一次的基礎(chǔ)上,這使得 鏡像越來越臃腫。如果我們想要定制我們的docker鏡像可以使用dockerfile

13.docker save -o 導(dǎo)出的鏡像名稱(后綴為.tar) <鏡像名稱>:<鏡像的版本>

14.docker load --input 導(dǎo)出的鏡像名稱(后綴為.tar)

15.docker export -o 導(dǎo)出的鏡像名稱(后綴為.tar) <容器Id>

16.docker import 導(dǎo)出的鏡像名稱(后綴為.tar) <鏡像名稱>:<鏡像的版本>

前兩個(gè)命令是搭配在一起的,我們通過save命令,把鏡像打包成tar文件的形式,這就可以分享給別人進(jìn)行使用,然后其他人可以通過 load 命令將 導(dǎo)出的文件,保存到本地。
后兩個(gè)命令也是搭配起來的將正在運(yùn)行的容器,打包成一個(gè)tar文件。然后把tar文件import進(jìn)來,形成一個(gè)鏡像。
我們可以看出load和import命令十分相似,那他們的區(qū)別在哪呢?

  • load 命令導(dǎo)入鏡像存儲(chǔ)文件到本地鏡像庫
  • import 導(dǎo)入一個(gè)容器快照到本地鏡像庫
    容器快照文件將丟棄所有的歷史記錄以及元數(shù)據(jù)信息,僅保留快照時(shí)的狀態(tài)
    鏡像存儲(chǔ)文件保持完整記錄,相對(duì)的體積也會(huì)更大。
    在我動(dòng)手實(shí)踐的時(shí)候也明顯感覺到了,使用export要比save的速度快的多。


    docker save load.png

    這里的 load的時(shí)候犯了一個(gè)錯(cuò)誤,在后面跟上了鏡像的名稱與版本,其實(shí)是并不需要的,切記下次不會(huì)再加了。


    docker import export.png

17.docker stop <容器的ID>

停止正在運(yùn)行的容器實(shí)例。

18.docker rm <容器的ID>

在刪除一個(gè)容器實(shí)例之前,應(yīng)該先要將容器停止。
主要支持的選項(xiàng):

  • -f , --force = false 強(qiáng)制刪除一個(gè)正在運(yùn)行的容器
  • -l , --link=false 刪除容器的連接,但是保存容器
  • -v , --volumes=false 刪除容器掛載的數(shù)據(jù)卷

19.docker restart <容器的ID>

重新啟動(dòng)容器,將容器先停止,后啟動(dòng)。

20.docker build -t <生成鏡像的名稱>:<鏡像的版本> <Dockerfile的位置>

這是三種創(chuàng)建自己鏡像的方法之一,也是最好的一種方法,很多時(shí)候我們看到Dockerfile的位置上為".",表示的是當(dāng)前目錄,說明我們cmd和我們的Dockerfile在同一目錄下。

21.docker container prune

清理掉所有已經(jīng)停止的容器,在容器失敗停止后,做集體的清理特別方便。

后續(xù)

在下一篇文章,我會(huì)繼續(xù)整理有關(guān)Dockerfile的編寫,以及其他相關(guān)的內(nèi)容。我希望這樣的總結(jié),可以給大家?guī)韼椭矊?duì)自己梳理知識(shí)體系有所幫助,謝謝大家
本文參考書籍:《Docker技術(shù)入門與實(shí)戰(zhàn)》

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容