Docker知識
- 一個layer是一個改變,每個命令(RUN, COPY,)都會產生一個新的layer。
- 每個layer都有一個ID,Image之間可以複用相同的layer。
- 當更新時,若有layer不發生變化,不需要重新上傳到registry
- docker history可以查看每個步驟產生的Layer大小。
優化案列
本文使用的image是基於python base image,安裝一些必要軟件後,提供Python的運行環境。
優化前的dockerfile
前面都是些安裝軟件,優化前最後的幾個步驟爲:
COPY . ${API_DIR}
RUN rm -rf ${API_DIR}/venv/
RUN set -x && \
source ${API_ENV_DIR}/bin/activate && pip install --upgrade --force-reinstall -r ${API_DIR}/requirements.txt
產生的問題:
每次更新一次源碼,image會有500MB的變化,非常大,影響Image更新。
優化原則
- 經常變化的內容(如源碼)儘量放到Dockerfile最後一步
優化步驟
- 去掉不必要的venv目錄,減少文件夾大小。
- 把安裝依賴庫提到複製源碼之前,這樣如果依賴庫不變,此layer就不會發生變化。
- 將複製源碼放到最後一步,這樣每次源碼發生變化,只有最後一個layer變化。
調整後的dockerfile:
# requirments install before source data, this can save image layer
COPY requirements.txt ${API_DIR}/
RUN set -x && \
source ${API_ENV_DIR}/bin/activate && pip install --upgrade --force-reinstall -r ${API_DIR}/requirements.txt
COPY . ${API_DIR}
RUN rm -rf ${API_DIR}/venv/
WORKDIR /src/
效果
優化後每次更新源碼需要推送Image更新只有13MB,而優化前是500MB