一区二区三区三上|欧美在线视频五区|国产午夜无码在线观看视频|亚洲国产裸体网站|无码成年人影视|亚洲AV亚洲AV|成人开心激情五月|欧美性爱内射视频|超碰人人干人人上|一区二区无码三区亚洲人区久久精品

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Spring Boot中Docker的入門指南(一)

「Spring」認(rèn)證安全架構(gòu) ? 來源:「Spring」認(rèn)證安全架構(gòu) ? 作者:「Spring」認(rèn)證安全 ? 2022-06-28 15:54 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

許多人使用容器來包裝他們的 Spring Boot 應(yīng)用程序,而構(gòu)建容器并不是一件簡單的事情。這是針對 Spring Boot 應(yīng)用程序開發(fā)人員的指南,容器對于開發(fā)人員來說并不總是一個好的抽象。它們迫使你去了解和思考低層次的問題。但是,有時可能會要求您創(chuàng)建或使用容器,因此了解構(gòu)建塊是值得的。在本指南中,我們旨在向您展示如果您面臨需要創(chuàng)建自己的容器的前景,您可以做出的一些選擇。

我們假設(shè)您知道如何創(chuàng)建和構(gòu)建基本的 Spring Boot 應(yīng)用程序。如果沒有,請轉(zhuǎn)到入門指南之一?——例如,關(guān)于構(gòu)建REST 服務(wù)的指南。從那里復(fù)制代碼并練習(xí)本指南中包含的一些想法。

還有一個關(guān)于Docker的入門指南,這也是一個很好的起點(diǎn),但它沒有涵蓋我們在此處介紹的選擇范圍或詳細(xì)介紹它們。

一個基本的 Dockerfile

Spring Boot 應(yīng)用程序很容易轉(zhuǎn)換為可執(zhí)行的 JAR 文件。所有的入門指南都是這樣做的,你從Spring Initializr下載的每個應(yīng)用程序都有一個構(gòu)建步驟來創(chuàng)建一個可執(zhí)行的 JAR。使用 Maven,你運(yùn)行./mvnw install,使用 Gradle,你運(yùn)行./gradlew build。運(yùn)行該 JAR 的基本 Dockerfile 將如下所示,位于項(xiàng)目的頂層:

Dockerfile

FROM openjdk:8-jdk-alpine
VOLUME /tmp
ARG JAR_FILE
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar","/app.jar"]復(fù)制

JAR_FILE您可以作為命令的一部分傳入docker(Maven 和 Gradle 不同)。對于 Maven,以下命令有效:

docker build --build-arg JAR_FILE=target/*.jar -t myorg/myapp .復(fù)制

對于 Gradle,以下命令有效:

docker build --build-arg JAR_FILE=build/libs/*.jar -t myorg/myapp .復(fù)制

一旦你選擇了一個構(gòu)建系統(tǒng),你就不需要ARG. 您可以對 JAR 位置進(jìn)行硬編碼。對于 Maven,如下所示:

Dockerfile

FROM openjdk:8-jdk-alpine
VOLUME /tmp
COPY target/*.jar app.jar
ENTRYPOINT ["java","-jar","/app.jar"]復(fù)制

然后我們可以使用以下命令構(gòu)建鏡像:

docker build -t myorg/myapp .復(fù)制

然后我們可以通過運(yùn)行以下命令來運(yùn)行它:

docker run -p 8080:8080 myorg/myapp復(fù)制

輸出類似于以下示例輸出:

.   ____          _            __ _ _
/\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/  ___)| |_)| | | | | || (_| |  ) ) ) )
'  |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.0.2.RELEASE)

Nov 06, 2018 2:45:16 PM org.springframework.boot.StartupInfoLogger logStarting
INFO: Starting Application v0.1.0 on b8469cdc9b87 with PID 1 (/app.jar started by root in /)
Nov 06, 2018 2:45:16 PM org.springframework.boot.SpringApplication logStartupProfileInfo
...復(fù)制

如果你想在鏡像內(nèi)部四處尋找,你可以通過運(yùn)行以下命令在其中打開一個 shell(注意基礎(chǔ)鏡像沒有bash):

docker run -ti --entrypoint /bin/sh myorg/myapp復(fù)制

輸出類似于以下示例輸出:

/ # ls
app.jar  dev      home     media    proc     run      srv      tmp      var
bin      etc      lib      mnt      root     sbin     sys      usr
/ #

我們在示例中使用的 alpine 基礎(chǔ)容器沒有bash,所以這是一個ashshell。它具有一些但不是全部的特性bash。

如果你有一個正在運(yùn)行的容器并且你想查看它,你可以通過運(yùn)行docker exec

docker run --name myapp -ti --entrypoint /bin/sh myorg/myapp
docker exec -ti myapp /bin/sh
/ #復(fù)制

傳遞給命令myapp的位置在哪里。如果您沒有使用,docker 會分配一個助記名稱,您可以從. 您還可以使用容器的 SHA 標(biāo)識符而不是名稱。SHA 標(biāo)識符在輸出中也可見。--namedocker run--namedocker psdocker ps

入口點(diǎn)

使用Dockerfile的exec 形式ENTRYPOINT,以便沒有外殼包裝 Java 進(jìn)程。優(yōu)點(diǎn)是java進(jìn)程響應(yīng)KILL發(fā)送到容器的信號。實(shí)際上,這意味著(例如)如果您docker run在本地使用圖像,則可以使用CTRL-C. 如果命令行有點(diǎn)長,您可以COPY在運(yùn)行之前將其提取到 shell 腳本中并放入映像中。以下示例顯示了如何執(zhí)行此操作:

Dockerfile

FROM openjdk:8-jdk-alpine
VOLUME /tmp
COPY run.sh .
COPY target/*.jar app.jar
ENTRYPOINT ["run.sh"]復(fù)制

請記住使用exec java …啟動 java 進(jìn)程(以便它可以處理KILL信號):

run.sh

#!/bin/sh
exec java -jar /app.jar復(fù)制

入口點(diǎn)的另一個有趣方面是您是否可以在運(yùn)行時將環(huán)境變量注入 Java 進(jìn)程。例如,假設(shè)您想要在運(yùn)行時添加 Java 命令行選項(xiàng)。您可以嘗試這樣做:

Dockerfile

FROM openjdk:8-jdk-alpine
VOLUME /tmp
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","${JAVA_OPTS}","-jar","/app.jar"]復(fù)制

然后您可以嘗試以下命令:

docker build -t myorg/myapp .
docker run -p 9000:9000 -e JAVA_OPTS=-Dserver.port=9000 myorg/myapp復(fù)制

這失敗了,因?yàn)?/span>${}替換需要一個外殼。exec 表單不使用 shell 來啟動進(jìn)程,因此不應(yīng)用選項(xiàng)。您可以通過將入口點(diǎn)移動到腳本(如run.sh前面顯示的示例)或在入口點(diǎn)顯式創(chuàng)建 shell 來解決此問題。以下示例顯示了如何在入口點(diǎn)中創(chuàng)建 shell:

Dockerfile

FROM openjdk:8-jdk-alpine
VOLUME /tmp
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["sh", "-c", "java ${JAVA_OPTS} -jar /app.jar"]復(fù)制

然后,您可以通過運(yùn)行以下命令來啟動此應(yīng)用程序:

docker run -p 8080:8080 -e "JAVA_OPTS=-Ddebug -Xmx128m" myorg/myapp復(fù)制

該命令產(chǎn)生類似于以下的輸出:

.   ____          _            __ _ _
/\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/  ___)| |_)| | | | | || (_| |  ) ) ) )
'  |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.2.0.RELEASE)
...
2019-10-29 09:12:12.169 DEBUG 1 --- [           main] ConditionEvaluationReportLoggingListener :


============================
CONDITIONS EVALUATION REPORT
============================
...復(fù)制

(前面的輸出顯示了 Spring BootDEBUG生成的完整輸出的一部分。)-Ddebug

將 anENTRYPOINT與顯式 shell 一起使用(如前面的示例所做的那樣)意味著您可以將環(huán)境變量傳遞給 Java 命令。但是,到目前為止,您還不能為 Spring Boot 應(yīng)用程序提供命令行參數(shù)。以下命令不會在端口 9000 上運(yùn)行應(yīng)用程序:

docker run -p 9000:9000 myorg/myapp --server.port=9000復(fù)制

該命令產(chǎn)生以下輸出,將端口顯示為 8080 而不是 9000:

.   ____          _            __ _ _
/\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/  ___)| |_)| | | | | || (_| |  ) ) ) )
'  |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.2.0.RELEASE)
...
2019-10-29 09:20:19.718  INFO 1 --- [           main] o.s.b.web.embedded.netty.NettyWebServer  : Netty started on port(s): 8080復(fù)制

它不起作用,因?yàn)?docker 命令(該--server.port=9000部分)被傳遞到入口點(diǎn) ( sh),而不是它啟動的 Java 進(jìn)程。要解決此問題,您需要將命令行從以下添加CMDENTRYPOINT

Dockerfile

FROM openjdk:8-jdk-alpine
VOLUME /tmp
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["sh", "-c", "java ${JAVA_OPTS} -jar /app.jar ${0} ${@}"]復(fù)制

然后您可以運(yùn)行相同的命令并將端口設(shè)置為 9000:

$ docker run -p 9000:9000 myorg/myapp --server.port=9000復(fù)制

如以下輸出示例所示,端口確實(shí)設(shè)置為 9000:

.   ____          _            __ _ _
/\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/  ___)| |_)| | | | | || (_| |  ) ) ) )
'  |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.2.0.RELEASE)
...
2019-10-29 09:30:19.751  INFO 1 --- [           main] o.s.b.web.embedded.netty.NettyWebServer  : Netty started on port(s): 9000復(fù)制

注意${0}“命令”(在這種情況下是第一個程序參數(shù))和${@}“命令參數(shù)”(程序參數(shù)的其余部分)的使用。如果您使用腳本作為入口點(diǎn),那么您不需要${0}/app/run.sh在前面的示例中)。以下列表顯示了腳本文件中的正確命令:

run.sh

#!/bin/sh
exec java ${JAVA_OPTS} -jar /app.jar ${@}復(fù)制

docker配置到現(xiàn)在都非常簡單,生成的鏡像效率不是很高。docker 鏡像有一個文件系統(tǒng)層,其中包含 fat JAR,我們對應(yīng)用程序代碼所做的每一次更改都會更改該層,這可能是 10MB 或更多(對于某些應(yīng)用程序甚至高達(dá) 50MB)。我們可以通過將 JAR 拆分為多個層來改進(jìn)這一點(diǎn)。

較小的圖像

請注意,前面示例中的基本映像是openjdk:8-jdk-alpine. 這些alpine圖像小于Dockerhubopenjdk的標(biāo)準(zhǔn)庫圖像。您還可以通過使用標(biāo)簽而不是. 并非所有應(yīng)用程序都使用 JRE(與 JDK 相對),但大多數(shù)應(yīng)用程序都可以。一些組織強(qiáng)制執(zhí)行一個規(guī)則,即每個應(yīng)用程序都必須使用 JRE,因?yàn)榇嬖跒E用某些 JDK 功能(例如編譯)的風(fēng)險(xiǎn)。jrejdk

另一個可以讓您獲得更小的映像的技巧是使用JLink,它與 OpenJDK 11 捆綁在一起。JLink 允許您從完整 JDK 中的模塊子集構(gòu)建自定義 JRE 分發(fā),因此您不需要 JRE 或 JDK基礎(chǔ)圖像。原則上,這將使您獲得比使用openjdk官方 docker 圖像更小的總圖像大小。在實(shí)踐中,您(還)不能將alpine基礎(chǔ)鏡像與 JDK 11 一起使用,因此您對基礎(chǔ)鏡像的選擇是有限的,并且可能會導(dǎo)致最終鏡像的大小更大。此外,您自己的基本映像中的自定義 JRE 不能在其他應(yīng)用程序之間共享,因?yàn)樗鼈冃枰煌淖远x。因此,您的所有應(yīng)用程序可能都有較小的圖像,但它們?nèi)匀恍枰L的時間才能啟動,因?yàn)樗鼈儧]有從緩存 JRE 層中受益。

最后一點(diǎn)突出了圖像構(gòu)建者的一個非常重要的問題:目標(biāo)不一定總是盡可能地構(gòu)建最小的圖像。較小的圖像通常是一個好主意,因?yàn)樗鼈冃枰俚臅r間來上傳和下載,但前提是它們中的所有圖層都沒有被緩存。如今,圖像注冊非常復(fù)雜,您很容易通過嘗試巧妙地構(gòu)建圖像而失去這些功能的好處。如果您使用通用基礎(chǔ)層,圖像的總大小就不再那么重要了,而且隨著注冊中心和平臺的發(fā)展,它可能變得更不重要。話雖如此,嘗試優(yōu)化應(yīng)用程序映像中的層仍然很重要且有用。然而,

更好的 Dockerfile

由于 JAR 本身的打包方式,Spring Boot fat JAR 自然有“層”。如果我們先解包,它已經(jīng)分為外部依賴和內(nèi)部依賴。要在 docker 構(gòu)建中一步完成此操作,我們需要先解壓縮 JAR。以下命令(堅(jiān)持使用 Maven,但 Gradle 版本非常相似)解壓縮 Spring Boot fat JAR:

mkdir target/dependency
(cd target/dependency; jar -xf ../*.jar)
docker build -t myorg/myapp .復(fù)制

然后我們可以使用下面的Dockerfile

Dockerfile

FROM openjdk:8-jdk-alpine
VOLUME /tmp
ARG DEPENDENCY=target/dependency
COPY ${DEPENDENCY}/BOOT-INF/lib /app/lib
COPY ${DEPENDENCY}/META-INF /app/META-INF
COPY ${DEPENDENCY}/BOOT-INF/classes /app
ENTRYPOINT ["java","-cp","app:app/lib/*","hello.Application"]復(fù)制

現(xiàn)在有三層,所有應(yīng)用程序資源都在后面兩層。如果應(yīng)用程序依賴沒有改變,第一層(from BOOT-INF/lib)不需要改變,所以構(gòu)建更快,并且容器在運(yùn)行時的啟動也更快,只要基礎(chǔ)層已經(jīng)被緩存。

我們使用了一個硬編碼的主應(yīng)用程序類:hello.Application. 這對于您的應(yīng)用程序可能有所不同。如果你愿意,你可以用另一個參數(shù)化它ARG。您還可以將 Spring Boot fat 復(fù)制JarLauncher到映像中并使用它來運(yùn)行應(yīng)用程序。它可以工作,您不需要指定主類,但啟動時會慢一些。

Spring Boot 層索引

從 Spring Boot 2.3.0 開始,使用 Spring Boot Maven 或 Gradle 插件構(gòu)建的 JAR 文件在 JAR 文件中包含層信息。該層信息根據(jù)應(yīng)用程序構(gòu)建之間更改的可能性來分離應(yīng)用程序的各個部分。這可以用來使 Docker 鏡像層更加高效。

層信息可用于將 JAR 內(nèi)容提取到每個層的目錄中:

mkdir target/extracted
java -Djarmode=layertools -jar target/*.jar extract --destination target/extracted
docker build -t myorg/myapp .復(fù)制

然后我們可以使用以下內(nèi)容Dockerfile

Dockerfile

FROM openjdk:8-jdk-alpine
VOLUME /tmp
ARG EXTRACTED=/workspace/app/target/extracted
COPY ${EXTRACTED}/dependencies/ ./
COPY ${EXTRACTED}/spring-boot-loader/ ./
COPY ${EXTRACTED}/snapshot-dependencies/ ./
COPY ${EXTRACTED}/application/ ./
ENTRYPOINT ["java","org.springframework.boot.loader.JarLauncher"]

Spring Boot fatJarLauncher是從 JAR 中提取到鏡像中的,因此它可以用于啟動應(yīng)用程序,而無需對主應(yīng)用程序類進(jìn)行硬編碼。

有關(guān)使用分層功能的更多信息,請參閱Spring Boot 文檔。

調(diào)整

如果您想盡快啟動您的應(yīng)用程序(大多數(shù)人都這樣做),您可能會考慮一些調(diào)整:

  • 使用spring-context-indexer(鏈接到文檔)。它不會為小型應(yīng)用程序增加太多,但每一點(diǎn)都有幫助。
  • 如果您負(fù)擔(dān)得起,請不要使用執(zhí)行器。
  • 使用 Spring Boot 2.1(或更高版本)和 Spring 5.1(或更高版本)。
  • 使用(通過命令行參數(shù)、系統(tǒng)屬性或其他方法)修復(fù)Spring Boot 配置文件的位置。spring.config.location
  • 通過設(shè)置來關(guān)閉 JMX(您可能不需要在容器中使用它)spring.jmx.enabled=false。
  • 使用-noverify. 還要考慮-XX:TieredStopAtLevel=1(這會在以后減慢 JIT 但會縮短啟動時間)。
  • 使用 Java 8 的容器內(nèi)存提示:-XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap. 在 Java 11 中,默認(rèn)情況下這是自動的。

您的應(yīng)用程序在運(yùn)行時可能不需要完整的 CPU,但它確實(shí)需要多個 CPU 才能盡快啟動(至少兩個,四個更好)。如果您不介意啟動速度較慢,則可以將 CPU 限制在四個以下。如果您被迫從少于四個 CPU 開始,設(shè)置 可能會有所幫助
-Dspring.backgroundpreinitializer.ignore=true,因?yàn)樗梢苑乐?Spring Boot 創(chuàng)建一個它可能無法使用的新線程(這適用于 Spring Boot 2.1.0 及更高版本)。

多階段構(gòu)建

A Better Dockerfile中Dockerfile所示的假設(shè)假設(shè)胖 JAR 已經(jīng)在命令行上構(gòu)建。您還可以通過使用多階段構(gòu)建并將結(jié)果從一個圖像復(fù)制到另一個圖像來在 docker 中執(zhí)行該步驟。以下示例通過使用 Maven 來實(shí)現(xiàn):

Dockerfile

FROM openjdk:8-jdk-alpine as build
WORKDIR /workspace/app

COPY mvnw .
COPY .mvn .mvn
COPY pom.xml .
COPY src src

RUN ./mvnw install -DskipTests
RUN mkdir -p target/dependency && (cd target/dependency; jar -xf ../*.jar)

FROM openjdk:8-jdk-alpine
VOLUME /tmp
ARG DEPENDENCY=/workspace/app/target/dependency
COPY --from=build ${DEPENDENCY}/BOOT-INF/lib /app/lib
COPY --from=build ${DEPENDENCY}/META-INF /app/META-INF
COPY --from=build ${DEPENDENCY}/BOOT-INF/classes /app
ENTRYPOINT ["java","-cp","app:app/lib/*","hello.Application"]復(fù)制

第一個圖像標(biāo)記為build,它用于運(yùn)行 Maven、構(gòu)建胖 JAR 并解壓縮它。解包也可以由 Maven 或 Gradle 完成(這是入門指南中采用的方法)。沒有太大區(qū)別,只是必須編輯構(gòu)建配置并添加插件。

請注意,源代碼已分為四層。后面的層包含構(gòu)建配置和應(yīng)用程序的源代碼,前面的層包含構(gòu)建系統(tǒng)本身(Maven 包裝器)。這是一個小的優(yōu)化,也意味著我們不必將target目錄復(fù)制到 docker 鏡像,即使是用于構(gòu)建的臨時鏡像。

RUN每個源代碼更改的構(gòu)建都很慢,因?yàn)楸仨氃诘谝徊糠种匦聞?chuàng)建 Maven 緩存。但是你有一個完全獨(dú)立的構(gòu)建,只要他們有 docker,任何人都可以運(yùn)行它來運(yùn)行你的應(yīng)用程序。這在某些環(huán)境中可能非常有用——例如,您需要與不了解 Java 的人共享您的代碼。

實(shí)驗(yàn)功能

Docker 18.06 帶有一些“實(shí)驗(yàn)性”特性,包括緩存構(gòu)建依賴項(xiàng)的方法。要打開它們,您需要在守護(hù)進(jìn)程 ( dockerd) 中有一個標(biāo)志,并在運(yùn)行客戶端時需要一個環(huán)境變量。然后你可以添加一個“神奇”的第一行到你的Dockerfile

Dockerfile

# syntax=docker/dockerfile:experimental復(fù)制

然后該RUN指令接受一個新標(biāo)志:--mount. 以下清單顯示了一個完整示例:

Dockerfile

# syntax=docker/dockerfile:experimental
FROM openjdk:8-jdk-alpine as build
WORKDIR /workspace/app

COPY mvnw .
COPY .mvn .mvn
COPY pom.xml .
COPY src src

RUN --mount=type=cache,target=/root/.m2 ./mvnw install -DskipTests
RUN mkdir -p target/dependency && (cd target/dependency; jar -xf ../*.jar)

FROM openjdk:8-jdk-alpine
VOLUME /tmp
ARG DEPENDENCY=/workspace/app/target/dependency
COPY --from=build ${DEPENDENCY}/BOOT-INF/lib /app/lib
COPY --from=build ${DEPENDENCY}/META-INF /app/META-INF
COPY --from=build ${DEPENDENCY}/BOOT-INF/classes /app
ENTRYPOINT ["java","-cp","app:app/lib/*","hello.Application"]復(fù)制

然后你可以運(yùn)行它:

DOCKER_BUILDKIT=1 docker build -t myorg/myapp .復(fù)制

以下清單顯示了示例輸出:

...
 => /bin/sh -c ./mvnw install -DskipTests              5.7s
 => exporting to image                                 0.0s
 => => exporting layers                                0.0s
 => => writing image sha256:3defa...
 => => naming to docker.io/myorg/myapp復(fù)制

使用實(shí)驗(yàn)性功能,您會在控制臺上獲得不同的輸出,但您可以看到,如果緩存是熱的,現(xiàn)在 Maven 構(gòu)建只需幾秒鐘而不是幾分鐘。

這個Dockerfile配置的 Gradle 版本非常相似:

Dockerfile

# syntax=docker/dockerfile:experimental
FROM openjdk:8-jdk-alpine AS build
WORKDIR /workspace/app

COPY . /workspace/app
RUN --mount=type=cache,target=/root/.gradle ./gradlew clean build
RUN mkdir -p build/dependency && (cd build/dependency; jar -xf ../libs/*.jar)

FROM openjdk:8-jdk-alpine
VOLUME /tmp
ARG DEPENDENCY=/workspace/app/build/dependency
COPY --from=build ${DEPENDENCY}/BOOT-INF/lib /app/lib
COPY --from=build ${DEPENDENCY}/META-INF /app/META-INF
COPY --from=build ${DEPENDENCY}/BOOT-INF/classes /app
ENTRYPOINT ["java","-cp","app:app/lib/*","hello.Application"]

雖然這些功能處于實(shí)驗(yàn)階段,但打開和關(guān)閉 buildkit 的選項(xiàng)取決于docker您使用的版本。檢查您擁有的版本的文檔(前面顯示的示例對于docker18.0.6 是正確的)。

安全方面

就像在經(jīng)典 VM 部署中一樣,進(jìn)程不應(yīng)以 root 權(quán)限運(yùn)行。相反,映像應(yīng)包含運(yùn)行應(yīng)用程序的非 root 用戶。

在 aDockerfile中,您可以通過添加另一個添加(系統(tǒng))用戶和組并將其設(shè)置為當(dāng)前用戶(而不是默認(rèn)的 root)的層來實(shí)現(xiàn)此目的:

Dockerfile

FROM openjdk:8-jdk-alpine

RUN addgroup -S demo && adduser -S demo -G demo
USER demo

...復(fù)制

如果有人設(shè)法突破您的應(yīng)用程序并在容器內(nèi)運(yùn)行系統(tǒng)命令,這種預(yù)防措施會限制他們的能力(遵循最小權(quán)限原則)。

一些進(jìn)一步的Dockerfile命令只能以 root 身份運(yùn)行,因此您可能必須將 USER 命令進(jìn)一步向下移動(例如,如果您計(jì)劃在容器中安裝更多包,它只能以 root 身份運(yùn)行)。

對于其他方法,不使用 aDockerfile可能更適合。例如,在后面描述的 buildpack 方法中,大多數(shù)實(shí)現(xiàn)默認(rèn)使用非 root 用戶。

另一個考慮因素是大多數(shù)應(yīng)用程序在運(yùn)行時可能不需要完整的 JDK,因此一旦我們進(jìn)行了多階段構(gòu)建,我們就可以安全地切換到 JRE 基礎(chǔ)映像。因此,在前面顯示的多階段構(gòu)建中,我們可以將其用于最終的可運(yùn)行映像:

Dockerfile

FROM openjdk:8-jre-alpine

...復(fù)制

如前所述,這也節(jié)省了映像中的一些空間,這些空間將被運(yùn)行時不需要的工具占用。

審核編輯:湯梓紅

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報(bào)投訴
  • 容器
    +關(guān)注

    關(guān)注

    0

    文章

    511

    瀏覽量

    22458
  • 應(yīng)用程序
    +關(guān)注

    關(guān)注

    38

    文章

    3337

    瀏覽量

    59044
  • spring
    +關(guān)注

    關(guān)注

    0

    文章

    340

    瀏覽量

    15088
  • Docker
    +關(guān)注

    關(guān)注

    0

    文章

    515

    瀏覽量

    12974
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關(guān)推薦
    熱點(diǎn)推薦

    Spring BootDocker入門指南(二)

    如果你不想docker在你的構(gòu)建中直接調(diào)用,有套豐富的 Maven 和 Gradle 插件可以為你完成這項(xiàng)工作。這里僅僅是少數(shù)。
    的頭像 發(fā)表于 06-28 15:55 ?2643次閱讀

    Spring bootRedis的使用

    【本人禿頂程序員】springboot專輯:Spring bootRedis的使用
    發(fā)表于 03-27 11:42

    Spring Boot嵌入式Web容器原理是什么

    Spring Boot嵌入式Web容器原理Spring Boot的目標(biāo)是構(gòu)建“非常容易創(chuàng)建、獨(dú)立、產(chǎn)品級別的基于Spring的應(yīng)用”。這些應(yīng)
    發(fā)表于 12-16 07:57

    Docker入門指南

    指南介紹了如何使用Docker簡化嵌入式設(shè)備和服務(wù)器上的多體系結(jié)構(gòu)應(yīng)用程序部署。 快速擴(kuò)展軟件環(huán)境可能是項(xiàng)既困難又耗時的任務(wù)。在本指南中,我們將向您展示
    發(fā)表于 08-02 06:09

    使用Spring Cloud與Docker實(shí)戰(zhàn)微服務(wù)

    使用Spring Cloud與Docker實(shí)戰(zhàn)微服務(wù)
    發(fā)表于 09-09 08:31 ?7次下載
    使用<b class='flag-5'>Spring</b> Cloud與<b class='flag-5'>Docker</b>實(shí)戰(zhàn)微服務(wù)

    spring boot入門

    運(yùn)行應(yīng)用:mvn spring-boot:run或在IDE運(yùn)行main()方法,在瀏覽器訪問http://localhost:8080,Hello World!就出現(xiàn)在了頁面。只
    發(fā)表于 11-25 09:57 ?2817次閱讀

    Spring Boot從零入門1 詳述

    在開始學(xué)習(xí)Spring Boot之前,我之前從未接觸過Spring相關(guān)的項(xiàng)目,Java基礎(chǔ)還是幾年前自學(xué)的,現(xiàn)在估計(jì)也忘得差不多了吧,寫Spring
    的頭像 發(fā)表于 12-10 22:18 ?857次閱讀

    Spring Boot特有的實(shí)踐

    Spring Boot是最流行的用于開發(fā)微服務(wù)的Java框架。在本文中,我將與你分享自2016年以來我在專業(yè)開發(fā)中使用Spring Boot所采用的最佳實(shí)踐。這些內(nèi)容是基于我的個人經(jīng)驗(yàn)
    的頭像 發(fā)表于 09-29 10:24 ?1171次閱讀

    強(qiáng)大的Spring Boot 3.0要來了

    和 Bugfix。 Spring Boot 3.0 的開發(fā)工作始于實(shí)驗(yàn)性的 Spring Native,旨在為 GraalVM 原生鏡像提供支持。 在該版本,開發(fā)者現(xiàn)在可以使用標(biāo)準(zhǔn)
    的頭像 發(fā)表于 10-31 11:17 ?2344次閱讀

    Spring Boot Web相關(guān)的基礎(chǔ)知識

    篇文章我們已經(jīng)學(xué)會了如何通過IDEA快速建立Spring Boot項(xiàng)目,還介紹了Spring B
    的頭像 發(fā)表于 03-17 15:03 ?896次閱讀

    Spring Boot如何使用定時任務(wù)

    本文介紹在 Spring Boot 如何使用定時任務(wù),使用非常簡單,就不做過多說明了。
    的頭像 發(fā)表于 04-12 10:56 ?1212次閱讀

    Spring Boot Actuator快速入門

    不知道大家在寫 Spring Boot 項(xiàng)目的過程,使用過 Spring Boot Actuator 嗎?知道
    的頭像 發(fā)表于 10-09 17:11 ?908次閱讀

    Spring Boot啟動 Eureka流程

    在上篇已經(jīng)說過了 Eureka-Server 本質(zhì)上是個 web 應(yīng)用的項(xiàng)目,今天就來看看 Spring Boot 是怎么啟動 Eureka 的。
    的頭像 發(fā)表于 10-10 11:40 ?1202次閱讀
    <b class='flag-5'>Spring</b> <b class='flag-5'>Boot</b>啟動 Eureka流程

    Spring Boot的啟動原理

    可能很多初學(xué)者會比較困惑,Spring Boot 是如何做到將應(yīng)用代碼和所有的依賴打包成個獨(dú)立的 Jar 包,因?yàn)閭鹘y(tǒng)的 Java 項(xiàng)目打包成 Jar 包之后,需要通過 -classpath 屬性
    的頭像 發(fā)表于 10-13 11:44 ?937次閱讀
    <b class='flag-5'>Spring</b> <b class='flag-5'>Boot</b>的啟動原理

    Spring Boot 的設(shè)計(jì)目標(biāo)

    什么是Spring Boot Spring BootSpring 開源組織下的個子項(xiàng)目,
    的頭像 發(fā)表于 10-13 14:56 ?800次閱讀
    <b class='flag-5'>Spring</b> <b class='flag-5'>Boot</b> 的設(shè)計(jì)目標(biāo)