【Spring Cloud 基础设施搭建系列】Spring Cloud Demo项目 将微服务运行在Docker上

将微服务运行在Docker上

我们需要把之前的微服务部署到docker上去,之前的微服务搭建可以翻看我博客的【Spring Cloud 基础设施搭建系列】

我对之前的一些配置进行了抽取,抽取了common的配置,并且放置到配置中心,还解决了Admin Server中无法获取Config Server的健康状态,解决方法是在Config Server的security配置中过滤掉"/actuator/health"端点。

在这里插入图片描述
可以参考我的gitee:
https://gitee.com/cckevincyh/spring-cloud-demo/tree/config-refactor/

这次我们主要讲一下如何使用Maven插件构建Docker镜像,如果对Docker不熟悉的可以先去看看Docker的基础使用。

使用Maven插件构建Docker镜像

Maven是一个强大的项目管理与构建工具。如果可以使用Maven构建Docker镜像,工作就能得到进一步的简化。

我们以cloud-eureka为例子,演示一下如何使用Maven插件构建Docker镜像

  1. 首先我们需要在parent pom文件中加入maven的插件。
    我们这里使用的是spotify的docker插件。
<plugin>
    <groupId>com.spotify</groupId>
    <artifactId>docker-maven-plugin</artifactId>
    <version>0.4.13</version>
    <configuration>
        <forceTags>true</forceTags>
        <imageName>spring-cloud-demo/${project.artifactId}:${project.version}</imageName>
        <baseImage>java</baseImage>
        <entryPoint>["java", "-jar", "/${project.build.finalName}.jar"]</entryPoint>
        <resources>
            <resource>
                <targetPath>/</targetPath>
                <directory>${project.build.directory}</directory>
                <include>${project.build.finalName}.jar</include>
            </resource>
        </resources>
    </configuration>
</plugin>

简要说明一下插件的配置:

  • imageName:用于指定镜像名称,其中spring-cloud-demo是仓库名称,${project.artifactId}是镜像名称, ${project.version}是标签名称。
  • baselmage:用于指定基础镜像,类似于Dockerfile中的FROM指令。
  • entrypoint:类似于Dockerfile的ENTRYPOINT指令。
  • resources.resource.directory:用于指定需要复制的根目录,${project.build.directory}
    表示target目录。
  • resources.resource.include:用于指定需要复制的文件。${project.build.finalName}.jar指的是打包后的jar包文件。

${project.build.finalName},${project.build.directory}对应的值到底是什么呢?

我们可以右键我们的cloud-eureka项目,找到Maven-> Show Effective POM,然后搜索finalName就可以找到。

在这里插入图片描述

在这里插入图片描述

其实${project.build.finalName}默认值就是为${project.artifactId}-${project.version}

我们搜directory就可以找到${project.build.directory}

在这里插入图片描述

其实${project.build.directory}是构建目录,默认为target目录

Maven内置变量说明:

  • ${basedir} 项目根目录
  • ${project.build.directory} 构建目录,缺省为target
  • ${project.build.outputDirectory} 构建过程输出目录,缺省为target/classes
  • ${project.build.finalName} 产出物名称,缺省为${project.artifactId}-${project.version}
  • ${project.packaging} 打包类型,缺省为jar
  • ${project.xxx} 当前pom文件的任意节点的内容

参考:

Maven学习笔记(一)——自定义maven变量以及maven内置常量

What is the value of project.build.finalName?

  1. 执行以下命令,构建Docker镜像
