欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

使用Docker多階段構(gòu)建來減小鏡像大小的方法

 更新時(shí)間:2018年12月12日 10:21:41   作者:Yuuta  
這篇文章主要介紹了使用Docker多階段構(gòu)建來減小鏡像大小的方法,適用于需要在 Dockerfile 中構(gòu)建程式,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧

本文講述了如何通過 Docker 的多階段構(gòu)建功能來大幅度減小鏡像大小,適用于需要在 Dockerfile 中構(gòu)建程式(如 javac),且需要另外安裝編譯工具鏈的鏡像。(如 Java)

先來學(xué)習(xí)單詞(本文全部采用中文詞匯,如需查詢外文文檔可對照該詞匯表。理論上個(gè)人不贊成翻譯術(shù)語):

  • multi-stage 多階段
  • build 構(gòu)建
  • image 鏡像
  • stage 階段

再來看一下效果: 原 110M+,現(xiàn) 92M。

對比一下 Dockerfile

優(yōu)化前 Dockerfile:

FROM openjdk:8u171-jdk-alpine3.8

ADD . /app
WORKDIR /app

RUN apk add maven \
  && mvn clean package \
  && apk del maven \
  && mv target/final.jar / \
  && cd / \
  && rm -rf /app \
  && rm -rf /root/.m2

ENTRYPOINT java -jar /final.jar

優(yōu)化后 Dockerfile:

FROM openjdk:8u171-jdk-alpine3.8 as builder

ADD . /app
WORKDIR /app

RUN apk add maven \
  && mvn clean package \
  && apk del maven \
  && mv target/final.jar /

FROM openjdk:8u181-jre-alpine3.8 as environment
WORKDIR /
COPY --from=builder /final.jar .
ENTRYPOINT java -jar /final.jar

很明顯,優(yōu)化后的 Dockerfile 新增了 FROM AS 這個(gè)命令,并出現(xiàn)了兩個(gè) FROM。這就是多階段構(gòu)建。

了解一下多階段構(gòu)建

多階段構(gòu)建是 Docker 17.05 的新增功能,它可以在一個(gè) Dockerfile 中使用多個(gè) FROM 語句,以創(chuàng)建多個(gè) Stages(階段)。每個(gè)階段間獨(dú)立(來源請求),可以通過 COPY --from 來獲取其它階段的文件。我們來打個(gè)比方,把最終鏡像比作一盤菜(炒青椒)。把原料青椒炒完后上桌。

# 對比清單
鏡像 -> 一盤菜
第一個(gè)階段 -> 炒
第二個(gè)階段 -> 上桌

兩個(gè)階段的目標(biāo)是做好(生成)最終的菜(鏡像)。我們要做的是將第一個(gè)階段「炒」出來的食物進(jìn)行「上桌」。我們的目標(biāo)是 做出菜,且 菜盤子(盛菜和中間產(chǎn)物)最輕。

可視化流程如下:

# 做菜流程
... 省略原料
原料 -> [第一個(gè)階段——炒] # 此時(shí)盤子里有炒的工具、炒的結(jié)果和中間產(chǎn)物
# 這時(shí)候開啟第二個(gè)階段,只保留炒的結(jié)果,而不再需要其它。
-> 炒的結(jié)果 -> [開始上桌,只保留結(jié)果] # 把炒出來的青椒拿來(COPY --from),其它不要
-> 最終是一盤菜。

現(xiàn)在應(yīng)該大致理解多階段構(gòu)建的流程了吧。我們把話筒交給 Java,看看在 Dockerfile 中使用編譯工具構(gòu)建一個(gè) JAR,并只保留構(gòu)建完的 JAR 和運(yùn)行時(shí)交給 Image,其它則扔掉應(yīng)該怎么做:

# 第一階段——編譯(炒)
FROM openjdk:8u171-jdk-alpine3.8 as builder # 自帶編譯工具

ADD . /app
WORKDIR /app

RUN ... 省略編譯和清理工作...

# 現(xiàn)在,JAR 已經(jīng)出爐。JDK 不再需要,所以不能留在鏡像中。
# 所以我們開啟第二階段——運(yùn)行(上桌),并扔掉第一階段的所有文件(包括編譯工具)
FROM openjdk:8u181-jre-alpine3.8 as environment # 只帶運(yùn)行時(shí)

