构建插件
如果你不想docker在你的构建中间接调用,有一套丰盛的 Maven 和 Gradle 插件能够为你实现这项工作。这里仅仅是多数。

Spring Boot Maven 和 Gradle 插件
您能够应用Maven和Gradle的 Spring Boot 构建插件来创立容器映像。docker build这些插件应用Cloud Native Buildpacks创立一个 OCI 映像(与创立的格局雷同) 。您不须要Dockerfile,但您的确须要 Docker 守护程序,能够在本地(应用 docker 构建时应用)或通过DOCKER_HOST环境变量近程进行。默认构建器针对 Spring Boot 应用程序进行了优化,并且图像像下面的示例一样无效地分层。

以下示例在不更改pom.xml文件的状况下应用 Maven:

./mvnw spring-boot:build-image -Dspring-boot.build-image.imageName=myorg/myapp复制
以下示例实用于 Gradle,无需更改build.gradle文件:

./gradlew bootBuildImage --imageName=myorg/myapp复制
第一次构建可能须要很长时间,因为它必须下载一些容器镜像和 JDK,但后续构建应该很快。

而后您能够运行映像,如以下清单所示(带输入):

docker run -p 8080:8080 -t myorg/myapp
Setting Active Processor Count to 6
Calculating JVM memory based on 14673596K available memory
Calculated JVM Memory Configuration: -XX:MaxDirectMemorySize=10M -Xmx14278122K -XX:MaxMetaspaceSize=88273K -XX:ReservedCodeCacheSize=240M -Xss1M (Total Memory: 14673596K, Thread Count: 50, Loaded Class Count: 13171, Headroom: 0%)
Adding 129 container CA certificates to JVM truststore
Spring Cloud Bindings Enabled
Picked up JAVA_TOOL_OPTIONS: -Djava.security.properties=/layers/paketo-buildpacks_bellsoft-liberica/java-security-properties/java-security.properties -agentpath:/layers/paketo-buildpacks_bellsoft-liberica/jvmkill/jvmkill-1.16.0-RELEASE.so=printHeapHistogram=1 -XX:ActiveProcessorCount=6 -XX:MaxDirectMemorySize=10M -Xmx14278122K -XX:MaxMetaspaceSize=88273K -XX:ReservedCodeCacheSize=240M -Xss1M -Dorg.springframework.cloud.bindings.boot.enable=true
....
2015-03-31 13:25:48.035 INFO 1 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080 (http)
2015-03-31 13:25:48.037 INFO 1 --- [ main] hello.Application复制
您能够看到应用程序失常启动。您可能还留神到 JVM 内存需要是在容器内计算并设置为命令行选项的。这与多年来在 Cloud Foundry 构建包中应用的内存计算雷同。它代表了对一系列 JVM 应用程序(包含但不限于 Spring Boot 应用程序)的最佳抉择的重要钻研,后果通常比 JVM 的默认设置好得多。您能够自定义命令行选项并通过设置环境变量笼罩内存计算器,如Paketo buildpacks 文档中所示。

Spotify Maven 插件
Spotify Maven 插件是一个受欢迎的抉择。它要求您编写 aDockerfile而后docker为您运行,就像您在命令行上执行它一样。docker 镜像标签和其余货色有一些配置选项,但它使您的应用程序中的 docker 常识集中在一个Dockerfile很多人喜爱的 .

对于真正的根本用法,它无需额定配置即可开箱即用:

mvn com.spotify:dockerfile-maven-plugin:build
...
[INFO] Building Docker context /home/dsyer/dev/demo/workspace/myapp
[INFO]
[INFO] Image will be built without a name
[INFO]
...
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 7.630 s
[INFO] Finished at: 2018-11-06T16:03:16+00:00
[INFO] Final Memory: 26M/595M
[INFO] ------------------------------------------------------------------------复制
这将构建一个匿名 docker 映像。咱们当初能够在命令行上标记它docker或应用 Maven 配置将其设置为repository. 以下示例在不更改pom.xml文件的状况下工作:

$ mvn com.spotify:dockerfile-maven-plugin:build -Ddockerfile.repository=myorg/myapp复制
或者,您更改pom.xml文件:

pom.xml

<build>

<plugins>    <plugin>        <groupId>com.spotify</groupId>        <artifactId>dockerfile-maven-plugin</artifactId>        <version>1.4.8</version>        <configuration>            <repository>myorg/${project.artifactId}</repository>        </configuration>    </plugin></plugins>

</build>复制
Palantir Gradle 插件
Palantir Gradle 插件与 a 一起应用,Dockerfile并且还可Dockerfile认为您生成 a。而后它docker就像在命令行上运行它一样运行。

