使用maven-docker工具快速构建可交付的java-web镜像

容器的出现让 Java开发人员比以往任何时候都更接近“编写一次,到处运行”的工作流程,然而在实际的工作中并非这样的~!要实现这样的诉求,首先你必须编写 Dockerfile,以 root身份运行 Docker守护进程,等待构建完成,最后将镜像推送到远程注册中心。说实话,Dockerfile有多复杂也有文章讲过,但并非所有的 Java开发人员都是容器专家。下面带着这些疑问,给大家介绍下java开源世界常用docker-maven-plugin、dockerfile-maven-plugin、jib-maven-plugin,工具的好坏,重要的看自己的喜好。

One-JAR的魅力在于:

  • 可以用 java -jar 机制执行。
  • 能够包含应用程序需要的 所有文件 —— 也就是说, 包括原始形式(未展开)的类和资源。
  • 拥有简单的内部结构,仅仅用 jar工具就可以被装配起来。
  • 对原来的应用程序不可见 —— 也就是说,无需修改原来的应用程序,就可以把它打包在 One-JAR 档案文件内部。

目录

1. docker-maven-plugin

历程

声明构建信息

使用Dockerfile

构建

使用私有镜像中心

认证

2. dockerfile-maven-plugin

约束

示例

它可以带来什么?

授权

配置

3. jib-maven-plugin

快速开始


1. docker-maven-plugin

2016-4月份由Spotify开源的,当前版本v1.1.1,一个,用于构建和上传docker镜像的Maven插件,官方介绍

历程

这个插件是Spotify使用的最初的Maven插件,用于从Java服务中构建DOCKERr镜像。它最初创建于2014,当我们第一次开始试验Docker。这个插件能够基于pom.xml文件中的配置为您生成一个Dockerfile,用于FROM映像、添加ADD/COPY等内容。

Spotify随着时间的推移,我们意识到,从Java项目中构建DOCKERr镜像最简单的方法是让开发人员编写DOCKFILE文件。这个插件在生成Dockerfile、将项目目录复制到“.ing”目录以作为Docker构建上下文等等方面的行为最终导致了与用户之间的许多不必要的混淆,这些混淆源于引入额外的抽象和对配置的需要。最重要的是Docker提供的东西。

这导致创建了用于构建docker映像的第二个Maven插件,dockerfile-maven,我们认为它为使用来自Maven的Docker提供了一个更简单的思维模型,原因都在dockerfile-maven的README中列出。

默认情况下,该插件通过访问localhost:2375来连接本地docker,可以通过设置DOCKER_HOST 环境变量来连接docker.

DOCKER_HOST=tcp://:2375

声明构建信息

此示例创建一个名为example的新镜像,将项目的jar文件复制到镜像中,并设置运行jar的入口点。更改版本到最新的标签版本。


  com.spotify
  docker-maven-plugin
  VERSION GOES HERE
  
    example
    java
    ["java", "-jar", "/${project.build.finalName}.jar"]
    
    
       
         /
         ${project.build.directory}
         ${project.build.finalName}.jar
       
    
  

参数解释:

  • imageName:镜像的名称,可以通过${project.groupId}/${project.artifactId}:${project.version} 动态制定镜像名称。当然也可以在前面加上镜像地址,比如127.0.0.1:5000,以声明将构建好的镜像存储在本地
  • baseImage: 基础镜像,这里是相当于Dockerfile的FROM java
  • resources 下的配置:构建时会生成docker文件夹,这里指生成文件夹的内容来源,包含了mvn clean package 之后的target的文件和生成的jar包。

使用Dockerfile

为了使用Dockerfile,必须在pom的文件中通过dockerDirectory来指明Dockerfile文件的所在目录。如果配置了dockerDirectory,baseImage,maintainer,cmd和entryPoint配置将忽略。下面的配置会将dockerDirectory的内容拷贝值${project.build.directory}/docker,使用resouces元素可以拷贝其他的文件,比如生成jar包文件。


  com.spotify
  docker-maven-plugin
  VERSION GOES HERE
  
    example
    docker
    
       
         /
         ${project.build.directory}
         ${project.build.finalName}.jar
       
    
  