mvn clean package docker:build
C:\Users\c\Desktop\spring-cloud-demo\cloud-eureka>mvn clean package docker:build
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building cloud-eureka 1.0
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-clean-plugin:3.1.0:clean (default-clean) @ cloud-eureka ---
[INFO] Deleting C:\Users\c\Desktop\spring-cloud-demo\cloud-eureka\target
[INFO]
[INFO] --- maven-resources-plugin:3.1.0:resources (default-resources) @ cloud-eureka ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 1 resource
[INFO] Copying 0 resource
[INFO]
[INFO] --- maven-compiler-plugin:3.8.0:compile (default-compile) @ cloud-eureka ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 1 source file to C:\Users\c\Desktop\spring-cloud-demo\cloud-eureka\target\classes
[INFO]
[INFO] --- maven-resources-plugin:3.1.0:testResources (default-testResources) @ cloud-eureka ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory C:\Users\c\Desktop\spring-cloud-demo\cloud-eureka\src\test\resources
[INFO]
[INFO] --- maven-compiler-plugin:3.8.0:testCompile (default-testCompile) @ cloud-eureka ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] --- maven-surefire-plugin:2.22.1:test (default-test) @ cloud-eureka ---
[INFO] No tests to run.
[INFO]
[INFO] --- maven-jar-plugin:3.1.0:jar (default-jar) @ cloud-eureka ---
[INFO] Building jar: C:\Users\c\Desktop\spring-cloud-demo\cloud-eureka\target\cloud-eureka-1.0.jar
[INFO]
[INFO] --- spring-boot-maven-plugin:2.1.1.RELEASE:repackage (repackage) @ cloud-eureka ---
[INFO] Replacing main artifact with repackaged archive
[INFO]
[INFO] --- docker-maven-plugin:0.4.13:build (default-cli) @ cloud-eureka ---
[INFO] Copying C:\Users\c\Desktop\spring-cloud-demo\cloud-eureka\target\cloud-eureka-1.0.jar -> C:\Users\c\Desktop\spring-cloud-demo\cloud-eureka\target\docker\cloud-eu
reka-1.0.jar
[INFO] Building image cloud-demo/cloud-eureka:1.0
Step 1/3 : FROM java

Pulling from library/java
5040bd298390: Pulling fs layer
fce5728aad85: Pulling fs layer
76610ec20bf5: Pulling fs layer
60170fec2151: Pulling fs layer
e98f73de8f0d: Pulling fs layer
11f7af24ed9c: Pulling fs layer
49e2d6393f32: Pulling fs layer
bb9cdec9c7f3: Pulling fs layer
60170fec2151: Waiting
e98f73de8f0d: Waiting
11f7af24ed9c: Waiting
49e2d6393f32: Waiting
bb9cdec9c7f3: Waiting
fce5728aad85: Downloading [>                                                  ]  185.7kB/18.54MB
fce5728aad85: Downloading [=>                                                 ]  371.9kB/18.54MB
76610ec20bf5: Downloading [>                                                  ]  425.1kB/42.5MB
5040bd298390: Downloading [>                                                  ]  514.7kB/51.36MB
fce5728aad85: Downloading [=>                                                 ]  558.1kB/18.54MB
fce5728aad85: Downloading [==>                                                ]  744.3kB/18.54MB
76610ec20bf5: Downloading [=>                                                 ]  850.7kB/42.5MB
76610ec20bf5: Downloading [=>                                                 ]  1.276MB/42.5MB
fce5728aad85: Downloading [===>                                               ]  1.303MB/18.54MB
fce5728aad85: Downloading [====>                                              ]  1.489MB/18.54MB
5040bd298390: Downloading [==>                                                ]  2.056MB/51.36MB
76610ec20bf5: Downloading [==>                                                ]  1.702MB/42.5MB
fce5728aad85: Downloading [====>                                              ]  
49e2d6393f32: Downloading [=========================================>         ]  108.1MB/130.1MB
49e2d6393f32: Downloading [=========================================>         ]  108.7MB/130.1MB
49e2d6393f32: Downloading [=============================================>     ]  117.6MB/130.1MB
49e2d6393f32: Downloading [=============================================>     ]  124.4MB/130.1MB
49e2d6393f32: Downloading [================================================>  ]  124.9MB/130.1MB
49e2d6393f32: Downloading [================================================>  ]  125.5MB/130.1MB
49e2d6393f32: Downloading [=================================================> ]  128.6MB/130.1MB
49e2d6393f32: Downloading [=================================================> ]  129.1MB/130.1MB
49e2d6393f32: Downloading [=================================================> ]  129.7MB/130.1MB
49e2d6393f32: Verifying Checksum
49e2d6393f32: Download complete
49e2d6393f32: Extracting [>                                                  ]  557.1kB/130.1MB
49e2d6393f32: Extracting [>                                                  ]  1.671MB/130.1MB
49e2d6393f32: Extracting [=>                                                 ]  2.785MB/130.1MB
49e2d6393f32: Extracting [=>                                                 ]  
49e2d6393f32: Extracting [===============================================>   ]  122.6MB/130.1MB
49e2d6393f32: Extracting [===============================================>   ]  123.7MB/130.1MB
49e2d6393f32: Extracting [===============================================>   ]  124.8MB/130.1MB
49e2d6393f32: Extracting [================================================>  ]  125.3MB/130.1MB
49e2d6393f32: Extracting [================================================>  ]  126.5MB/130.1MB
49e2d6393f32: Extracting [================================================>  ]    127MB/130.1MB
49e2d6393f32: Extracting [=================================================> ]  127.6MB/130.1MB
49e2d6393f32: Extracting [=================================================> ]  129.8MB/130.1MB
49e2d6393f32: Extracting [==================================================>]  130.1MB/130.1MB
49e2d6393f32: Pull complete
bb9cdec9c7f3: Extracting [=====>                                             ]  32.77kB/289kB
bb9cdec9c7f3: Extracting [==================================================>]    289kB/289kB
bb9cdec9c7f3: Extracting [==================================================>]    289kB/289kB
bb9cdec9c7f3: Pull complete
?[0BDigest: sha256:c1ff613e8ba25833d2e1940da0940c3824f03f802c449f3d1815a66b7f8c0e9d
Status: Downloaded newer image for java:latest
 ---> d23bdf5b1b1b
Step 2/3 : ADD /cloud-eureka-1.0.jar //

 ---> 11356e5b9dea
Step 3/3 : ENTRYPOINT ["java", "-jar", "/cloud-eureka-1.0.jar"]

 ---> Running in 710837e5de27
Removing intermediate container 710837e5de27
 ---> 2bddac8bfef7
ProgressMessage{id=null, status=null, stream=null, error=null, progress=null, progressDetail=null}
Successfully built 2bddac8bfef7
Successfully tagged cloud-demo/cloud-eureka:1.0
[INFO] Built cloud-demo/cloud-eureka:1.0
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 03:13 min
[INFO] Finished at: 2019-10-19T22:31:44+08:00
[INFO] Final Memory: 72M/555M
[INFO] ------------------------------------------------------------------------

由以上日志可知,已成功构建了一个Docker镜像。

  1. 执行docker images命令,即可查看刚刚构建的镜像。
$ docker images
REPOSITORY                TAG                 IMAGE ID            CREATED             SIZE
cloud-demo/cloud-eureka   1.0                 2bddac8bfef7        10 minutes ago      687MB
  1. 启动以下镜像:
$ docker run -d -p 8888:8888 cloud-demo/cloud-eureka:1.0
9105eacca9aa7dc01d6285aef9571b1397c70040bdb691515fe2d3b9e2c66882
  1. 访问测试
    访问 http://Docker 宿主机IP:8888,能够看到Eureka Server的首页。

我们这里访问 http://192.168.99.100:8888/

在这里插入图片描述

使用Maven插件读取Dockerfile进行构建

之前的示例直接在pom.xml中设置了一些构建的参数。很多场景下希望使用Dockerfile更精确、有可读性地构建镜像。

  1. 首先在/cloud-eureka/src/main/docker目录下,新建一个Dockerfile文件
FROM java:8
VOLUME /tmp
ADD cloud-eureka-1.0.jar app.jar
RUN bash -c 'touch /app.jar'
EXPOSE 8888
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]

