Docker最全教程——從理論到實戰(三)

原文: Docker最全教程——從理論到實戰(三)

往期連接:

http://www.javashuo.com/article/p-zwsmmmid-bm.htmlhtml

http://www.javashuo.com/article/p-ewonxmgb-eq.html前端

 

 

寫在前面

容器是應用走向雲端以後必然的發展趨勢,所以筆者很是樂於和你們分享咱們這段時間對容器的理解、心得和實踐。python

本教程持續編寫了2個星期左右而且一直在完善、補充具體的細節和實踐,預計所有完成須要1到2個月的時間。因爲編寫的過程當中極其費時,而且還須要配合作一些實踐(有些實踐存在一些坑,並且極其費時費事)。所以目前產出的速度已經跟不上發佈的速度了,後續的發佈節奏會放慢,請你們多多理解和多多包含。linux

根據目前和你們的交流,筆者針對你們的狀況進行了一些修改和補充,但願對你們有所幫助。另外,對於熟悉容器服務的你,也能夠參與進來,讓咱們一塊兒打造這個系列教程,咱們但願可以多多交流,多多分享,以幫助更多的人。同時,咱們也但願獲得你們的支持。nginx

前言

內容發出來以後,有部分小夥伴有些疑惑。這裏我特別說明下,Docker for windows 指的是docker官方提供的windows的安裝包,並非指的基於windows鏡像開發。筆者推薦的方式是——在windows上開發和調測,託管到Linux。git

Docker持續開發工做流

Docker改變了開發以及產品交付流程,如下是通常狀況下的Docker應用程序的內部循環的持續開發工做流,本工做流只關注在開發人員的計算機上進行的開發工做,不包括設置環境等初始步驟,由於這些步驟只需進行一次。web

應用程序通常由開發人員本身的服務代碼和附加庫(依賴項)組成,如下是生成 Docker 應用程序時經常使用的基本步驟,具體以下圖所示:redis

在本篇教程中,咱們以開源框架Magicodes.Admin爲例進行講解。docker

Magicodes.Admin,是心萊科技團隊打造的一套高效率、易擴展、基礎設施強大、代碼生成完備、理念和技術先進的敏捷開發框架,同時也是一套分佈式(即將提供微服務架構參考)、跨平臺(linux、Docker容器支持)、多終端(包括Android、IOS、H五、小程序、微信公衆號)支持的統一開發框架和解決方案。框架基於.NET Core 2.一、Angular、Ionic、EF Core、ABP和ASP.NET Zero,並在其基礎上進行了封裝和完善,而且編寫了相關的工具(代碼生成)、組件(雲存儲、支付、微信等等)、生成服務。shell

代碼地址:https://gitee.com/xl_wenqiang/Magicodes.Admin.Core

 

在開始以前,咱們先須要準備好相關環境和代碼。好比:

Git clone git@gitee.com:xl_wenqiang/Magicodes.Admin.Core.git

相關環境以及前期準備你們能夠參閱公衆號」magiccodes「中的教程,這裏就很少贅述了。

 

開發

開發過程其實和傳統開發同樣,也就是說,開發Docker 應用的方式與開發非Docker應用的方式相似。兩者的主要區別在於,開發 Docker 應用程序時,是在本地環境中的Docker容器中部署和測試,該容器能夠是Linux容器或Windows 容器。

 

通常狀況下,咱們搭建好框架代碼以後,就須要針對需求進行開發,以知足業務爲目的,也就是這個開發過程並無什麼改變,這裏咱們假設全部代碼均已就緒,開始下一步。

 

建立Dockerfile

本節內容不少,咱們但願你們可以瞭解和使用好Dockerfile。

關於dockerfile

雖然咱們能夠經過docker commit命令來手動建立鏡像,可是經過Dockerfile文件,能夠幫助咱們自動建立鏡像,而且可以自定義建立過程。本質上,Dockerfile就是由一系列命令和參數構成的腳本,這些命令應用於基礎鏡像並最終建立一個新的鏡像。它簡化了從頭至尾的構建流程並極大的簡化了部署工做。使用dockerfile構建鏡像有如下好處:

  • 像編程同樣構建鏡像,支持分層構建以及緩存;

  • 能夠快速而精確地從新建立鏡像以便於維護和升級;

  • 便於持續集成;

  • 能夠在任何地方快速構建鏡像

 

