天天看點

看完此文,媽媽還會擔心你docker入不了門?

本文在個人技術部落格不同步釋出,詳情可猛戳 亦可掃描螢幕右側二維碼關注個人公衆号,公衆号内有個人聯系方式,等你來撩...

  上周對象突然心血來潮說想養個小寵物,我問想養啥她又說随便,你看着辦!!!這我真的比較難辦啊!但是咱們程式員能有個對象就不錯了,還不趕緊寵着,我隻能照辦咯!

  我去到了一家寵物店,半天也沒有找到合适的目标。正在我猶豫彷徨之時,看到了老闆門口魚缸裡面的金魚遊來遊去還挺順眼!于是我問老闆

  我:老闆,金魚多少錢?

  老闆:加魚缸一起100塊錢不講價!

  我:這...便宜一點咯!

  老闆:小夥子看你骨骼驚奇,定是個養魚的奇才,2塊錢賣給你吧!但是魚缸可不能給你!

  我:那,你幫我打包一條吧,幫我拿個袋子裝着就好了!

  于是我興高采烈的拎着小金魚就回家了,找了個大罐子養着!對象看到我買的小金魚後露出了幸福的笑容~

  第二天早上對象把我從睡夢中搖醒:“嘤嘤嘤,人家的小魚動不了了,你賠~~~ ”。于是我很憤怒的跑去寵物店找老闆索賠!

  我:你們家賣的魚有問題,回去就不行了!

  老闆:不可能,昨天在我們這都活蹦亂跳的!

  我:就是你們家的魚有問題!

  老闆:肯定是你自己買的魚缸有問題!

  我:手持兩把锟斤拷,口中疾呼燙燙燙。

  老闆:腳踏千朵屯屯屯,笑看萬物锘锘锘?

  這一幕,似曾相識!像極了我們在開發中

  測試:xx,你的代碼在生産環境上運作有問題。

  我:不可能,我本地都運作得好好的。

  測試:你自己上生産環境上看。

  我:我不看,我的代碼在本地沒問題,肯定是運維的鍋,你去找運維!

  或許很多開發人員都有過上面的經曆,程式在本地運作都很正常,一上到生産環境就崩了。這是因為程式跟小金魚一樣也會“水土不服”!而導緻程式水土不服的原因一般就是環境和配置的差異!加上現在網際網路高并發、大流量的通路,一個應用往往需要部署到叢集的多台機器上,并且叢集擴容縮容的需求也比較頻繁。如果按照傳統的方式部署,那每一台伺服器上都需要裝各種軟體...然後進行各種配置...我仿佛看到了“工作996,生病ICU”在向運維工程師招手!

  那有沒有一種方案不僅能屏蔽環境的差異,并且還能快速部署呢?既然“水土不服”那我把程式及整個“水土”都打包遷移,就看你服不服。而docker就是這樣的一種讓你服技術!

  昂,上面的對象是我自己new的(* ̄︶ ̄)...

  Docker是什麼呢?百度百科是這樣跟我說的:Docker 是一個開源的應用容器引擎,讓開發者可以打包他們的應用以及依賴包到一個可移植的鏡像中,然後釋出到任何流行的 Linux或Windows 機器上,也可以實作虛拟化。容器是完全使用沙箱機制,互相之間不會有任何接口。

  這段話已經很概括的描述了docker是什麼,docker能幹嘛,docker的基本特性!相信剛開始接觸docker的你跟我也一樣,看了幾遍都很懵逼!沒關系,看完全文再回頭看這段話,或許就有不一樣的體會了!我們先看看docker官方給出的“定妝照”