VOLUME 指定挂载点

  • 该指令使容器中的一个目录具有持久化存储的功能,该目录可被容器本身使用,也可共享给其他容器。当容器中的应用有持久化数据的需求时可以在Dockerfile中使用该指令。

ADD复制文件

  • ADD指令用于复制文件

EXPOSE声明暴露的端口

  • EXPOSE指令用于声明在运行时容器提供服务的端口
  1. 修改pom.xml
<plugin>
        <groupId>com.spotify</groupId>
        <artifactId>docker-maven-plugin</artifactId>
        <version>0.4.13</version>
        <configuration>
            <imageName>cloud-demo/${project.artifactId}:${project.version}</imageName>
            <dockerDirectory>${project.basedir}/src/main/docker</dockerDirectory>
            <resources>
                <resource>
                    <targetPath>/</targetPath>
                    <directory>${project.build.directory}</directory>
                    <include>${project.build.finalName}.jar</include>
                </resource>
            </resources>
        </configuration>
    </plugin>

可以看到,不再指定baselImage和entrypoint,而是使用dockerDirectory指定Dockerfile所在的路径。这样,就可以使用Dockerfile构建Docker镜像了。

  1. 使用如下命令构建Docker镜像
C:\Users\c\Desktop\spring-cloud-demo\cloud-eureka>mvn clean package docker:build
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building cloud-eureka 1.0
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-clean-plugin:3.1.0:clean (default-clean) @ cloud-eureka ---
[INFO] Deleting C:\Users\c\Desktop\spring-cloud-demo\cloud-eureka\target
[INFO]
[INFO] --- maven-resources-plugin:3.1.0:resources (default-resources) @ cloud-eureka ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 1 resource
[INFO] Copying 0 resource
[INFO]
[INFO] --- maven-compiler-plugin:3.8.0:compile (default-compile) @ cloud-eureka ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 1 source file to C:\Users\c\Desktop\spring-cloud-demo\cloud-eureka\target\classes
[INFO]
[INFO] --- maven-resources-plugin:3.1.0:testResources (default-testResources) @ cloud-eureka ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory C:\Users\c\Desktop\spring-cloud-demo\cloud-eureka\src\test\resources
[INFO]
[INFO] --- maven-compiler-plugin:3.8.0:testCompile (default-testCompile) @ cloud-eureka ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] --- maven-surefire-plugin:2.22.1:test (default-test) @ cloud-eureka ---
[INFO] No tests to run.
[INFO]
[INFO] --- maven-jar-plugin:3.1.0:jar (default-jar) @ cloud-eureka ---
[INFO] Building jar: C:\Users\c\Desktop\spring-cloud-demo\cloud-eureka\target\cloud-eureka-1.0.jar
[INFO]
[INFO] --- spring-boot-maven-plugin:2.1.1.RELEASE:repackage (repackage) @ cloud-eureka ---
[INFO] Replacing main artifact with repackaged archive
[INFO]
[INFO] --- docker-maven-plugin:0.4.13:build (default-cli) @ cloud-eureka ---
[INFO] Copying C:\Users\c\Desktop\spring-cloud-demo\cloud-eureka\target\cloud-eureka-1.0.jar -> C:\Users\c\Desktop\spring-cloud-demo\cloud-eureka\target\docker\cloud-eu
reka-1.0.jar
[INFO] Copying C:\Users\c\Desktop\spring-cloud-demo\cloud-eureka\src\main\docker\Dockerfile -> C:\Users\c\Desktop\spring-cloud-demo\cloud-eureka\target\docker\Dockerfil
e
[INFO] Building image cloud-demo/cloud-eureka:1.0
Step 1/6 : FROM java:8

 ---> d23bdf5b1b1b