Dockerfile指令

咱們須要瞭解一些基本的Dockerfile 指令,Dockerfile 指令爲 Docker 引擎提供了建立容器映像所需的步驟。這些指令按順序逐一執行。如下是有關一些基本 Dockerfile 指令的詳細信息。

1.FROM

FROM 指令用於設置在新映像建立過程期間將使用的容器映像。

格式:FROM 

示例:

FROM nginx

FROM microsoft/dotnet:2.1-aspnetcore-runtime

  

2.RUN

RUN 指令指定將要運行並捕獲到新容器映像中的命令。 這些命令包括安裝軟件、建立文件和目錄,以及建立環境配置等。

格式:

RUN ["", "", ""]

RUN

示例:

RUN apt-get update

RUN mkdir -p /usr/src/redis

RUN apt-get update && apt-get install -y libgdiplus

RUN ["apt-get","install","-y","nginx"]

注意:每個指令都會建立一層,並構成新的鏡像。當運行多個指令時,會產生一些很是臃腫、很是多層的鏡像,不只僅增長了構建部署的時間,也很容易出錯。所以,在不少狀況下,咱們能夠合併指令並運行,例如:RUN apt-get update && apt-get install -y libgdiplus。在命令過多時,必定要注意格式,好比換行、縮進、註釋等,會讓維護、排障更爲容易,這是一個比較好的習慣。使用換行符時,可能會遇到一些問題,具體能夠參閱下節的轉義字符。

 

3.COPY

COPY 指令將文件和目錄複製到容器的文件系統。文件和目錄需位於相對於 Dockerfile 的路徑中。

格式:

COPY

若是源或目標包含空格,請將路徑括在方括號和雙引號中。

 

COPY ["", ""]

示例:

COPY . .

COPY nginx.conf /etc/nginx/nginx.conf

COPY . /usr/share/nginx/html

COPY hom* /mydir/

 

4.ADD

ADD 指令與 COPY 指令很是相似,但它包含更多功能。除了將文件從主機複製到容器映像,ADD 指令還可使用 URL 規範從遠程位置複製文件。

格式:

ADD<source> <destination>

示例:

ADD https://www.python.org/ftp/python/3.5.1/python-3.5.1.exe /temp/python-3.5.1.exe

此示例會將 Python for Windows下載到容器映像的 c:\temp 目錄。

 

5.WORKDIR

WORKDIR 指令用於爲其餘 Dockerfile 指令(如 RUN、CMD)設置一個工做目錄,而且還設置用於運行容器映像實例的工做目錄。

格式:

WORKDIR

示例:

WORKDIR /app

 

6.CMD

CMD指令用於設置部署容器映像的實例時要運行的默認命令。例如,若是該容器將承載 NGINX Web 服務器,則 CMD 可能包括用於啓動Web服務器的指令,如 nginx.exe。 若是 Dockerfile 中指定了多個CMD 指令,只會計算最後一個指令。

格式:

CMD ["<executable", "

CMD

示例:

CMD ["c:\\Apache24\\bin\\httpd.exe", "-w"]

CMD c:\\Apache24\\bin\\httpd.exe -w

 

7.ENTRYPOINT

配置容器啓動後執行的命令,而且不可被 docker run 提供的參數覆蓋。每一個 Dockerfile 中只能有一個ENTRYPOINT,當指定多個時,只有最後一個起效。

格式:

ENTRYPOINT ["", ""]

示例:

ENTRYPOINT ["dotnet", "Magicodes.Admin.Web.Host.dll"]

 

8.ENV

ENV命令用於設置環境變量。這些變量以」key=value」的形式存在,並能夠在容器內被腳本或者程序調用。這個機制給在容器中運行應用帶來了極大的便利。

格式:

ENV==...

示例:

ENV VERSION=1.0 DEBUG=on \

NAME="Magicodes"

 

9.EXPOSE

EXPOSE用來指定端口,使容器內的應用能夠經過端口和外界交互。

格式:

EXPOSE

示例:

EXPOSE 80

 

說了這麼多,咱們能夠用下圖來一言以蔽之:

 

轉義字符

在許多狀況下,Dockerfile 指令須要跨多個行;這可經過轉義字符完成。 默認 Dockerfile 轉義字符是反斜槓 \。 因爲反斜槓在 Windows 中也是一個文件路徑分隔符,這可能致使出現問題。

如下示例顯示使用默認轉義字符跨多個行的單個 RUN 指令。

FROM microsoft/windowsservercore

 

RUN powershell.exe -Command \

$ErrorActionPreference = 'Stop'; \

wget https://www.python.org/ftp/python/3.5.1/python-3.5.1.exe -OutFile c:\python-3.5.1.exe ; \

Start-Process c:\python-3.5.1.exe -ArgumentList '/quiet InstallAllUsers=1 PrependPath=1' -Wait ; \

Remove-Item c:\python-3.5.1.exe -Force

 

要修改轉義字符,必須在 Dockerfile 最開始的行上放置一個轉義分析程序指令。 如如下示例所示:

# escape=`

 

FROM microsoft/windowsservercore

 

RUN powershell.exe -Command `

$ErrorActionPreference = 'Stop'; `

wget https://www.python.org/ftp/python/3.5.1/python-3.5.1.exe -OutFile c:\python-3.5.1.exe ; `

Start-Process c:\python-3.5.1.exe -ArgumentList '/quiet InstallAllUsers=1 PrependPath=1' -Wait ; `

Remove-Item c:\python-3.5.1.exe -Force

注意,只有兩個值可用做轉義字符:\ 和 ` 。

 

優化

篇幅有限,咱們這裏只進行簡單講解,後續結合實際案例再進行細說。可是有幾點值得注意的是:

  1. 不能忽視dockerfile的優化,一般狀況下,咱們能夠忽略那些細小的優化,可是咱們須要知道優化的原理,爲何要優化

  2. 不能爲了優化而優化。鏡像的構建過程視業務狀況狀況不一樣,指令就有多到少的區別,在不少狀況下,咱們先要以知足業務目標爲準,而不是鏡像層數。若是須要減小鏡像的層數,咱們必定要選擇合適的基礎鏡像,或者建立符合咱們須要的基礎鏡像。

下面是一些優化的準則:

  • 選擇合適的基礎鏡像

    這點相對最爲重要。爲何這麼說,咱們結合現實社會也能夠看到,在大部分狀況下,一我的一輩子的成就更多的是看出身。不少狀況下,基因和出身決定了你的高度和終點,這點拿到技術層面來講,也是有很大道理的,所以咱們須要選擇合適的父母——一個合適的鏡像。

    一個合適的基礎鏡像是指能知足運行應用所須要的最小的鏡像,理論上是能用小的就不要用大的,能用輕量的就不要用重量級的,能用性能好的就不要用性能差的。這裏有時候還須要考慮那些可以減小咱們構建層數的基礎鏡像。

     

  • 優化指令順序

    Docker會緩存Dockerfile中還沒有更改的全部步驟,可是,若是更改任何指令,將重作其後的全部步驟。也就是指令3有變更,那麼四、五、6就會重作。所以,咱們須要將最不可能產生更改的指令放在前面,按照這個順序來編寫dockerfile指令。這樣,在構建過程當中,就能夠節省不少時間。好比,咱們能夠把WORKDIR、ENV等命令放前面,COPY、ADD放後面。

     

  • 合併指令

    前面其實咱們提到過這點,甚至還特意講到了轉義字符,其實主要是爲此服務。前面咱們說到了,每個指令都會建立一層,並構成新的鏡像。當運行多個指令時,會產生一些很是臃腫、很是多層的鏡像,不只僅增長了構建部署的時間,也很容易出錯。所以,在不少狀況下,咱們能夠合併指令並運行,例如:RUN apt-get update && apt-get install -y libgdiplus。在命令過多時,必定要注意格式,好比換行、縮進、註釋等,會讓維護、排障更爲容易,這是一個比較好的習慣。

     

  • 刪除多餘文件和清理沒用的中間結果

    這點很易於理解,一般來說,體積更小,部署更快!所以在構建過程當中,咱們須要清理那些最終不須要的代碼或文件。好比說,臨時文件、源代碼、緩存等等。

      

  • 使用 .dockerignore

    .dockerignore文件用於忽略那些鏡像構建時非必須的文件,這些文件能夠是開發文檔、日誌、其餘無用的文件。例如:

說了這麼多,其實咱們更多的仍是須要根據命令的實際執行狀況來進行調整。

 

Visual studio和dockerfile

如上所示,要生成自定義鏡像,需爲每一個自定義鏡像提供一個 Dockerfile。不管是從Visual Studio 自動部署,仍是使用 Docker CLI(docker run 和 docker-compose 命令)手動部署,都需爲每一個要部署的容器提供一個 Dockerfile。若是應用程序只包含一個自定義服務,則只須要一個 Dockerfile。若是應用程序包含多個服務(如在微服務體系結構中),則每一個服務都須要一個 Dockerfile。Dockerfile文件須要放在應用程序或服務的根文件夾中。

可是,對於.NET開發人員來講,利用Visual Studio只需單擊幾回鼠標便可完成此任務。以下圖所示:

還可經過在 Visual Studio 中右鍵單擊項目文件,選擇「添加 Docker 項目支持」選項,爲新項目或現有項目啓用 Docker 支持:

對項目(如 ASP.NET Web 應用程序或 Web API 服務)應用此操做後,系統會向含有所需配置的項目添加 Dockerfile。

在更多的狀況下,筆者建議你們選擇下面的菜單——容器業務流程協調程序支持:

由於會向整個解決方案添加 docker-compose.yml 等文件。整個過程,Visual Studio 代爲執行了操做,可是,咱們也須要了解 Dockerfile中的內容,不然遇到問題,會抓蝦,哦,是抓瞎。

啓用了以後,咱們就能夠看到頂部的菜單欄出現了一些便捷操做:

不只支持一鍵啓動,還可以調試!!!這對於大部分開發者來講,簡直是天籟之音哈!

接下來,咱們以Magicodes.Admin爲例。在Magicodes.Admin中,存在多個應用,好比後臺服務和後臺UI,目前框架中已經提供了多個dockerfile的配置,分別在相應的工程目錄之中。

 

.net core後臺服務的dockerfile

文件所在目錄以下所示:

相關指令我在註釋中進行了一一說明,不過,因爲Excel的導出在Linux環境須要libgdiplus庫的支持,以設置字體,所以咱們須要在dockerfile中配置安裝此庫。同時,咱們還推薦使用如下簡化的dockerfile:

其中,包還原、編譯、單元測試運行以及發佈等過程咱們經過腳本進行了實現,所以在Dockerfile中,命令比較簡單幹淨,關鍵是整個過程咱們可以在本地進行更多的自定義——好比執行單元測試並再經過以後才進行部署和推送。固然,使用第一個配置可以讓咱們能夠更好地和線上的CI工具配套使用。

注意:這裏咱們並無使用其餘web服務器,咱們直接在代碼中使用了Kestrel服務器進行託管。

 

 

後臺前端應用的dockerfile

文件所在目錄以下所示:

後臺前端應用使用nginx web服務器進行託管,同時執行了copy命令複製相關配置、靜態文件和ssl證書。其中nginx.conf的配置以下所示:

關於dockerfile的相關內容,咱們先講述到這裏,但願你們對此有個全面的瞭解。若是你有疑問或者建議,歡迎討論交流。

往期連接:

http://www.javashuo.com/article/p-zwsmmmid-bm.html

http://www.javashuo.com/article/p-ewonxmgb-eq.html

相關文章
相關標籤/搜索