看完此文,媽媽還會擔心你docker入不了門?

  如果非要我用一句話描述這張圖檔,還在上幼稚園的我會說:“一條可愛的鲸魚背着多個集裝箱,暢遊在大海裡 ”!而現在我會說:“docker是一個運作在作業系統上的軟體,這個軟體上面可以運作多個互相隔離的容器”!不同的表述,同一個意思!這條可愛的鲸魚就是咱們的docker,而大海就是我們的作業系統,多個集裝箱就是在docker上運作的容器!什麼是容器咱們後面會說~

  假如你想漂洋過海來看我,你可以選擇自己造一條船,這樣你就得自己備足很多幹糧,還得準備很多一些其他的必需品才能出發!但是現在有一條鲸魚遊過來對你說,我這裡有很多集裝箱,裡面有你所需要的一切,你選一個适合你的進來就可以了,我會帶你乘風破浪的!

  看到這裡,你是否對docker有個初步的印象了呢?至少知道了:1、docker是什麼?2、為什麼需要docker?

  前面我們說過docker可以實作虛拟化,那docker與我們平時用的虛拟機有什麼差別和聯系呢?在那些年我們還買不起雲伺服器的時候,如果我們想學linux那就得先安裝一個建立虛拟機的軟體,然後在軟體上面建立虛拟機,然後配置設定記憶體、配置設定磁盤、安裝linux作業系統等等一系列的操作,然後等個分把鐘讓虛拟機運作起來~

  為什麼傳統虛拟機啟動會那麼慢呢?因為傳統虛拟機技術是虛拟出一套硬體後,在其上面運作一個完整的作業系統,然後在該系統上面再運作所需要的應用程式,并且虛拟機的資源需要提前配置設定,一旦配置設定這些資源将全部被占用。但是docker容器内的應用程式是直接運作于宿主的核心,容器沒有自己的核心,更加不會對硬體進行虛拟。是以docker容器比傳統的虛拟機更為輕便!但是docker容器技術也是參考虛拟機一步一步的疊代優化過來的!我們來看看官方給出的docker容器和傳統虛拟機的對比圖:

  圖中也能看出來,docker就是一個運作在作業系統上的軟體!以後如果想在windows上面學習Linux,隻需要在本地安裝一個windows版本的docker,然後看完本文的剩下的部分,就能輕輕松松的玩轉linux啦!不過在windows上安裝docker也需要先安裝一個虛拟機~

  前面對docker的基本概念有了個大緻印象,但是到目前為止,可能你對docker的認識還比較空泛,那下面部分我們就從docker的基本組成要素來更深入的走進docker!docker是一個client-server的結構!先看看官網給出的架構圖:

看完此文,媽媽還會擔心你docker入不了門?

  這張圖裡面概括了docker的所有的元素!我們就逐一分析docker用戶端、docker服務、倉庫、鏡像、容器等概念!

  最左邊是docker的用戶端,類似我們操作mysql的工具navcat,隻不過我們這裡的是沒有圖形化界面的指令終端。docker用戶端是使用者與docker服務互動的視窗!我們能看到圖中就是各種操作的指令!

  中間的是docker背景運作的服務,一個稱為docker daemon的守護程序。可以了解為我們mysql的服務,我們的操作指令都是在這部分進行處理!docker deamon監聽着用戶端的請求,并且管理着docker的鏡像、容器、網絡、磁盤(圖中隻列出了鏡像與容器)等對象。同樣,docker的用戶端與服務可以運作在同一機器上,也可以用某台機器上的用戶端遠端連接配接另一台機器上的docker服務,這跟我們的mysql一樣的呢。

  右邊部分是注冊倉庫,在遠古時代做開發的都知道,我們以前需要一個第三方包的時候需要去網上下載下傳對應的jar包,很麻煩不說,還容易下的包是不穩定的版本。有了maven之後,我們隻要在maven配置檔案中引入對應的依賴,就可以直接從遠端倉庫中下載下傳對應版本的jar包了。docker中的倉庫與maven的倉庫是一個概念,可以遠端下載下傳常用的鏡像,也可以push包到遠端倉庫(如圖中的redis、nginx等鏡像),同一個鏡像又可以有多個版本,在docker中稱為tag!

  前面我們有多次提到鏡像和容器,這是docker裡面很核心的兩個概念。那鏡像和容器分别是什麼呢?鏡像和容器的關系是什麼呢?

  鏡像

  官方給出的定義是:docker鏡像是一個隻讀模闆,可以用來建立docker容器。鏡像是一種輕量級的、可執行的獨立軟體包,用來打包軟體運作環境和基于運作環境開發的軟體。它包含運作某個軟體所需要的所有的内容,包括代碼、運作時、庫、環境變量、配置檔案等。我們開發的web應用需要jdk環境、需要tomcat容器、需要linux作業系統,那我們可以把我們所需要的一切都進行打包成一個整體(包括自己開發的web應用+jdk+tomcat+centos/ubuntu+各種配置檔案)。打包後的鏡像在某台機器上能運作,那它就能夠在任何裝有docker的機器上運作。

  任何鏡像的建立會基于其他的父鏡像,也就是說鏡像是一層套一層,比如一個tomcat鏡像,需要運作在centos/ubuntu上,那我們的tomcat鏡像就會基于centos/ubuntu鏡像建立(在後面的操作部分我們可以通過指令檢視),這樣的結構就類似于我們吃的洋蔥,如果你願意一層一層一層地剝開我的心~

