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

Docker多階段構建鏡像multi-stage詳解

 更新時間:2025年10月24日 08:48:33   作者:尤達c  
多階段構建是Docker 17.05及以上版本的新特性,允許在一個Dockerfile中使用多個階段,每個階段可以有一個獨立的基礎鏡像,并且可以通過COPY --from命令在階段之間傳遞文件,這樣可以有效地減少最終鏡像的大小,只保留必要的文件

多階段構建是一個新特性,需要 Docker 17.05 或更高版本的守護進程和客戶端。對于那些努力優(yōu)化 Dockerfiles 并使其易于閱讀和維護的人來說,多階段構建非常有用。

在之前先來學習術語:

  • multi-stage 多階段
  • build 構建
  • image 鏡像
  • stage 階段

一、使用在多階段構建之前

構建鏡像時最具挑戰(zhàn)性的事情之一就是縮小鏡像大小。

Dockerfile 中的每一條指令都會在鏡像中添加一個層,在進入下一層之前,您需要記住清除所有不需要的工件。

要編寫一個真正高效的 Dockerfile,傳統(tǒng)上需要使用 shell 技巧和其他邏輯來保持層盡可能小,并確保每一層都有它需要的來自前一層的工件,而沒有其他東西。

實際上,有一個 Dockerfile 用于開發(fā)環(huán)境(包含構建應用程序所需的所有內容,包括編譯工具等),同時有一個精簡的 Dockerfile 用于生產(chǎn)環(huán)境(僅包含應用程序和運行應用程序所需的內容)是非常常見的。這被稱為“建造者模式”。維護兩個 Dockerfiles 并不理想。

這里一個例子,對比一下 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
  1. 很明顯,優(yōu)化后的 Dockerfile 新增了 FROM AS 這個命令,并出現(xiàn)了兩個 FROM。這就是多階段構建。
  2. 請注意,此示例還使用 Bash 操作符 && 將兩個 RUN命令人為壓縮在一起,以避免在鏡像中創(chuàng)建額外的層。這很容易發(fā)生故障,也很難維護。例如,很容易插入另一個命令而忘記使用 \ 字符繼續(xù)行。

二、了解下多階段構建

多階段構建是 Docker 17.05 的新增功能,它可以在一個 Dockerfile 中使用多個 FROM 語句,以創(chuàng)建多個 Stages(階段)。每個階段間獨立(來源請求),可以通過 COPY --from 來獲取其它階段的文件

看看在 Dockerfile 中使用編譯工具構建一個 JAR,并只保留構建完的 JAR 和運行時交給 Image,其它則扔掉應該怎么做:

# 第一階段——編譯
FROM openjdk:8u171-jdk-alpine3.8 as builder # 自帶編譯工具
ADD . /app
WORKDIR /app
RUN ... 省略編譯和清理工作...
 
 
# 現(xiàn)在,JAR 已經(jīng)出爐。JDK 不再需要,所以不能留在鏡像中。
# 所以我們開啟第二階段——運行,并扔掉第一階段的所有文件(包括編譯工具)
# 第二階段——運行
FROM openjdk:8u181-jre-alpine3.8 as environment # 只帶運行時環(huán)境
 
# 目前,編譯工具等上一階段的東西已經(jīng)被我們拋下。目前的鏡像中只有運行時環(huán)境,
# 我們需要把上一階段的結果拿來,其它不要。
COPY --from=0 /final.jar .
 
# 好了,現(xiàn)在鏡像只有必要的運行時和 JAR 了。
ENTRYPOINT java -jar /final.jar

如上就是多階段構建的介紹

三、使用多階段構建

1. 只有最后一個stage才會被納入image中

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

我們來做一個最 simple 的多階段構建例子:

# 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

可以自己構建一下這個 Dockerfile,然后 docker save > docker.tar

看看其中的內容。不出意外應該只有 /demo/hi-2.txt 和 Alpine。

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

2. 復制文件——階段間的橋梁

如果階段間完全隔離,那么多階段就沒有意義——上一個階段的結果會被完全拋棄,并進入全新的下一階段。