Step 2/6 : VOLUME /tmp

 ---> Running in 13880234da8c
Removing intermediate container 13880234da8c
 ---> f7fd43313aa4
Step 3/6 : ADD cloud-eureka-1.0.jar app.jar

 ---> 97ea89c50ce4
Step 4/6 : RUN bash -c 'touch /app.jar'

 ---> Running in 4d22bd44a2e2
Removing intermediate container 4d22bd44a2e2
 ---> cf215d997e1f
Step 5/6 : EXPOSE 8888

 ---> Running in 69445855b134
Removing intermediate container 69445855b134
 ---> bc31140fabd9
Step 6/6 : ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]

 ---> Running in c8b6f5d2e1a2
Removing intermediate container c8b6f5d2e1a2
 ---> 25404f35b2ab
ProgressMessage{id=null, status=null, stream=null, error=null, progress=null, progressDetail=null}
Successfully built 25404f35b2ab
Successfully tagged cloud-demo/cloud-eureka:1.0
[INFO] Built cloud-demo/cloud-eureka:1.0
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 16.740 s
[INFO] Finished at: 2019-10-20T13:05:05+08:00
[INFO] Final Memory: 64M/556M
[INFO] ------------------------------------------------------------------------

  1. 测试访问 http://192.168.99.100:8888/

在这里插入图片描述

将插件绑定在某个phase执行

很多场景下,有这样的需求,执行例如mvn clean package时,插件就自动为构建 Docker镜像。要想实现这点,只须将插件的goal绑定在某个phase即可。

phase和goal可以这样理解:maven命令格式是:mvn phase:goal,例如mvn package docker
:build。那么,package和docker都是phase,build则是goal。示例:

<plugin>
    <groupId>com.spotify</groupId>
    <artifactId>docker-maven-plugin</artifactId>
    <version>0.4.13</version>
    <executions>
        <execution>
            <id>build-image</id>
            <phase>package</phase>
            <goals>
                <goal>build</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <imageName>cloud-demo/${project.artifactId}:${project.version}</imageName>
        <dockerDirectory>${project.basedir}/src/main/docker</dockerDirectory>
        <resources>
            <resource>
                <targetPath>/</targetPath>
                <directory>${project.build.directory}</directory>
                <include>${project.build.finalName}.jar</include>
            </resource>
        </resources>
    </configuration>
</plugin>

由配置可知,只须添加如下配置:

<executions>
    <execution>
        <id>build-image</id>
        <phase>package</phase>
        <goals>
            <goal>build</goal>
        </goals>
    </execution>
</executions>

就可将插件绑定在package这个phase上。也就是说,用户只须执行mvn package,就会自动执行mvn docker:build。当然,读者也可按照需求,将插件绑定到其他的phase。