首先,您须要将插件导入您的build.gradle:

build.gradle

buildscript {

...dependencies {    ...    classpath('gradle.plugin.com.palantir.gradle.docker:gradle-docker:0.13.0')}

}复制
而后,最初,您能够利用插件并调用它的工作:

build.gradle

apply plugin: 'com.palantir.docker'

group = 'myorg'

bootJar {

baseName = 'myapp'version =  '0.1.0'

}

task unpack(type: Copy) {

dependsOn bootJarfrom(zipTree(tasks.bootJar.outputs.files.singleFile))into("build/dependency")

}
docker {

name "${project.group}/${bootJar.baseName}"copySpec.from(tasks.unpack.outputs).into("dependency")buildArgs(['DEPENDENCY': "dependency"])

}复制
在本例中,咱们抉择将 Spring Boot fat JAR 解压到build目录中的特定地位,该地位是 docker build 的根目录。Dockerfile而后晚期显示的多层(不是多阶段)起作用。

Jib Maven 和 Gradle 插件
Google 有一个名为Jib的开源工具,它绝对较新,但出于多种起因十分乏味。可能最乏味的是您不须要 docker 来运行它。Jib 应用与您取得的雷同规范输入来构建映像,docker build但除非您要求它,否则它不会应用docker,因而它能够在未装置 docker 的环境中工作(在构建服务器中很常见)。您也不须要Dockerfile(无论如何都会被疏忽)或任何货色pom.xml来取得在 Maven 中构建的图像(Gradle 将要求您至多在 中装置插件build.gradle)。

DockerfileJib 的另一个乏味的个性是它对层有意见,并且它以与下面创立的多层略有不同的形式优化它们。与胖 JAR 中一样,Jib 将本地应用程序资源与依赖项离开,但它更进一步,还将快照依赖项放入独自的层,因为它们更有可能发生变化。有用于进一步自定义布局的配置选项。

以下示例在不更改 Maven 的状况下应用pom.xml:

$ mvn com.google.cloud.tools:jib-maven-plugin:build -Dimage=myorg/myapp复制
myorg要运行该命令,您须要具备在存储库前缀下推送到 Dockerhub 的权限。如果您已docker在命令行上进行了身份验证,则能够在本地~/.docker配置中应用。~/.m2/settings.xml您还能够在您的(id存储库的重要)中设置 Maven“服务器”身份验证:

settings.xml

<server>  <id>registry.hub.docker.com</id>  <username>myorg</username>  <password>...</password></server>复制

还有其余选项——例如,您能够docker应用dockerBuild指标而不是build. 还反对其余容器注册表。对于每一项,您都须要通过 Docker 或 Maven 设置来设置本地身份验证。

gradle 插件具备相似的性能,一旦你在你的build.gradle:.

build.gradle

plugins {
...
id 'com.google.cloud.tools.jib' version '1.8.0'
}复制
以下清单应用入门指南中应用的旧 Gradle 款式:

build.gradle

buildscript {

repositories {  maven {    url "https://plugins.gradle.org/m2/"  }  mavenCentral()}dependencies {    classpath('org.springframework.boot:spring-boot-gradle-plugin:2.2.1.RELEASE')    classpath('com.google.cloud.tools.jib:com.google.cloud.tools.jib.gradle.plugin:1.8.0')}

}复制
而后,您能够通过运行以下命令来构建映像:

./gradlew jib --image=myorg/myapp复制
与 Maven 构建一样,如果您已docker在命令行上进行了身份验证,则图像推送将从您的本地~/.docker配置进行身份验证。

继续集成
现在,自动化(或应该是)是每个应用程序生命周期的一部分。人们用来进行自动化的工具往往十分善于从源代码调用构建零碎。因而,如果这为您提供了一个 docker 映像,并且构建代理中的环境与开发人员本人的环境充沛统一,那可能就足够了。对 docker 注册表进行身份验证可能是最大的挑战,但所有自动化工具中都有一些性能能够帮忙解决这个问题。

然而,有时最好将容器创立齐全留给自动化层,在这种状况下,可能不须要净化用户的代码。容器创立很辣手,开发人员有时不须要真正关怀它。如果用户代码更洁净,则不同的工具更有可能“做正确的事”(利用平安修复、优化缓存等)。自动化有多种抉择,现在它们都带有一些与容器相干的性能。咱们将看一对夫妇。

大厅
Concourse是一个基于管道的自动化平台,可用于 CI 和 CD。它在 VMware 外部应用,该项目标次要作者在那里工作。Concourse 中的所有内容都是无状态的,并且在容器中运行,CLI 除外。因为运行容器是自动化管道的次要业务程序,因而很好地反对创立容器。Docker Image Resource负责放弃构建的输入状态是最新的,如果它是一个容器镜像的话。

