1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        基于BuildKit優(yōu)化Dockerfile的構建

        共 9668字,需瀏覽 20分鐘

         ·

        2021-05-02 10:11

        Docker通過讀取Dockerfile中的指令自動構建鏡像,Dockerfile是一個文本文件,其中依次包含構建給定鏡像所需的所有命令。

        上面的解釋摘自Docker的官方文檔并總結了Dockerfile的用途。Dockerfile的使用非常重要,因為它是我們的藍圖,是我們添加到Docker鏡像中的層的記錄。

        本文,我們將學習如何利用BuildKit功能,這是Docker v18.09上引入的一組增強功能。集成BuildKit將為我們提供更好的性能,存儲管理和安全性。

        本文目標

        • 減少構建時間;

        • 縮小鏡像尺寸;

        • 獲得可維護性;

        • 獲得可重復性;

        • 了解多階段Dockerfile;

        • 了解BuildKit功能。

        先決條件

        • Docker概念知識

        • 已安裝Docker(當前使用v19.03)

        • 一個Java應用程序(在本文中,我使用了一個Jenkins Maven示例應用程序)

        讓我們開始吧!

        簡單的Dockerfile示例

        以下是一個包含Java應用程序的未優(yōu)化Dockerfile的示例。我們將逐步進行一些優(yōu)化。

        FROM debian
        COPY . /app
        RUN apt-get update
        RUN apt-get -y install openjdk-11-jdk ssh emacs
        CMD [“java”, “-jar”, “/app/target/my-app-1.0-SNAPSHOT.jar”]

        在這里,我們可能會問自己:構建需要多長時間?為了回答這個問題,讓我們在本地開發(fā)環(huán)境上創(chuàng)建該Dockerfile,并讓Docker構建鏡像。

        # enter your Java app folder
        cd simple-java-maven-app-master
        # create a Dockerfile
        vim Dockerfile
        # write content, save and exit
        docker pull debian:latest # pull the source image
        time docker build --no-cache -t docker-class . # overwrite previous layers
        # notice the build time
        0,21s user 0,23s system 0% cpu 1:55,17 total

        此時,我們的構建需要1m55s。

        如果我們僅啟用BuildKit而沒有其他更改,會有什么不同嗎?

        啟用BuildKit

        BuildKit可以通過兩種方法啟用:

        在調(diào)用Docker build命令時設置DOCKER_BUILDKIT = 1環(huán)境變量,例如:

        time DOCKER_BUILDKIT=1 docker build --no-cache -t docker-class

        將Docker BuildKit設置為默認開啟,需要在/etc/docker/daemon.json進行如下設置,然后重啟:

        "features": { "buildkit"true } }

        BuildKit最初的效果

        DOCKER_BUILDKIT=1 docker build --no-cache -t docker-class .
        0,54s user 0,93s system 1% cpu 1:43,00 total

        此時,我們的構建需要1m43s。在相同的硬件上,構建花費的時間比以前少了約12秒。這意味著構建幾乎無需費力即可節(jié)約10%左右的時間。

        現(xiàn)在讓我們看看是否可以采取一些額外的步驟來進一步改善。

        從最小到最頻繁變化的順序

        因為順序?qū)τ诰彺婧苤匾?,所以我們將COPY命令移到更靠近Dockerfile末尾的位置。

        FROM debian
        RUN apt-get update
        RUN apt-get -y install openjdk-11-jdk ssh emacs
        RUN COPY . /app
        CMD [“java”, “-jar”, “/app/target/my-app-1.0-SNAPSHOT.jar”]

        避免使用“COPY .”

        選擇更具體的COPY參數(shù),以避免緩存中斷。僅復制所需內(nèi)容。

        FROM debian
        RUN apt-get update
        RUN apt-get -y install openjdk-11-jdk ssh vim
        COPY target/my-app-1.0-SNAPSHOT.jar /app
        CMD [“java”, “-jar”, “/app/my-app-1.0-SNAPSHOT.jar”]

        apt-get update 和install命令一起使用

        這樣可以防止使用過時的程序包緩存。

        FROM debian
        RUN apt-get update && \
            apt-get -y install openjdk-11-jdk ssh vim
        COPY target/my-app-1.0-SNAPSHOT.jar /app
        CMD [“java”, “-jar”, “/app/my-app-1.0-SNAPSHOT.jar”]

        刪除不必要的依賴

        在開始時,不要安裝調(diào)試和編輯工具,以后可以在需要時安裝它們。

        FROM debian
        RUN apt-get update && \
            apt-get -y install --no-install-recommends \
            openjdk-11-jdk
        COPY target/my-app-1.0-SNAPSHOT.jar /app
        CMD [“java”, “-jar”, “/app/my-app-1.0-SNAPSHOT.jar”]

        刪除程序包管理器緩存

        你的鏡像不需要此緩存數(shù)據(jù)。借此機會釋放一些空間。

        FROM debian
        RUN apt-get update && \
            apt-get -y install --no-install-recommends \
            openjdk-11-jdk && \
            rm -rf /var/lib/apt/lists/*
        COPY target/my-app-1.0-SNAPSHOT.jar /app
        CMD [“java”, “-jar”, “/app/my-app-1.0-SNAPSHOT.jar”]

        盡可能使用官方鏡像

        使用官方鏡像有很多理由,例如減少鏡像維護時間和減小鏡像尺寸,以及預先配置鏡像以供容器使用。

        FROM openjdk
        COPY target/my-app-1.0-SNAPSHOT.jar /app
        CMD [“java”, “-jar”, “/app/my-app-1.0-SNAPSHOT.jar”]

        使用特定標簽

        請勿使用latest標簽。

        FROM openjdk:8
        COPY target/my-app-1.0-SNAPSHOT.jar /app
        CMD [“java”, “-jar”, “/app/my-app-1.0-SNAPSHOT.jar”]

        尋找最小的鏡像

        以下是openjdk鏡像列表。選擇最適合自己的最輕的那個鏡像。

        REPOSITORY TAG標簽 SIZE大小
        openjdk 8 634MB
        openjdk 8-jre 443MB
        openjdk 8-jre-slim 204MB
        openjdk 8-jre-alpine 83MB

        在一致的環(huán)境中從源構建

        如果你不需要整個JDK,則可以使用Maven Docker鏡像作為構建基礎。

        FROM maven:3.6-jdk-8-alpine
        WORKDIR /app
        COPY pom.xml .
        COPY src ./src
        RUN mvn -e -B package
        CMD [“java”, “-jar”, “/app/my-app-1.0-SNAPSHOT.jar”]

        在單獨的步驟中獲取依賴項

        可以緩存–用于獲取依賴項的Dockerfile命令。緩存此步驟將加快構建速度。

        FROM maven:3.6-jdk-8-alpine
        WORKDIR /app
        COPY pom.xml .
        RUN mvn -e -B dependency:resolve
        COPY src ./src
        RUN mvn -e -B package
        CMD [“java”, “-jar”, “/app/my-app-1.0-SNAPSHOT.jar”]

        多階段構建:刪除構建依賴項

        為什么要使用多階段構建?

        • 將構建與運行時環(huán)境分開

        • DRY方式


          • 具有開發(fā),測試等環(huán)境的不同詳細信息
        • 線性化依賴關系

        • 具有特定于平臺的階段

        FROM maven:3.6-jdk-8-alpine AS builder
        WORKDIR /app
        COPY pom.xml .
        RUN mvn -e -B dependency:resolve
        COPY src ./src
        RUN mvn -e -B package

        FROM openjdk:8-jre-alpine
        COPY --from=builder /app/target/my-app-1.0-SNAPSHOT.jar /
        CMD [“java”, “-jar”, “/my-app-1.0-SNAPSHOT.jar”]

        如果你此時構建我們的應用程序,

        time DOCKER_BUILDKIT=1 docker build --no-cache -t docker-class .
        0,41s user 0,54s system 2% cpu 35,656 total

        你會注意到我們的應用程序構建需要大約35.66秒的時間。這是一個令人愉快的進步。

        下面,我們將介紹其他場景的功能。

        多階段構建:不同的鏡像風格

        下面的Dockerfile顯示了基于Debian和基于Alpine的鏡像的不同階段。

        FROM maven:3.6-jdk-8-alpine AS builder

        FROM openjdk:8-jre-jessie AS release-jessie
        COPY --from=builder /app/target/my-app-1.0-SNAPSHOT.jar /
        CMD [“java”, “-jar”, “/my-app-1.0-SNAPSHOT.jar”]

        FROM openjdk:8-jre-alpine AS release-alpine
        COPY --from=builder /app/target/my-app-1.0-SNAPSHOT.jar /
        CMD [“java”, “-jar”, “/my-app-1.0-SNAPSHOT.jar”]

        要構建特定的鏡像,我們可以使用–target參數(shù):

        time docker build --no-cache --target release-jessie .

        不同的鏡像風格(DRY /全局ARG)

        ARG flavor=alpine
        FROM maven:3.6-jdk-8-alpine AS builder

        FROM openjdk:8-jre-$flavor AS release
        COPY --from=builder /app/target/my-app-1.0-SNAPSHOT.jar /
        CMD [“java”, “-jar”, “/my-app-1.0-SNAPSHOT.jar”]

        ARG命令可以指定要構建的鏡像。在上面的例子中,我們指定alpine為默認的鏡像,但我們也可以在docker build命令中,通過–build-arg flavor=參數(shù)指定鏡像。

        time docker build --no-cache --target release --build-arg flavor=jessie .

        并發(fā)

        并發(fā)在構建Docker鏡像時很重要,因為它會充分利用可用的CPU線程。在線性Dockerfile中,所有階段均按順序執(zhí)行。通過多階段構建,我們可以讓較小的依賴階段準備就緒,以供主階段使用它們。

        BuildKit甚至帶來了另一個性能上的好處。如果在以后的構建中不使用該階段,則在結束時將直接跳過這些階段,而不是對其進行處理和丟棄。

        下面是一個示例Dockerfile,其中網(wǎng)站的資產(chǎn)是在一個assets階段中構建的:

        FROM maven:3.6-jdk-8-alpine AS builder

        FROM tiborvass/whalesay AS assets
        RUN whalesay “Hello DockerCon!” > out/assets.html

        FROM openjdk:8-jre-alpine AS release
        COPY --from=builder /app/my-app-1.0-SNAPSHOT.jar /
        COPY --from=assets /out /assets
        CMD [“java”, “-jar”, “/my-app-1.0-SNAPSHOT.jar”]

        這是另一個Dockerfile,其中分別編譯了C和C ++庫,并在builder以后使用該階段。

        FROM maven:3.6-jdk-8-alpine AS builder-base


        FROM gcc:8-alpine AS builder-someClib

        RUN git clone … ./configure --prefix=/out && make && make install

        FROM g++:8-alpine AS builder-some CPPlib

        RUN git clone … && cmake …

        FROM builder-base AS builder
        COPY --from=builder-someClib /out /
        COPY --from=builder-someCpplib /out /

        BuildKit應用程序緩存

        BuildKit具有程序包管理器緩存的特殊功能。以下是一些緩存文件夾位置的示例:

        包管理器 路徑

        apt /var/lib/apt/lists
        go ~/.cache/go-build
        go-modules $GOPATH/pkg/mod
        npm ~/.npm
        pip ~/.cache/pip

        我們可以將此Dockerfile與上面介紹的在一致的環(huán)境中從源代碼構建中介紹的Dockerfile進行比較。這個較早的Dockerfile沒有特殊的緩存處理。我們可以使用–mount=type=cache來做到這一點。

        FROM maven:3.6-jdk-8-alpine AS builder
        WORKDIR /app
        RUN --mount=target=. --mount=type=cache,target /root/.m2 \
            && mvn package -DoutputDirectory=/

        FROM openjdk:8-jre-alpine
        COPY --from=builder /app/target/my-app-1.0-SNAPSHOT.jar /
        CMD [“java”, “-jar”, “/my-app-1.0-SNAPSHOT.jar”]

        BuildKit的安全功能

        BuildKit具有安全功能,下面的示例中,我們使用了–mount=type=secret隱藏了一些機密文件,例如~/.aws/credentials。

        FROM <baseimage>
        RUN …
        RUN --mount=type=secret,id=aws,target=/root/.aws/credentials,required \
        ./fetch-assets-from-s3.sh
        RUN ./build-scripts.sh

        要構建此Dockerfile,需要使用–secret參數(shù):

        docker build --secret id=aws,src=~/.aws/credentials

        還有為了提高安全性,避免使用諸如COPY ./keys/private.pem /root .ssh/private.pem之類的命令,我們可以使用BuildKit中的ssh解決此問題:

        FROM alpine
        RUN apk add --no-cache openssh-client
        RUN mkdir -p -m 0700 ~/.ssh && ssh-keyscan github.com >> ~/.ssh/known_hosts
        ARG REPO_REF=19ba7bcd9976ef8a9bd086187df19ba7bcd997f2
        RUN --mount=type=ssh,required git clone [email protected]:org/repo /work && cd /work && git checkout -b $REPO_REF

        要構建此Dockerfile,你需要在ssh-agent中加載到你的SSH私鑰。

        eval $(ssh-agent)
        ssh-add ~/.ssh/id_rsa # this is the SSH key default location
        docker build --ssh=default .

        結論

        本文,我們介紹了使用Docker BuildKit優(yōu)化Dockerfile,并因此加快了鏡像構建時間。這些速度的提高,可以幫助我們提高效率和節(jié)省計算能力。

        參考:https://www.kubernetes.org.cn/9059.html
        文章轉(zhuǎn)載:K8S中文社區(qū)
        (版權歸原作者所有,侵刪)

        點擊下方“閱讀原文”查看更多

        瀏覽 111
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            成人片全裸直播在线观看视频 | 国产精品片9区乱婬人成人 | 久久亚洲天堂网 | 老熟女一区二区三区 | 久久久xxx | 国产精品久久久久白丝呻吟 | 全部孕妇毛片丰满孕妇孕交 | 亚洲乱小说 | 美女操逼在线 | 亚洲五月 |