我們可以通過 COPY 命令來獲取其它階段的文件。在多階段中使用 COPY 和普通應用完全一致,僅需要添加 –form ` 即可。那么,我們修正上一個例子,使最終鏡像包含兩個階段的產(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
  • 重新構建并保存(Save),你會發(fā)現(xiàn)多了一層 Layer,其中包含 hi-1.txt。
  • 第二個 FROM 指令用 alpine:3.8 鏡像作為基礎,開始一個新的構建階段。
  • COPY --from=0 行只將前一階段的構建工件復制到這個新階段;
  • FROM 指令的第一個整數(shù)從 0 開始,0代表第一階段

3. 階段命名——快速識別

每次使用 stage index 并不是一件很妙的事情。

這時候,可以通過階段命名的方式給它們賦予名字,以方便識別。

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

現(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

重新構建并保存,結果應該同上次相同。

4. 僅構建其中的部分階段——輕松調試

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

仍然沿用上次的 Dockerfile,但使用 --target 參數(shù)進行構建:

$ docker build --target build1 .

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

總結

這就是一些多階段構建的用法

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

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關文章

  • docker部署code-server的方法

    docker部署code-server的方法

    這篇文章主要介紹了docker部署code-server的方法,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-09-09
  • docker的iptables策略詳解和用戶自定義策略的添加方式

    docker的iptables策略詳解和用戶自定義策略的添加方式

    在Docker環(huán)境下,直接修改iptables以允許特定主機訪問指定端口時,需要考慮Docker自身的iptables規(guī)則,Docker通過修改nat表的PREROUTING鏈和filter表的FORWARD鏈來處理外部對Docker容器的訪問,繞過了filter表的INPUT鏈
    2024-10-10
  • 在Kubernetes環(huán)境下使用Docker實現(xiàn)GPU支持的完整方案

    在Kubernetes環(huán)境下使用Docker實現(xiàn)GPU支持的完整方案

    本文將介紹如何在?Kubernetes?環(huán)境下,使用?Docker?容器運行時實現(xiàn)?NVIDIA?GPU?加速支持,包括環(huán)境準備、安裝?nvidia-docker2、K8s?device?plugin?配置等內容,需要的朋友可以參考下
    2025-05-05
  • Docker?Desktop常見的幾種啟動失敗問題解決方法

    Docker?Desktop常見的幾種啟動失敗問題解決方法

    使用Docker Desktop 可以很方便的啟用 Kubernetes,下面這篇文章主要給大家介紹了關于Docker?Desktop常見的幾種啟動失敗問題解決方法的相關資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2022-09-09
  • Docker中鏡像構建文件Dockerfile與相關命令的詳細介紹

    Docker中鏡像構建文件Dockerfile與相關命令的詳細介紹

    這篇文章主要介紹了Docker中鏡像構建文件Dockerfile與相關命令的相關資料,文中介紹的很詳細,相信對大家具有一定的參考價值,有需要的朋友們下面來一起看看吧。
    2017-02-02
  • Docker遠程連接設置的實現(xiàn)示例

    Docker遠程連接設置的實現(xiàn)示例

    本文主要介紹了Docker遠程連接設置的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • 創(chuàng)建Web項目的Docker鏡像實例講解

    創(chuàng)建Web項目的Docker鏡像實例講解

    這篇文章主要介紹了創(chuàng)建Web項目的Docker鏡像實例講解的相關資料,需要的朋友可以參考下
    2016-10-10
  • Docker部署Mysql集群的實現(xiàn)

    Docker部署Mysql集群的實現(xiàn)

    這篇文章主要介紹了Docker部署Mysql集群的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-09-09
  • docker容器通過ping直接運行獲取公網(wǎng)IP操作

    docker容器通過ping直接運行獲取公網(wǎng)IP操作

    這篇文章主要介紹了docker容器通過ping直接運行獲取公網(wǎng)IP操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-11-11
  • Docker?容器健康檢查的指令方式詳解

    Docker?容器健康檢查的指令方式詳解

    這篇文章主要介紹了Docker?容器健康檢查的指令方式詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-11-11

最新評論