构建

  • 生成一个镜像,mvn clean package docker:build
  • 将生成的镜像推送到镜像注册中心,mvn clean package docker:build -DpushImage
  • 如果推送制定tags 的镜像,​​​​​​​mvn clean package docker:build -DpushImageTag

绑定docker命令到maven phases


  com.spotify
  docker-maven-plugin
  VERSION GOES HERE
  
    
      build-image
      package
      
        build
      
    
    
      tag-image
      package
      
        tag
      
      
        my-image:${project.version}
        registry.example.com/my-image:${project.version}
      
    
    
      push-image
      deploy
      
        push
      
      
        registry.example.com/my-image:${project.version}
      
            
  

可以通过一下命令跳过docker构建的阶段

  • DskipDockerBuild 跳过镜像构建
  • DskipDockerTag 跳过镜像tag设置
  • DskipDockerPush 跳过镜像推送
  • DskipDocker 跳过所有的镜像构建目标

删除一个名称为foobar的镜像
mvn docker:removeImage -DimageName=foobar
获取完成的配置选项列表
mvn com.spotify:docker-maven-plugin::help -Ddetail=true

使用私有镜像中心

为了将镜像推送到私有的镜像注册中心,docker需要在镜像tag之前用注册中心的地址作为前缀。比如需要推送my-image到registry.example.com,那么这个镜像需要命名为registry.example.com/my-image
最简单的方法就是在中配置:


  com.spotify
  docker-maven-plugin
  
    registry.example.com/my-image
...

这样,当你通过命令docker:build -DpushImage或者docker:push推送镜像时,docker引擎会将镜像推送到registry.example.com.

当然你可以在docker:build命令中通过 docker:tag -DpushImage对创建的镜像加上私有镜像注册中心的地址,如不配置,则会推送到默认的镜像中心,即Docker hub;你也可如下这样配置:


  com.spotify
  docker-maven-plugin
  
    my-image
    ...
  
  
    
      build-image
      package
      
        build
      
    
    
      tag-image
      package
      
        tag
      
      
        my-image
        registry.example.com/my-image
      
    
  

认证

支持三种认证方式:
1. 读取本地配置文件,自动认证
从1.0.0版本之后,docker-maven-plugin插件会自动读取到docker-cli的认证配置,默认在~/.dockercfg 和~/.docker/config.json,而无需额外的配置

2. GCR认证
如果本机配置DOCKER_GOOGLE_CREDENTIALS的环境变量,则会使用GCR认证。

3. Server认证



  
    docker-hub
    foo
    secret-password
    
      [email protected]
    
  



  com.spotify
  docker-maven-plugin
  VERSION GOES HERE
  
    [...]
    docker-hub
    https://index.docker.io/v1/
  

以上三种配置方式中,通过读取客户端默认配置的优先级更高。

在server配置中加密密码
为了不在配置文件中不暴露明文密码,可以使用maven加密功能对密码进行加密,通过{ }方式都认为是被加密的密码


  
    docker-hub
    foo
    {gc4QPLrlgPwHZjAhPw8JPuGzaPitzuyjeBojwCz88j4=}
  

2. dockerfile-maven-plugin

上面讲过,Spotify的第二个版本,官方介绍

  • 不要做任何花哨的事。dockerfile是如何构建DOCKER项目;这就是插件使用的内容。它们是强制性的。
  • 使DOCKER构建过程与Maven构建过程集成。如果绑定默认阶段,则在键入mvn package时,会得到docker映像。当您键入mvn deploy时,您的镜像会被推送。
  • 让目标记住你在做什么。您可以键入mvn dockerfile:buildmvn dockerfile:tag和稍后的mvn dockerfile:push无问题。这也消除了对诸如mvn dockerfile:build -DalsoPush之类的东西的需求;相反,您可以只说mvn dockerfile:build dockerfile:push
  • 与Maven构建集成。您可以依赖于另一个项目中的一个项目的DOCKERr镜像,而Maven将按照正确的顺序构建项目。当您想要运行涉及多个服务的集成测试时,这是有用的。

约束

这个插件需要Java 7或更高版本和Apache Maven 3或更高版本。要运行集成测试或在实践中使用插件,需要一个docker环境。