以下示例管道为后面显示的示例构建了一个 docker 映像,假如它位于 github 中myorg/myapp,Dockerfile在根中有一个,并且在 中有一个构建工作申明src/main/ci/build.yml:

resources:

  • name: myapp
    type: git
    source:
    uri: https://github.com/myorg/myap...
  • name: myapp-image
    type: docker-image
    source:
    email: {{docker-hub-email}}
    username: {{docker-hub-username}}
    password: {{docker-hub-password}}
    repository: myorg/myapp

jobs:

  • name: main
    plan:

    • task: build
      file: myapp/src/main/ci/build.yml
    • put: myapp-image
      params:
      build: myapp复制
      管道的构造是十分具备申明性的:您定义“资源”(输出、输入或两者)和“作业”(应用资源并将操作利用于资源)。如果任何输出资源产生更改,则会触发新的构建。如果任何输入资源在作业期间产生更改,则会对其进行更新。

管道能够在与应用程序源代码不同的中央定义。此外,对于通用构建设置,工作申明也能够集中或内部化。这容许在开发和自动化之间拆散一些关注点,这适宜一些软件开发组织。

詹金斯
Jenkins是另一个风行的自动化服务器。它具备大量性能,但最靠近此处其余自动化示例的是管道性能。上面Jenkinsfile应用 Maven 构建一个 Spring Boot 我的项目,而后应用 aDockerfile构建一个镜像并将其推送到存储库:

Jenkinsfile

node {

checkout scmsh './mvnw -B -DskipTests clean package'docker.build("myorg/myapp").push()

}复制
对于须要在构建服务器中进行身份验证的(理论)docker 存储库,您能够docker应用docker.withCredentials(…).

构建包
packSpring Boot Maven 和 Gradle 插件应用构建包的形式与CLI 在以下示例中的应用形式完全相同。给定雷同的输出,生成的图像是雷同的。

Cloud Foundry在外部应用容器曾经很多年了,用于将用户代码转换为容器的局部技术是 Build Packs,这个想法最后是从Heroku借来的。以后一代的 buildpacks (v2) 生成由平台组装到容器中的通用二进制输入。新一代构建包(v3) 是 Heroku 与其余公司(包含 VMware)的单干,它间接明确地构建容器镜像。这对开发人员和运营商来说很乏味。开发人员不须要太关怀如何构建容器的细节,但如果须要,他们能够轻松创立一个。Buildpacks 还具备许多用于缓存构建后果和依赖项的性能。通常,构建包的运行速度比原生 Docker 构建快得多。操作员能够扫描容器以审核其内容并将其转换为修补它们以进行安全更新。此外,您能够在本地(例如,在开发人员机器或 CI 服务中)或在 Cloud Foundry 等平台中运行构建包。

buildpack 生命周期的输入是容器映像,但您不须要Dockerfile. 输入映像中的文件系统层由 buildpack 管制。通常,许多优化都是在开发人员不用晓得或关怀它们的状况下进行的。在较低层(例如蕴含操作系统的根底映像)和较高层(蕴含中间件和语言特定依赖项)之间还有一个应用程序二进制接口。这使得 Cloud Foundry 等平台能够在有安全更新的状况下修补较低层,而不会影响应用程序的完整性和性能。

为了让您理解 buildpack 的性能,以下示例(显示其输入)从命令行应用Pack CLI(它能够与咱们在本指南中应用的示例应用程序一起应用 - 不须要Dockerfile或任何非凡的构建配置):

pack build myorg/myapp --builder=paketobuildpacks/builder:base --path=.
base: Pulling from paketobuildpacks/builder
Digest: sha256:4fae5e2abab118ca9a37bf94ab42aa17fef7c306296b0364f5a0e176702ab5cb
Status: Image is up to date for paketobuildpacks/builder:base
base-cnb: Pulling from paketobuildpacks/run
Digest: sha256:a285e73bc3697bc58c228b22938bc81e9b11700e087fd9d44da5f42f14861812
Status: Image is up to date for paketobuildpacks/run:base-cnb
===> DETECTING
7 of 18 buildpacks participating
paketo-buildpacks/ca-certificates 2.3.2
paketo-buildpacks/bellsoft-liberica 8.2.0
paketo-buildpacks/maven 5.3.2
paketo-buildpacks/executable-jar 5.1.2
paketo-buildpacks/apache-tomcat 5.6.1
paketo-buildpacks/dist-zip 4.1.2
paketo-buildpacks/spring-boot 4.4.2
===> ANALYZING
Previous image with name "myorg/myapp" not found
===> RESTORING
===> BUILDING