看完此文,媽媽還會擔心你docker入不了門?

  容器

  官方給出的定義是:docker的容器是用鏡像建立的運作執行個體,docker可以利用容器獨立運作一個或一組應用。我們可以使用用戶端或者API控制容器的啟動、開始、停止、删除。每個容器之間是互相隔離的。上一步我們建構的鏡像隻是一個靜态的檔案,這個檔案需要運作就需要變為容器,我們可以把容器看做是一個簡易版的linux系統和運作在其中的應用程式!就是前面看到的鲸魚背上的一個一個的集裝箱,每個集裝箱都是獨立的!

  鏡像與容器關系

  上面的概念很抽象,可以了解為容器就是鏡像的一個執行個體,相信大家都寫過類似下面的代碼:

  我們在代碼中定義了一個Dog類,這個類就相當于一個鏡像,可以根據這個類new出很多的執行個體,new出來的執行個體就相當于一個個的容器。鏡像是靜态的檔案,而容器就是有生命的個體!Dog類可以繼承父類Animal,如果不顯式的指定繼承關系,Dog類就預設繼承Object類。同樣上面也說到過docker中的鏡像也有繼承關系,一個鏡像可以繼承其他的鏡像建立,添加新的功能!

  看到這裡的你是不是對docker有了更多的了解了呢?我們再回頭看看百度百科對docker的描述,可能你又會有更深的印象:

  Docker 是一個開源的應用容器引擎,讓開發者可以打包他們的應用以及依賴包到一個可移植的鏡像中,然後釋出到任何流行的 Linux或Windows 機器上,也可以實作虛拟化。容器是完全使用沙箱機制,互相之間不會有任何接口。

  上面說到容器是一個簡易版的linux系統和運作在其中的應用程式,那我們的應用程式産生的資料(比如記錄檔、異常日志、資料)也是在容器内的系統中存放的,預設不會做持久化,我們可以進入到容器中檢視。但是萬一有一天,docker這條鲸魚不滿人類的壓迫,反抗了...老子打爛你的集裝箱!