示例


  com.spotify
  dockerfile-maven-plugin
  ${dockerfile-maven-version}
  
    
      default
      
        build
        push
      
    
  
  
    spotify/foobar
    ${project.version}
    
      ${project.build.finalName}.jar
    
  

对应的docker镜像可以是:

FROM openjdk:8-jre
MAINTAINER David Flemström 

ENTRYPOINT ["/usr/bin/java", "-jar", "/usr/share/myservice/myservice.jar"]

# Add Maven dependencies (not shaded into the artifact; Docker-cached)
ADD target/lib           /usr/share/myservice/lib
# Add the service itself
ARG JAR_FILE
ADD target/${JAR_FILE} /usr/share/myservice/myservice.jar

它可以带来什么?

1.更快的建造时间,这个插件允许您更一致地利用Docker缓存,通过让您在映像中缓存Maven依赖项,极大地加快了构建的速度。它还鼓励避免maven-shade-plugin,这也大大加快了构建。

2.一致的构建生命周期

mvn package
mvn dockerfile:build
mvn verify
mvn dockerfile:push
mvn deploy

3.依赖docker镜像上的其他服务,您可以依赖于另一个项目的Docker信息,因为这个插件在构建Docker映像时附加项目元数据。只需将此信息添加到任何项目

4.使用依赖Dockerfiles的其他docker工具


a/
     Dockerfile
     pom.xml
b/
     Dockerfile
     pom.xml

service-a:
  build: a/
  ports:
  - '80'

service-b:
  build: b/
  links:
  - service-a

授权

更多

配置

更多

3. jib-maven-plugin

google 于2018-7开源的,通过 Jib,我们不需要编写 Dockerfile 或安装 Docker,通过集成到 Maven 或 Gradle 插件,就可以立即将 Java 应用程序容器化。官方介绍

优点

  • 无需编写Dockerfile,甚至无需安装docker
  • 无需再执行docker build、push命令了
  • 增量构建镜像,无需每次编译项目先打包jar

缺点

  • 默认拉取的基础镜像是gcr仓库需要(可以国内的阿里云镜像服务),并且jdk默认是openjdk
  • 在拉取自定义的基础镜像和push构建的镜像这块,设计的不够友好,依赖需要第三方的加密组件(折腾了好一会);
  • 侵入性太强,需要每个项目都添加上maven插件。如果是现有方案,只需要添加一个Dockerfile就可以了,而且定制化高
  • 只支持java平台

快速开始


    4.0.0
    com.alex.sample.lib
    helloworld-samples
    0.1
    jar
    helloworld-samples
    
        UTF-8
        1.0.2
        3.8.0
    
    
    
    
        
            
                org.apache.maven.plugins
                maven-compiler-plugin
                ${maven-compiler-plugin.version}
                
                    1.8
                    1.8
                
            
            
            
                com.google.cloud.tools
                jib-maven-plugin
                ${jib-maven-plugin.version}
                
                    
                        registry.cn-hangzhou.aliyuncs.com/alex/oracle_java8
                    
                    
                        registry.cn-hangzhou.aliyuncs.com/alex/jib-helloworld:v1
                    
                    
                        
                            -Xms512m
                            -Xdebug
                        
                        com.alex.HelloWorld
                    
                
                
                    
                        package
                        
                            build
                        
                    
                
            
        
    



  
    ...
        
        registry.cn-hangzhou.aliyuncs.com
        你的阿里云账号
        你的阿里云密码
        
  

构建镜像
mvn compile jib:build
把镜像直接构建到本地docker中
mvn compile jib:dockerBuild
把镜像直接构建到本地磁盘(target/jib-image.tar)
mvn compile jib:buildTar
这样,可以从本地启动
docker load --input target/jib-image.tar
导出一个Docker context
mvn compile jib:exportDockerContext -DjibTargetDir=my/docker/context/
可以使用docker build image
docker build -t myimage my/docker/context/

其他参数说明,更多

最后,工具没有好坏之说,但个人推荐使用jib-maven-plugin,功能特性上稍稍丰富一些,另外就是google的魅力。

你可能感兴趣的:(Java,工具,系统运维)