摘要:最理想的情況下,我們希望或者變動的時候會重新的安裝包,在沒有變動的情況下使用緩存縮短構建時間。
在使用Docker部署PHP或者node.js應用時,常用的方法是將代碼和環境鏡像打包成一個鏡像然后運行,一些云廠商提供了非常便捷的操作,只需要把我們的代碼提交到VCS上,然后它們就會幫我們拉取代碼并根據代碼包內的Dockerfile構建我們的鏡像然后部署到集群里。
PHP和node.js都有非常不錯的生態,有各種各樣的包,但是一旦引入的包多了我們的項目內的文件就會變得非常多,所以在使用VCS協作的時候我們都會忽略掉依賴包目錄(node_modules / vendor)。但是我們忽略了包目錄后在構建鏡像的時候就要使用composer或者npm把包重新裝回去,所以Dockerfile大概長這樣
FROM node COPY . /src RUN cd /src && npm install
這樣看起來沒什么問題,但是如果包一旦多起來安裝的時候需要花費很長的時間,修復緊急bug的情況下等待的時間就是煎熬,那我們有沒有什么辦法能讓這個過程更快一些呢?
我們知道Docker構建是分層的,一條指令一層,在沒有帶--no-cache=true指令的情況下如果某一層沒有改動,Docker就不會重新構建這一層而是會使用緩存,先來看看Docker官方文檔的描述
Starting with a parent image that is already in the cache, the next instruction is compared against all child images derived from that base image to see if one of them was built using the exact same instruction. If not, the cache is invalidated.
In most cases, simply comparing the instruction in the Dockerfile with one of the child images is sufficient. However, certain instructions require more examination and explanation.
For the ADD and COPY instructions, the contents of the file(s) in the image are examined and a checksum is calculated for each file. The last-modified and last-accessed times of the file(s) are not considered in these checksums. During the cache lookup, the checksum is compared against the checksum in the existing images. If anything has changed in the file(s), such as the contents and metadata, then the cache is invalidated.
簡單來說就是如果第n層有改動,則n層以后的緩存都會失效,大多數情況下判斷有無改動的方法是判斷這層的指令和緩存中的構建指令是否一致,但是對于COPY和ADD命令會計算鏡像內的文件和構建目錄文件的校驗和然后做比較來判斷本層是否有改動。
最理想的情況下,我們希望package.json或者composer.json變動的時候會重新的安裝包,在沒有變動的情況下使用緩存縮短構建時間。
了解上面的規則后我們再來看看上面那個Dockerfile,如果我們不修改任何代碼的話第二次構建也是能使用緩存的,但是如果我們修改了代碼,COPY . /src這層的緩存就會失效,同時下一層的緩存也會失效。但是大多數情況下,重新構建鏡像就意味著代碼有修改,但是package.json和composer.json這兩個文件并不會頻繁的修改,所以我們需要把這兩個文件以及install的操作分離出來,所以有
FROM node COPY package.json /src/package.json RUN cd /src && npm install COPY . /src
在package.json里面寫一個依賴包
{ "dependencies": { "express": "^4.16.4" } }
然后再寫一個index.js
const app = require("express")(); app.listen(8080)
然后我們進行第一次構建,看看docker history的輸出
LIN2UR:~ lin2ur$ docker history demo IMAGE CREATED CREATED BY SIZE COMMENT 3c913c9e997b 6 seconds ago /bin/sh -c #(nop) COPY dir:e3c12f06720cf5f3b… 1.6MB 21373087419a 6 seconds ago /bin/sh -c cd /src && npm install 3MB 64896ee5240d 14 seconds ago /bin/sh -c #(nop) COPY file:87de28b86afd2c1c… 53B
把每一層的IMAGE ID和Dockerfile里面的指令對應起來就是
64896ee5240d => COPY package.json /src/package.json
21373087419a => RUN cd /src && npm install
3c913c9e997b => COPY . /src
現在我們來修改一下index.js模擬我們業務代碼變動然后再進行構建
LIN2UR:~ lin2ur$ docker history demo IMAGE CREATED CREATED BY SIZE COMMENT 5d697905ad0a 6 seconds ago /bin/sh -c #(nop) COPY dir:d698db67dac047bd2… 1.6MB 21373087419a 4 minutes ago /bin/sh -c cd /src && npm install 3MB 64896ee5240d 4 minutes ago /bin/sh -c #(nop) COPY file:87de28b86afd2c1c… 53B
可以看到除了最上一層外其他兩層的IMAGE ID是沒有變化的,再來看看docker build命令的輸出
LIN2UR:~ lin2ur$ docker build --rm -f "Dockerfile" -t demo . Sending build context to Docker daemon 1.902MB Step 1/4 : FROM node ---> c63e58f0a7b2 Step 2/4 : COPY package.json /src/package.json ---> Using cache ---> 64896ee5240d Step 3/4 : RUN cd /src && npm install ---> Using cache ---> 21373087419a Step 4/4 : COPY . /src ---> 5d697905ad0a Successfully built 5d697905ad0a Successfully tagged demo:latest
可以看到步驟2和3都使用了緩存,比第一次構建的時間縮短不少?,F在我們在package.json里面再加一個包模擬依賴包變動
LIN2UR:~ lin2ur$ docker history demo IMAGE CREATED CREATED BY SIZE COMMENT 020ce95b1987 29 seconds ago /bin/sh -c #(nop) COPY dir:ea4d7afd475895520… 1.6MB d9697dfc7022 31 seconds ago /bin/sh -c cd /src && npm install 3MB 71d8a2fb458a 38 seconds ago /bin/sh -c #(nop) COPY file:87bd25345a96e6b3… 51B
這次底下兩層的IMAGE ID都變了,意味著沒有使用緩存,再來看看docker build命令的輸出
LIN2UR:~ lin2ur$ docker build --rm -f "Dockerfile" -t demo . Sending build context to Docker daemon 1.902MB Step 1/4 : FROM node ---> c63e58f0a7b2 Step 2/4 : COPY package.json /src/package.json ---> 71d8a2fb458a Step 3/4 : RUN cd /src && npm install ---> Running in ce424d6af936 Step 4/4 : COPY . /src ---> 020ce95b1987 Successfully built 020ce95b1987 Successfully tagged demo:latest
由于第二層的package.json改動導致這層及后續的緩存失效,然后重新安裝包,實現了我們希望的結果。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/30130.html
摘要:最理想的情況下,我們希望或者變動的時候會重新的安裝包,在沒有變動的情況下使用緩存縮短構建時間。 在使用Docker部署PHP或者node.js應用時,常用的方法是將代碼和環境鏡像打包成一個鏡像然后運行,一些云廠商提供了非常便捷的操作,只需要把我們的代碼提交到VCS上,然后它們就會幫我們拉取代碼并根據代碼包內的Dockerfile構建我們的鏡像然后部署到集群里。 PHP和node.js都...
摘要:本文將介紹精簡容器鏡像的必要性并以基于的應用為例描述最小化容器鏡像的常用技巧。經過這一優化,最終鏡像的大小為。 背景 隨著容器技術的普及,越來越多的應用被容器化。人們使用容器的頻率越來越高,但常常忽略一個基本但又非常重要的問題 - 容器鏡像的體積。本文將介紹精簡容器鏡像的必要性并以基于 spring boot 的 java 應用為例描述最小化容器鏡像的常用技巧。 精簡容器鏡像的必要性 ...
摘要:接下來我們將逐步的減少這個鏡像的體積。優化生產環境鏡像使用鏡像大幅減小鏡像體積的最簡單和最快的方法是選擇一個小得多的基本鏡像。使用多階段構建可以充分利用鏡像的緩存,大大減少最終部署到生產環境的時間。 關注作者github每日一道面試題詳解 你討厭部署你的應用程序花費很長時間嗎? 對于單個容器來說,超過gb并不是最佳實踐。每次部署新版本時都要處理數十億字節,這對我們來說并不太合適。 本文...
摘要:極大地降低了平臺的復雜度,更加方便企業開發人員實現各種業務應用,幫助企業輕松打造基于云計算的軟件基礎設施。本文將從實際案例出發,結合不同的使用場景,為各位介紹的這些特性。是未來數據中心操作系統的核心。 0.前言 隨著 Docker 技術的日漸火熱,本就火爆的云計算行業進入了一個加速階段。云計算最大的特點是彈性和靈活,幫助企業應對復雜的業務需求。由于云計算的IT構架和上一代的IT構架有很...
閱讀 2591·2021-11-18 10:02
閱讀 2627·2021-11-15 11:38
閱讀 3699·2021-11-12 10:36
閱讀 696·2021-11-12 10:34
閱讀 2888·2021-10-21 09:38
閱讀 1479·2021-09-29 09:48
閱讀 1492·2021-09-29 09:34
閱讀 1088·2021-09-22 10:02