您好,登錄后才能下訂單哦!
本篇內容主要講解“怎么寫Dockerfile”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“怎么寫Dockerfile”吧!
一個開發周期包括構建 Docker 鏡像,更改代碼,然后重新構建 Docker 鏡像。在構建鏡像的過程中,如果能夠利用緩存,可以減少不必要的重復構建步驟。
鏡像的構建順序很重要,當你向 Dockerfile 中添加文件,或者修改其中的某一行時,那一部分的緩存就會失效,該緩存的后續步驟都會中斷,需要重新構建。所以優化緩存的最佳方法是把不需要經常更改的行放到最前面,更改最頻繁的行放到最后面。
當拷貝文件到鏡像中時,盡量只拷貝需要的文件,切忌使用 COPY .
指令拷貝整個目錄。如果被拷貝的文件內容發生了更改,緩存就會被破壞。在上面的示例中,鏡像中只需要構建好的 jar 包,因此只需要拷貝這個文件就行了,這樣即使其他不相關的文件發生了更改也不會影響緩存。
每一個 RUN
指令都會被看作是可緩存的執行單元。太多的 RUN 指令會增加鏡像的層數,增大鏡像體積,而將所有的命令都放到同一個 RUN 指令中又會破壞緩存,從而延緩開發周期。當使用包管理器安裝軟件時,一般都會先更新軟件索引信息,然后再安裝軟件。推薦將更新索引和安裝軟件放在同一個 RUN 指令中,這樣可以形成一個可緩存的執行單元,否則你可能會安裝舊的軟件包。
鏡像的體積很重要,因為鏡像越小,部署的速度更快,攻擊范圍越小。
刪除不必要的依賴,不要安裝調試工具。如果實在需要調試工具,可以在容器運行之后再安裝。某些包管理工具(如 apt
)除了安裝用戶指定的包之外,還會安裝推薦的包,這會無緣無故增加鏡像的體積。apt 可以通過添加參數 -–no-install-recommends
來確保不會安裝不需要的依賴項。如果確實需要某些依賴項,請在后面手動添加。
包管理工具會維護自己的緩存,這些緩存會保留在鏡像文件中,推薦的處理方法是在每一個 RUN 指令的末尾刪除緩存。如果你在下一條指令中刪除緩存,不會減小鏡像的體積。
當然了,還有其他更高級的方法可以用來減小鏡像體積,如下文將會介紹的多階段構建。接下來我們將探討如何優化 Dockerfile 的可維護性、安全性和可重復性。
使用官方鏡像可以節省大量的維護時間,因為官方鏡像的所有安裝步驟都使用了最佳實踐。如果你有多個項目,可以共享這些鏡像層,因為他們都可以使用相同的基礎鏡像。
基礎鏡像盡量不要使用 latest
標簽。雖然這很方便,但隨著時間的推移,latest 鏡像可能會發生重大變化。因此在 Dockerfile 中最好指定基礎鏡像的具體標簽。我們使用 openjdk
作為示例,指定標簽為 8。其他更多標簽請查看官方倉庫。
基礎鏡像的標簽風格不同,鏡像體積就會不同。slim
風格的鏡像是基于 Debian 發行版制作的,而 alpine
風格的鏡像是基于體積更小的 Alpine Linux 發行版制作的。其中一個明顯的區別是:Debian 使用的是 GNU 項目所實現的 C 語言標準庫,而 Alpine 使用的是 Musl C 標準庫,它被設計用來替代 GNU C 標準庫(glibc)的替代品,用于嵌入式操作系統和移動設備。因此使用 Alpine 在某些情況下會遇到兼容性問題。 以 openjdk 為例,jre
風格的鏡像只包含 Java 運行時,不包含 SDK
,這么做也可以大大減少鏡像體積。
到目前為止,我們一直都在假設你的 jar 包是在主機上構建的,這還不是理想方案,因為沒有充分利用容器提供的一致性環境。例如,如果你的 Java 應用依賴于某一個特定的操作系統的庫,就可能會出現問題,因為環境不一致(具體取決于構建 jar 包的機器)。
源代碼是你構建 Docker 鏡像的最終來源,Dockerfile 里面只提供了構建步驟。
首先應該確定構建應用所需的所有依賴,本文的示例 Java 應用很簡單,只需要 Maven
和 JDK
,所以基礎鏡像應該選擇官方的體積最小的 maven 鏡像,該鏡像也包含了 JDK。如果你需要安裝更多依賴,可以在 RUN 指令中添加。pom.xml
文件和 src
文件夾需要被復制到鏡像中,因為最后執行 mvn package
命令(-e 參數用來顯示錯誤,-B 參數表示以非交互式的“批處理”模式運行)打包的時候會用到這些依賴文件。
雖然現在我們解決了環境不一致的問題,但還有另外一個問題:**每次代碼更改之后,都要重新獲取一遍 pom.xml 中描述的所有依賴項。**下面我們來解決這個問題。
結合前面提到的緩存機制,我們可以讓獲取依賴項這一步變成可緩存單元,只要 pom.xml 文件的內容沒有變化,無論代碼如何更改,都不會破壞這一層的緩存。上圖中兩個 COPY 指令中間的 RUN 指令用來告訴 Maven 只獲取依賴項。
現在又遇到了一個新問題:跟之前直接拷貝 jar 包相比,鏡像體積變得更大了,因為它包含了很多運行應用時不需要的構建依賴項。
多階段構建可以由多個 FROM 指令識別,每一個 FROM 語句表示一個新的構建階段,階段名稱可以用 AS
參數指定。本例中指定第一階段的名稱為 builder
,它可以被第二階段直接引用。兩個階段環境一致,并且第一階段包含所有構建依賴項。
第二階段是構建最終鏡像的最后階段,它將包括應用運行時的所有必要條件,本例是基于 Alpine 的最小 JRE 鏡像。上一個構建階段雖然會有大量的緩存,但不會出現在第二階段中。為了將構建好的 jar 包添加到最終的鏡像中,可以使用 COPY --from=STAGE_NAME
指令,其中 STAGE_NAME 是上一構建階段的名稱。
多階段構建是刪除構建依賴的首選方案。
到此,相信大家對“怎么寫Dockerfile”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。