看完此文,媽媽還會擔心你docker入不了門?

  随着容器的關閉,容器内的資料也會丢失,重新開啟的容器不會加載原來的資料(簡單說就是容器重新啟動又是另外一個執行個體了)。那對容器内的資料需要持久化到主控端上就很有必要了,這就需要了解我們的容器資料卷~

  容器資料卷的設計目的就是做資料的持久化和容器間的資料共享,資料卷完全獨立于容器的生命周期,也就是說就算容器關閉或者删除,資料也不會丢失。簡單點說就将主控端的目錄挂在到容器,應用在容器内的資料可以同步到主控端磁盤上,這樣容器内産生的資料就可以持久化了。關于容器卷的指令我們後面會有操作執行個體!

  上面說了那麼多,下面就到了咱們的實操環節啦!這一節的内容會通過一些常用的指令讓大家更進一步的了解docker,注意!!這裡隻是一些常用的指令來加深了解,而不是指令大全!如果沒有安裝docker的小夥伴可以自己按照官網的文檔進行安裝,本文不會講到這部分的内容!是以我假設你在自己的伺服器上已經裝好了docker!

  1、<code>docker version</code> 檢視docker用戶端和服務的版本。

  2、<code>docker info</code> 檢視docker的基本資訊,如有多少容器、多少鏡像、docker根目錄等等。

  3、<code>docker --help</code> 檢視docker的幫助資訊,這個指令可以檢視所有docker支援的指令~

  這幾個指令非常簡單,有過一點linux基礎的小夥伴應該很容易了解!

  1、<code>docker images</code> 檢視本地主機上所有的鏡像。注意是本地主機的!這裡能看到鏡像的名稱、版本、id、大小等基本資訊,注意這裡的image ID是鏡像的唯一辨別!還可以通過<code>docker images tomcat</code>指定某個具體的鏡像檢視對應資訊。這裡還要注意的是centos的鏡像才200MB的大小,比我們實體機器上裝的centos要小得多的多,這是因為centos的鏡像隻保留了linux核心部分,這也是為什麼docker虛拟化技術比虛拟機運作效率更高的原因!那為什麼tomcat的鏡像這麼大呢?那是因為我們之前說過我們的鏡像就像一個洋蔥一樣,是一層套一層的!tomcat的運作需要基于centos、jdk等等鏡像,tomcat在上層是以體積比較大啦!

  

看完此文,媽媽還會擔心你docker入不了門?

  2、<code>docker rmi</code> 删除本地的鏡像,如下圖所示,可以加上<code>-f</code>參數進行強制删除。這裡的rmi指令跟linux中的删除指令就很像啦,隻是這裡加了一個i代表image!

看完此文,媽媽還會擔心你docker入不了門?

  3、<code>docker search</code> 根據鏡像名稱搜尋遠端倉庫中的鏡像!

看完此文,媽媽還會擔心你docker入不了門?

  4、<code>docker pull</code> 搜尋到某個鏡像之後就可以從遠端拉取鏡像啦,有點類似咱們git中的pull指令,當然對應的還有個docker push的指令。如圖,如果我們沒有指定tag,預設就會拉取latest版本,也可以通過<code>docker pull tomcat:1.7</code>的方式拉取指定版本!注意這裡在拉取鏡像的時候列印出來的資訊有很多,這也是前面說到的鏡像是一層套一層,拉取一個鏡像也是一層一層的拉取!

看完此文,媽媽還會擔心你docker入不了門?

  通過鏡像指令我們就能擷取鏡像、删除鏡像等操作啦!鏡像有了下面自然就需要通過鏡像建立對應的執行個體啦,也就是我們的容器。下面我們以tomcat為例:

  1、<code>docker run [OPTIONS] IMAGE [COMMAND] [ARG...]</code> 可以基于某個鏡像運作一個容器,如果本地有指定的鏡像則使用本地鏡像,如果沒有則從遠端拉取對應的鏡像然後啟動!由于這個指令非常重要,是以下面列出幾個比較重要的參數:

<code>-d</code>:啟動容器,并且背景運作(docker容器背景運作,就必須要有一個前台程序,容器運作的指令如果不是一直挂起的指令,容器啟動後就會自動退出); <code>-i</code>:以互動模式運作容器,通常與<code>-t</code>同時使用; <code>-t</code>:為容器重新配置設定一個僞輸入終端,通常與-i同時使用(容器啟動後進入到容器内部的指令視窗); <code>-P</code>:随機端口映射,容器内部端口随機映射到主機的高端口; <code>-p</code>:指定端口映射,格式為:主機(宿主)端口:容器端口; <code>-v</code>:建立主控端與容器目錄的同步; <code>--name="myTomcat"</code>: 為容器指定一個名稱(如果不指定,則有個随機的名字);
看完此文,媽媽還會擔心你docker入不了門?

  上面我通過指令啟動了一個tomcat的容器,由于使用了 <code>-t</code> 的參數,是以容器啟動後就進入到了容器的内部的指令視窗,列印了很多tomcat啟動的日志。并且使用 <code>-p</code> 參數指定了端口映射,也就是容器内tomcat運作的端口是8080,并且映射到了主控端上的8888端口,這樣我們在外部就可以同過伺服器的ip+8888端口 通路到我們容器内部tomcat部署的服務了。

  前面我們提到過容器内的資料會随着容器的關閉而丢失。那我們就需要有容器資料卷的技術能将容器内的資料持久化到主控端。這裡需要用到 <code>-v</code> 參數!我們看下面的截圖

  這裡第一個要注意的是我們用的 <code>-d</code> 參數,啟動後沒有進入到容器内部,還是在主控端。(可以對比一下與上面 -it 參數的差別)。第二個要注意的是 <code>-v /主控端:/容器内目錄</code> 實作了主控端與容器内指定目錄的資料同步!容器啟動後就可以使用 linux 的 ll 指令檢視主控端上已經同步到了容器内的檔案。第三個要注意的是這裡的同步是雙向的,也就是說在主控端上對檔案的修改也會同步到容器内部!多個不同的容器映射到主控端的同一個目錄,就可以實作不同容器間的資料共享啦!