然后我们执行如下命令就可以进行构建了。

C:\Users\c\Desktop\spring-cloud-demo\cloud-eureka>mvn clean package
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building cloud-eureka 1.0
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-clean-plugin:3.1.0:clean (default-clean) @ cloud-eureka ---
[INFO] Deleting C:\Users\c\Desktop\spring-cloud-demo\cloud-eureka\target
[INFO]
[INFO] --- maven-resources-plugin:3.1.0:resources (default-resources) @ cloud-eureka ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 1 resource
[INFO] Copying 0 resource
[INFO]
[INFO] --- maven-compiler-plugin:3.8.0:compile (default-compile) @ cloud-eureka ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 1 source file to C:\Users\c\Desktop\spring-cloud-demo\cloud-eureka\target\classes
[INFO]
[INFO] --- maven-resources-plugin:3.1.0:testResources (default-testResources) @ cloud-eureka ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory C:\Users\c\Desktop\spring-cloud-demo\cloud-eureka\src\test\resources
[INFO]
[INFO] --- maven-compiler-plugin:3.8.0:testCompile (default-testCompile) @ cloud-eureka ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] --- maven-surefire-plugin:2.22.1:test (default-test) @ cloud-eureka ---
[INFO] No tests to run.
[INFO]
[INFO] --- maven-jar-plugin:3.1.0:jar (default-jar) @ cloud-eureka ---
[INFO] Building jar: C:\Users\c\Desktop\spring-cloud-demo\cloud-eureka\target\cloud-eureka-1.0.jar
[INFO]
[INFO] --- spring-boot-maven-plugin:2.1.1.RELEASE:repackage (repackage) @ cloud-eureka ---
[INFO] Replacing main artifact with repackaged archive
[INFO]
[INFO] --- docker-maven-plugin:0.4.13:build (build-image) @ cloud-eureka ---
[INFO] Copying C:\Users\c\Desktop\spring-cloud-demo\cloud-eureka\target\cloud-eureka-1.0.jar -> C:\Users\c\Desktop\spring-cloud-demo\cloud-eureka\target\docker\cloud-eu
reka-1.0.jar
[INFO] Copying C:\Users\c\Desktop\spring-cloud-demo\cloud-eureka\src\main\docker\Dockerfile -> C:\Users\c\Desktop\spring-cloud-demo\cloud-eureka\target\docker\Dockerfil
e
[INFO] Building image cloud-demo/cloud-eureka:1.0
Step 1/6 : FROM java:8

 ---> d23bdf5b1b1b
Step 2/6 : VOLUME /tmp

 ---> Using cache
 ---> f7fd43313aa4
Step 3/6 : ADD cloud-eureka-1.0.jar app.jar

 ---> e742c02ab4a0
Step 4/6 : RUN bash -c 'touch /app.jar'

 ---> Running in 1f5ab28f9f32
Removing intermediate container 1f5ab28f9f32
 ---> edd847fd6a8b
Step 5/6 : EXPOSE 8888

 ---> Running in 9190d4137a96
Removing intermediate container 9190d4137a96
 ---> 4e557d99ebca
Step 6/6 : ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]

 ---> Running in d2d566d49093
Removing intermediate container d2d566d49093
 ---> 96101741ff95
ProgressMessage{id=null, status=null, stream=null, error=null, progress=null, progressDetail=null}
Successfully built 96101741ff95
Successfully tagged cloud-demo/cloud-eureka:1.0
[INFO] Built cloud-demo/cloud-eureka:1.0
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 19.664 s
[INFO] Finished at: 2019-10-20T18:20:16+08:00
[INFO] Final Memory: 64M/581M
[INFO] ------------------------------------------------------------------------
C:\Users\c\Desktop\spring-cloud-demo\cloud-eureka>

参考

SecureRandom生成随机数超慢 导致tomcat启动时间过长的解决办法

SecureRandom产生随机数性能优化 -Djava.security.egd=file:/dev/./urandom

Maven学习笔记(一)——自定义maven变量以及maven内置常量

What is the value of project.build.finalName?

使用Maven插件构建Docker镜像

源代码

https://gitee.com/cckevincyh/spring-cloud-demo/tree/config-refactor/

https://gitee.com/cckevincyh/spring-cloud-demo/tree/release-docker/

https://gitee.com/cckevincyh/spring-cloud-demo/tree/release-docker-dockerfile/

发布了647 篇原创文章 · 获赞 816 · 访问量 98万+

猜你喜欢

转载自blog.csdn.net/cckevincyh/article/details/102652268
今日推荐