# 目前,編譯工具等上一階段的東西已經(jīng)被我們拋下。目前的鏡像中只有運(yùn)行時(shí),我們需要把上一階段(炒)的結(jié)果拿來,其它不要。
COPY --from=0 /final.jar .

# 好了,現(xiàn)在鏡像只有必要的運(yùn)行時(shí)和 JAR 了。
ENTRYPOINT java -jar /final.jar

如上就是多階段構(gòu)建的介紹。

使用多階段構(gòu)建

多階段構(gòu)建的核心命令是 FROM。FORM 對于身經(jīng)百戰(zhàn)的你來說已經(jīng)不用多講了。在多階段構(gòu)建中,每次 FROM 都會開啟一個(gè)新的 Stage(階段),可以看作一個(gè)新的 Image(不夠準(zhǔn)確、來源請求),與其它階段隔離(甚至包括環(huán)境變量)。只有最后的 FROM 才會被納入 Image 中。

我們來做一個(gè)最 simple 的多階段構(gòu)建例子:

# Stage 1
FROM alpine:3.8
WORKDIR /demo
RUN echo "Hello, stage 1" > /demo/hi-1.txt

# Stage 2
FROM alpine:3.8
WORKDIR /demo
RUN echo "Hello, stage 2" > /demo/hi-2.txt

可以自己構(gòu)建一下這個(gè) Dockerfile,然后 docker save <tag> > docker.tar 看看其中的內(nèi)容。不出意外應(yīng)該只有 /demo/hi-2.txt 和 Alpine。

在這個(gè) Dockerfile 中,我們創(chuàng)建了兩個(gè)階段。第一個(gè)階段創(chuàng)建 hi-1.txt,第二個(gè)階段創(chuàng)建 hi-2.txt,且第二個(gè)階段會被加入最終 Image,其它不會。

復(fù)制文件——階段間的橋梁

如果階段間完全隔離,那么多階段就沒有意義——上一個(gè)階段的結(jié)果會被完全拋棄,并進(jìn)入全新的下一階段。