看完此文,媽媽還會擔心你docker入不了門?

  2、進入到容器後可以通過<code>exit</code>指令退出容器,也可以通過ctrl+P+Q快捷鍵退出容器,這兩種方式的不同之處是<code>exit</code>會退出并且關閉容器,而ctrl+P+Q快捷鍵隻是單純的退出,容器還在運作,并且還能再次進入!

  3、<code>docker ps</code>我們可以通過該指令檢視正在運作的容器的資訊,這裡能看到容器的唯一id,啟動時間等等...這裡跟linux的ps指令類似,是以也可以把容器了解為一個運作在docker上的程序!<code>docker ps -a</code>可以檢視運作中與停止的所有容器。

看完此文,媽媽還會擔心你docker入不了門?

  4、<code>docker attach [OPTIONS] CONTAINER</code>上面說過通過ctrl+P+Q快捷鍵退出容器後容器還在背景運作,那如果想再次進入容器怎麼辦呢?我們就可以通過<code>attach</code>指令+容器的id再次進入容器!

  5、<code>docker exec [OPTIONS] CONTAINER</code>這個指令與attach一樣都可以再次進入背景運作的容器,但是該指令可以不進入容器而在運作的容器中執行指令!比<code>attach</code>更加強大!

  6、<code>docker stop</code> <code>docker kill</code> <code>docker restart</code>這三個指令分别用來停止容器、強制停止容器和重新開機容器,就跟我們在linux上停止、強制停止和重新開機某個程序一樣的啦,這裡就不做示範了!

  7、<code>docker rm</code> 使用這個指令就可以删除某個容器,這裡跟删除鏡像的差別是這裡少了一個 i 啦!需要注意的是通過stop和kill停止的容器還存在于docker中,而使用 rm 指令操作後的容器将不再存在!

  8、<code>docker inspect</code> 檢視容器的詳情(也能檢視鏡像詳情)。

  前面我們對docker以及相關概念、常用指令有了基本的了解,我們也知道了可以從遠端pull一個鏡像,那遠端的鏡像是怎麼來的呢?如果我們想自己建立一個鏡像又該怎麼做呢?

對,Dockerfile!Dockerfile是一個包含使用者能夠建構鏡像的所有指令的文本文檔,它有自己的文法以及指令,docker能夠從dockerfile中讀取指令自動的建構鏡像!

  我們要想編寫自己的Dockerfiler并建構鏡像,那對Dockerfile的文法和指令的了解就是必須的,了解規則才好辦事嘛!

FROM

  <code>FROM &lt;image&gt; [AS &lt;name&gt;]</code>

  <code>FROM &lt;image&gt;[:&lt;tag&gt;] [AS &lt;name&gt;]</code>

  <code>FROM &lt;image&gt;[@&lt;digest&gt;] [AS &lt;name&gt;]</code>

  指定基礎鏡像,目前鏡像是基于哪個鏡像建立的,有點類似java中的類繼承。FROM指令必是Dockerfile檔案中的首條指令。