Paketo CA Certificates Buildpack 2.3.2
https://github.com/paketo-bui...
Launch Helper: Contributing to layer

Creating /layers/paketo-buildpacks_ca-certificates/helper/exec.d/ca-certificates-helper

Paketo BellSoft Liberica Buildpack 8.2.0
https://github.com/paketo-bui...
Build Configuration:

$BP_JVM_VERSION              11              the Java version

Launch Configuration:

$BPL_JVM_HEAD_ROOM           0               the headroom in memory calculation$BPL_JVM_LOADED_CLASS_COUNT  35% of classes  the number of loaded classes in memory calculation$BPL_JVM_THREAD_COUNT        250             the number of threads in memory calculation$JAVA_TOOL_OPTIONS                           the JVM launch flags

BellSoft Liberica JDK 11.0.12: Contributing to layer

Downloading from https://github.com/bell-sw/Liberica/releases/download/11.0.12+7/bellsoft-jdk11.0.12+7-linux-amd64.tar.gzVerifying checksumExpanding to /layers/paketo-buildpacks_bellsoft-liberica/jdkAdding 129 container CA certificates to JVM truststoreWriting env.build/JAVA_HOME.overrideWriting env.build/JDK_HOME.override

BellSoft Liberica JRE 11.0.12: Contributing to layer

Downloading from https://github.com/bell-sw/Liberica/releases/download/11.0.12+7/bellsoft-jre11.0.12+7-linux-amd64.tar.gzVerifying checksumExpanding to /layers/paketo-buildpacks_bellsoft-liberica/jreAdding 129 container CA certificates to JVM truststoreWriting env.launch/BPI_APPLICATION_PATH.defaultWriting env.launch/BPI_JVM_CACERTS.defaultWriting env.launch/BPI_JVM_CLASS_COUNT.defaultWriting env.launch/BPI_JVM_SECURITY_PROVIDERS.defaultWriting env.launch/JAVA_HOME.defaultWriting env.launch/MALLOC_ARENA_MAX.default

Launch Helper: Contributing to layer

Creating /layers/paketo-buildpacks_bellsoft-liberica/helper/exec.d/active-processor-countCreating /layers/paketo-buildpacks_bellsoft-liberica/helper/exec.d/java-optsCreating /layers/paketo-buildpacks_bellsoft-liberica/helper/exec.d/link-local-dnsCreating /layers/paketo-buildpacks_bellsoft-liberica/helper/exec.d/memory-calculatorCreating /layers/paketo-buildpacks_bellsoft-liberica/helper/exec.d/openssl-certificate-loaderCreating /layers/paketo-buildpacks_bellsoft-liberica/helper/exec.d/security-providers-configurerCreating /layers/paketo-buildpacks_bellsoft-liberica/helper/exec.d/security-providers-classpath-9

JVMKill Agent 1.16.0: Contributing to layer

Downloading from https://github.com/cloudfoundry/jvmkill/releases/download/v1.16.0.RELEASE/jvmkill-1.16.0-RELEASE.soVerifying checksumCopying to /layers/paketo-buildpacks_bellsoft-liberica/jvmkillWriting env.launch/JAVA_TOOL_OPTIONS.appendWriting env.launch/JAVA_TOOL_OPTIONS.delim

Java Security Properties: Contributing to layer

Writing env.launch/JAVA_SECURITY_PROPERTIES.defaultWriting env.launch/JAVA_TOOL_OPTIONS.appendWriting env.launch/JAVA_TOOL_OPTIONS.delim

Paketo Maven Buildpack 5.3.2
https://github.com/paketo-bui...
Build Configuration:

$BP_MAVEN_BUILD_ARGUMENTS  -Dmaven.test.skip=true package  the arguments to pass to Maven$BP_MAVEN_BUILT_ARTIFACT   target/*.[jw]ar                 the built application artifact explicitly.  Supersedes $BP_MAVEN_BUILT_MODULE$BP_MAVEN_BUILT_MODULE                                     the module to find application artifact inCreating cache directory /home/cnb/.m2

Compiled Application: Contributing to layer

Executing mvnw --batch-mode -Dmaven.test.skip=true package

[ ... Maven build output ... ]

[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 53.474 s
[INFO] Finished at: 2021-07-23T20:10:28Z
[INFO] ------------------------------------------------------------------------
Removing source code

Paketo Executable JAR Buildpack 5.1.2
https://github.com/paketo-bui...
Class Path: Contributing to layer

Writing env/CLASSPATH.delimWriting env/CLASSPATH.prepend

Process types:

executable-jar: java org.springframework.boot.loader.JarLauncher (direct)task:           java org.springframework.boot.loader.JarLauncher (direct)web:            java org.springframework.boot.loader.JarLauncher (direct)

Paketo Spring Boot Buildpack 4.4.2
https://github.com/paketo-bui...
Creating slices from layers index

dependenciesspring-boot-loadersnapshot-dependenciesapplication

Launch Helper: Contributing to layer

Creating /layers/paketo-buildpacks_spring-boot/helper/exec.d/spring-cloud-bindings

Spring Cloud Bindings 1.7.1: Contributing to layer

Downloading from https://repo.spring.io/release/org/springframework/cloud/spring-cloud-bindings/1.7.1/spring-cloud-bindings-1.7.1.jarVerifying checksumCopying to /layers/paketo-buildpacks_spring-boot/spring-cloud-bindings

Web Application Type: Contributing to layer

Reactive web application detectedWriting env.launch/BPL_JVM_THREAD_COUNT.default

4 application slices
Image labels:

org.opencontainers.image.titleorg.opencontainers.image.versionorg.springframework.boot.version

===> EXPORTING
Adding layer 'paketo-buildpacks/ca-certificates:helper'
Adding layer 'paketo-buildpacks/bellsoft-liberica:helper'
Adding layer 'paketo-buildpacks/bellsoft-liberica:java-security-properties'
Adding layer 'paketo-buildpacks/bellsoft-liberica:jre'
Adding layer 'paketo-buildpacks/bellsoft-liberica:jvmkill'
Adding layer 'paketo-buildpacks/executable-jar:classpath'
Adding layer 'paketo-buildpacks/spring-boot:helper'
Adding layer 'paketo-buildpacks/spring-boot:spring-cloud-bindings'
Adding layer 'paketo-buildpacks/spring-boot:web-application-type'
Adding 5/5 app layer(s)
Adding layer 'launcher'
Adding layer 'config'
Adding layer 'process-types'
Adding label 'io.buildpacks.lifecycle.metadata'
Adding label 'io.buildpacks.build.metadata'
Adding label 'io.buildpacks.project.metadata'
Adding label 'org.opencontainers.image.title'
Adding label 'org.opencontainers.image.version'
Adding label 'org.springframework.boot.version'
Setting default process type 'web'
Saving myorg/myapp...
* Images (ed1f92885df0):

  myorg/myapp

Adding cache layer 'paketo-buildpacks/bellsoft-liberica:jdk'
Adding cache layer 'paketo-buildpacks/maven:application'
Adding cache layer 'paketo-buildpacks/maven:cache'
Successfully built image 'myorg/myapp'复制
这--builder是一个运行 buildpack 生命周期的 Docker 镜像。通常,它将是所有开发人员或单个平台上的所有开发人员的共享资源。您能够在命令行上设置默认构建器(在 中创立一个文件~/.pack),而后从后续构建中省略该标记。

构建器
paketobuildpacks/builder:base还晓得如何从可执行 JAR 文件构建映像,因而您能够先应用 Maven 构建,而后将其指向--pathJAR 文件以取得雷同的后果。

原生
容器和平台畛域的另一个新我的项目是Knative。如果您不相熟它,能够将其视为构建无服务器平台的构建块。它建设在Kubernetes 之上,因而最终它会应用容器镜像并将它们转化为平台上的应用程序或“服务”。不过,它的次要性能之一是可能应用源代码并为您构建容器,使其对开发人员和操作员更加敌对。Knative Build是执行此操作的组件,它自身就是一个灵便的平台,用于将用户代码转换为容器——您简直能够以任何您喜爱的形式进行操作。一些模板提供了通用模式(例如 Maven 和 Gradle 构建)和多阶段 docker 构建应用卡尼科。还有一个模板应用了Buildpacks,这对咱们来说很乏味,因为 buildpacks 始终对 Spring Boot 有很好的反对。

完结
本指南提供了许多用于为 Spring Boot 应用程序构建容器映像的选项。所有这些都是齐全无效的抉择,当初由您决定您须要哪一个。您的第一个问题应该是“我真的须要构建容器映像吗?” 如果答案是“是”,那么您的抉择可能会受到效率、可缓存性和关注点拆散的驱动。您是否想让开发人员无需过多理解容器镜像的创立形式?当须要修补操作系统和中间件破绽时,您是否想让开发人员负责更新映像?或者,开发人员可能须要齐全管制整个过程,并且他们领有所需的所有工具和常识。

文末备注:
Spring Boot Docker起源:Spring中国教育管理中心