我們可以通過 COPY 命令來獲取其它階段的文件。在多階段中使用 COPY 和普通應(yīng)用完全一致,僅需要添加 –form ` 即可。那么,我們修正上一個(gè)例子,使最終鏡像包含兩個(gè)階段的產(chǎn)物:

# Stage 1
FROM alpine:3.8
WORKDIR /demo
RUN echo "Hello, stage 1" > /demo/hi-1.txt

# Stage 2
FROM alpine:3.8
WORKDIR /demo
COPY --from=0 /demo/hi-1.txt /demo
RUN echo "Hello, stage 2" > /demo/hi-2.txt

重新構(gòu)建并保存(Save),你會發(fā)現(xiàn)多了一層 Layer,其中包含 hi-1.txt。

階段命名——快速識別

對于只有七秒記憶的我們來說,每次使用 stage index 并不是一件很妙的事情。這時(shí)候,可以通過階段命名的方式給它們賦予名字,以方便識別。

為階段添加名字很簡單,只需要在 FROM 后加上 as <name> 即可。

現(xiàn)在,我們更新 Dockerfile,給予階段名稱并使用名稱來 COPY。

# Stage 1, it's name is "build1"
FROM alpine:3.8 as build1
WORKDIR /demo
RUN echo "Hello, stage 1" > /demo/hi-1.txt

# Stage 2, it's name is "build2"
FROM alpine:3.8 as build2
WORKDIR /demo
# No longer use indexes
COPY --from=build1 /demo/hi-1.txt /demo
RUN echo "Hello, stage 2" > /demo/hi-2.txt

重新構(gòu)建并保存,結(jié)果應(yīng)該同上次相同。

僅構(gòu)建部分階段——輕松調(diào)試

Docker 還為我們提供了一個(gè)很方便的調(diào)試方式——僅構(gòu)建部分階段。它可以使構(gòu)建停在某個(gè)階段,并不構(gòu)建后面的階段。這可以方便我們調(diào)試;區(qū)分生產(chǎn)、開發(fā)和測試。

仍然沿用上次的 Dockerfile,但使用 --target <stage> 參數(shù)進(jìn)行構(gòu)建:

$ docker build --target build1 .

再次 Save,你會發(fā)現(xiàn)只有 build1 的內(nèi)容。

總結(jié)

這就是多階段構(gòu)建的全部用法了。我們再回到開篇的兩個(gè) Dockerfile 對比,你能發(fā)現(xiàn)優(yōu)化前的鏡像胖在哪里了嗎?

很顯然,它包含了無用的 JDK,JDK 只在編譯時(shí)起作用,編譯完便無用了,只需要 JRE 即可。所以,利用多階段構(gòu)建可以隔離編譯階段和運(yùn)行階段,以達(dá)到鏡像最優(yōu)化。

參考文獻(xiàn)

https://docs.docker.com/develop/develop-images/multistage-build/#name-your-build-stages

https://yeasy.gitbooks.io/docker_practice/image/multistage-builds.html

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Docker的安裝與配置命令代碼實(shí)例

    Docker的安裝與配置命令代碼實(shí)例

    這篇文章主要介紹了Docker的安裝與配置命令代碼實(shí)例,這是docker的基礎(chǔ)知識點(diǎn),有正在學(xué)習(xí)docker的同學(xué)可以研究下
    2021-03-03
  • 如何使用docker部署前端應(yīng)用的方法步驟

    如何使用docker部署前端應(yīng)用的方法步驟

    這篇文章主要介紹了如何使用docker部署前端應(yīng)用的方法步驟,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2019-03-03
  • Dockerfile建立一個(gè)自定義的鏡像執(zhí)行自定義進(jìn)程詳細(xì)過程

    Dockerfile建立一個(gè)自定義的鏡像執(zhí)行自定義進(jìn)程詳細(xì)過程

    這篇文章主要介紹了Dockerfile建立一個(gè)自定義的鏡像執(zhí)行自定義進(jìn)程,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-12-12
  • 使用Docker搭建MySQL數(shù)據(jù)庫服務(wù)的方法詳解

    使用Docker搭建MySQL數(shù)據(jù)庫服務(wù)的方法詳解

    在現(xiàn)代應(yīng)用程序開發(fā)中,使用數(shù)據(jù)庫是必不可少的,文將介紹如何使用Docker搭建MySQL數(shù)據(jù)庫服務(wù),讓你在本地環(huán)境中快速部署一個(gè)MySQL實(shí)例,感興趣的可以了解下
    2024-03-03
  • docker 容器添加指定網(wǎng)絡(luò)地址的方法實(shí)現(xiàn)

    docker 容器添加指定網(wǎng)絡(luò)地址的方法實(shí)現(xiàn)

    Docker容器運(yùn)行的時(shí)候默認(rèn)會自動分配一個(gè)默認(rèn)網(wǎng)橋所在網(wǎng)段的IP地址,本文主要介紹了docker容器添加指定網(wǎng)絡(luò)地址的方法實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-01-01
  • docker倉庫登錄及配置insecure-registries的方法

    docker倉庫登錄及配置insecure-registries的方法

    這篇文章主要介紹了docker倉庫登錄配置insecure-registries的方法,docker客戶端如果配置中添加了insecure-registary配置,就不需要在docker 客戶端配置上對應(yīng)證書,如果不配置要在/etc/docker/certs.d/目錄中添加對應(yīng)證書才能正常登錄,感興趣的朋友跟隨小編一起看看吧
    2022-07-07
  • 詳解Docker Swarm概念與用法

    詳解Docker Swarm概念與用法

    這篇文章主要介紹了Docker Swarm概念與用法,幫助大家更好的理解和使用docker容器,感興趣的朋友可以了解下
    2020-09-09
  • Docker修改容器內(nèi)部文件的3種簡單方法

    Docker修改容器內(nèi)部文件的3種簡單方法

    docker容器化技術(shù)在打包生產(chǎn)和發(fā)布中占據(jù)著更高的地位,其高效簡便很有亮點(diǎn),下面這篇文章主要給大家介紹了關(guān)于Docker修改容器內(nèi)部文件的3種簡單方法,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-05-05
  • docker鏡像的導(dǎo)入和導(dǎo)出的實(shí)現(xiàn)

    docker鏡像的導(dǎo)入和導(dǎo)出的實(shí)現(xiàn)

    這篇文章主要介紹了docker鏡像的導(dǎo)入和導(dǎo)出的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-01-01
  • 帶你快速了解Docker和k8s的使用及說明

    帶你快速了解Docker和k8s的使用及說明

    這篇文章主要介紹了帶你快速了解Docker和k8s的使用及說明,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-05-05

最新評論