MAINTAINER

  <code>MAINTAINER &lt;name&gt;</code>

  鏡像維護者的資訊,該指令已經被标記為不推薦使用了。

LABEL

  <code>LABEL &lt;key&gt;=&lt;value&gt; &lt;key&gt;=&lt;value&gt; &lt;key&gt;=&lt;value&gt; ...</code>

  給鏡像添加中繼資料,可以用LABEL指令替換MAINTAINER指令。指定一些作者、郵箱等資訊。

ENV

  <code>ENV &lt;key&gt; &lt;value&gt;</code>

  <code>ENV &lt;key&gt;=&lt;value&gt; ...</code>

  設定環境變量,設定的變量可供後面指令使用。跟java中定義變量差不多的意思!

WORKDIR

  <code>WORKDIR /path/to/workdir</code>

  設定工作目錄,在該指令後的RUN、CMD、ENTRYPOINT, COPY、ADD指令都會在該目錄執行。如果該目錄不存在,則會建立!

RUN

  <code>RUN &lt;command&gt;</code>

  <code>RUN ["executable", "param1", "param2"]</code>

  RUN會在目前鏡像的最上面建立一個新層,并且能執行任何的指令,然後對執行的結果進行送出。送出後的結果鏡像在dockerfile的後續步驟中可以使用。

ADD

  <code>ADD [--chown=&lt;user&gt;:&lt;group&gt;] &lt;src&gt;... &lt;dest&gt;</code>

  <code>ADD [--chown=&lt;user&gt;:&lt;group&gt;] ["&lt;src&gt;",... "&lt;dest&gt;"]</code>

  從主控端拷貝檔案或者檔案夾到鏡像,也可以複制一個網絡檔案!如果拷貝的檔案是一個壓縮包,會自動解壓縮!

COPY

  <code>COPY [--chown=&lt;user&gt;:&lt;group&gt;] &lt;src&gt;... &lt;dest&gt;</code>

  <code>COPY [--chown=&lt;user&gt;:&lt;group&gt;] ["&lt;src&gt;",... "&lt;dest&gt;"]</code>

  從主控端拷貝檔案或者檔案夾到鏡像,不能複制網絡檔案也不會自動解壓縮!

VOLUME

  <code>VOLUME ["/data"]</code>

  VOLUME用于建立挂載點,一般配合run指令的-v參數使用。

EXPOSE

  <code>EXPOSE &lt;port&gt; [&lt;port&gt;/&lt;protocol&gt;...]</code>

  指定容器運作時對外暴露的端口,但是該指定實際上不會釋出該端口,它的功能是鏡像建構者和容器運作者之間的記錄檔案。

  回到容器指令中的run指令部分,run指令有-p和-P兩個參數,如果是-P就是随機端口映射,容器内會随機映射到EXPOSE指定的端口,如果是-p就是指定端口映射,告訴運維人員容器内需要映射的端口号。

CMD

  <code>CMD ["executable","param1","param2"]</code>

  <code>CMD ["param1","param2"]</code>

  <code>CMD command param1 param2</code>

  指定容器啟動時預設運作的指令,在一個Dockerfile檔案中,如果有多個CMD指令,隻有一個最後一個會生效!同樣是可以執行指令,可能你會覺得跟上面的RUN指令很相似,RUN指令是在建構鏡像時候執行的,而CMD指令是在每次容器運作的時候執行的!docker run指令會覆寫CMD的指令!

ENTRYPOINT

  <code>ENTRYPOINT ["executable", "param1", "param2"]</code>

  <code>ENTRYPOINT command param1 param2</code>

  這個指令與CMD指令類似,都是指定啟動容器時要運作的指令,如果指定了ENTRYPOINT,則CMD指定的指令不會執行!在一個Dockerfile檔案中,如果有多個ENTRYPOINT指令,也隻有一個最後一個會生效!不同的是通過<code>docker run command</code>指令會覆寫CMD的指令!執行的指令不會覆寫ENTRYPOINT,docker run指令中指定的任何參數都會被當做參數傳遞給ENTRYPOINT!

RUN、CMD、ENTRYPOINT差別 1、RUN指令是在鏡像建構時運作,而後兩個是在容器啟動時執行! 2、CMD指令設定的指令是容器啟動時預設運作的指令,如果<code>docker run</code>沒有指定任何的指令,并且Dockerfile中沒有指定ENTRYPOINT,那容器啟動的時候就會執行CMD指定的指令!有點類似代碼中的預設參數! 3、如果設定了ENTRYPOINT指令,則優先使用!并且可以通過<code>docker run</code>給該指令設定的指令傳參! 4、CMD有點類似代碼中的預設參數

USER

  <code>USER &lt;user&gt;[:&lt;group&gt;]</code>

  <code>USER &lt;UID&gt;[:&lt;GID&gt;]</code>

  用于指定運作鏡像所使用的使用者。

ARG

  <code>ARG &lt;name&gt;[=&lt;default value&gt;]</code>

  指定在鏡像建構時可傳遞的變量,定義的變量可以通過docker build --build-arg =的方式在建構時設定。

ONBUILD

  <code>ONBUILD [INSTRUCTION]</code>

  當所建構的鏡像被當做其他鏡像的基礎鏡像時,ONBUILD指定的指令會被觸發!

STOPSIGNAL

  <code>STOPSIGNAL signal</code>

  設定當容器停止時所要發送的系統調用信号!

HEALTHCHECK

  <code>HEALTHCHECK [OPTIONS] CMD command</code> (在容器内運作運作指令檢測容器的運作情況)

  <code>HEALTHCHECK NONE</code> (禁止從父鏡像繼承檢查)

  該指令可以告訴Docker怎麼去檢測一個容器的運作狀況!

SHELL

  <code>SHELL ["executable", "parameters"]</code>

  用于設定執行指令所使用的預設的shell類型!該指令在windows作業系統下比較有用,因為windows下通常會有cmd和powershell兩種shell,甚至還有sh。

  Dockerfile執行順序是從上到下,順序執行!每條指令都會建立一個新的鏡像層,并對鏡像進行送出。編寫好Dockerfile檔案後,就需要使用docker build指令對鏡像進行建構了。

  docker build的格式:<code>docker build [OPTIONS] PATH | URL | -</code>

<code>-f</code> :指定要使用的Dockerfile路徑,如果不指定,則在目前工作目錄尋找Dockerfile檔案! <code>-t</code>: 鏡像的名字及标簽,通常 <code>name:tag</code> 或者 <code>name</code> 格式;可以在一次建構中為一個鏡像設定多個标簽。

  例如我們可以<code>docker build -t myApp:1.0.1 .</code>這樣來建構自己的鏡像,注意後面的 <code>.</code> ,用于指定鏡像建構過程中的上下文環境的目錄。如果大家想了解那些官方鏡像的Dockerfile檔案都是怎麼樣寫的,可以上https://hub.docker.com/ 進行搜尋,以tomcat鏡像為例

  能看到tomcat鏡像的父鏡像是openjdk鏡像,我們再搜尋openjdk的Dockerfile檔案

看完此文,媽媽還會擔心你docker入不了門?

  openjdk鏡像的父鏡像又是oraclelinux鏡像,我們再搜尋oraclelinux的Dockerfile檔案

看完此文,媽媽還會擔心你docker入不了門?

  openjdk鏡像的父鏡像是scratch,這是根鏡像,所有的鏡像都會依賴該鏡像,就像我們代碼中所有的對象的父類都是Object!是以能看到tomcat鏡像就是這樣一層一層的建構出來的,這也是為什麼前面通過<code>docker images</code>檢視到的tomcat鏡像為什麼會有四百多兆的原因啦!

  看到這裡的你,是否對docker是什麼?為什麼需要docker?docker鏡像、docker容器的概念是什麼?docker中常用的指令有哪些?Dockerfile有哪些指令?怎麼去建構自己的鏡像?這些問題都能明白了呢?

  最後,推薦極客時間上的一門不錯的架構師課程,走向架構師必備!

    

看完此文,媽媽還會擔心你docker入不了門?