【CI/CD技术专题】「Docker实战系列」使用Maven插件构建Docker镜像的方法

> 本文介绍了使用Maven插件构建Docker镜像的方法,分享给大家,具体如下: ### 工具 > **工欲善其事,必先利其器。笔者经过调研,有以下几款Docker的Maven插件进入笔者视野。** ### 插件名称+官方地址 - **docker-maven-plugin https://github.com/spotify/docker-maven-plugin** - docker-maven-plugin https://github.com/fabric8io/docker-maven-plugin - docker-maven-plugin https://github.com/bibryam/docker-maven-plugin ### 修改宿主机配置(docker可以远程访问) - 修改宿主机的docker配置,让其支持远程访问。 ```shell vi /usr/lib/systemd/system/docker.service ``` 开启docker远程API,修改docker配置文件 docker.service进入编辑模式后。 >**ExecStart=后添加配置-H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock** > 保存后退出,重新加载配置文件#systemctl daemon-reload ,启动docker #systemctl start docker 。 - 刷新配置,重新服务 ```` systemctl daemon-reload systemctl restart docker ```` ### 配置 DOCKER_HOST > **docker-maven-plugin 插件默认连接本地 Docker 地址为:localhost:2375,所以我们需要先设置下环境变量。** ```` DOCKER_HOST=tcp://:2375 ```` > **注意:如果没有设置 DOCKER_HOST 环境变量,可以命令行显示指定 DOCKER_HOST 来执行,如我本机指定 DOCKER_HOST:DOCKER_HOST=tcp://:2375** #### 例如 - ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock ,这里就写4个0,你可别改成自己的ip哦, - 输入`#netstat -anp|grep 2375` 显示docker正在监听2375端口,输入#curl 127.0.0.1:2375/info 显示一大堆信息,证明远程api就弄好了 - 在windows系统环境变量中新建DOCKER_HOST,值为tcp://10.100.74.220:2375,(你改成你自己的docker服务器ip地址) ![](https://oscimg.oschina.net/oscnet/up-2c04bc3d1be5808783efad705729d2e026b.png) ### 使用插件构建Docker镜像 > **在我们持续集成过程中,项目工程一般使用 Maven 编译打包,然后生成镜像,通过镜像上线,能够大大提供上线效率,同时能够快速动态扩容,快速回滚,着实很方便。docker-maven-plugin 插件就是为了帮助我们在Maven工程中,通过简单的配置,自动生成镜像并推送到仓库中**。 #### 添加插件 在pom.xml中添加下面这段: ```xml 添加相关的镜像插件 ``` ### 构建镜像 > **构建镜像可以使用一下两种方式,第一种是将构建信息指定到 POM 中,第二种是使用已存在的 Dockerfile 构建**。(支持将 FROM, ENTRYPOINT, CMD, MAINTAINER 以及 ADD 信息配置在 POM 中,不需要使用 Dockerfile 配置。) - 第一种方式,支持将 FROM, ENTRYPOINT, CMD, MAINTAINER 以及 ADD 信息配置在 POM 中,不需要使用 Dockerfile 配置 - 第二种方式,如果使用 VOLUME 或其他 Dockerfile 中的命令的时候,需要创建一个 Dockerfile,并在 POM 中配置 dockerDirectory 来指定路径即可。(创建一个 Dockerfile,并在 POM 中配置 dockerDirectory 来指定路径即可) ##### 添加docker-maven-plugin ```xml com.spotifydocker-maven-plugin0.4.13${project.basedir}/src/main/docker   {dockerhub名称/imageName}{imageTag}{baseImage}{end[point]}author author@email.com/ROOT/${project.build.directory}${project.build.finalName}.jar ``` - {dockerhub名称/imageName}: - dockerhub名称:对应DockerHub用户名,,一定要是符合正则[a-z0-9-_.]的,否则构建不会成功 - imageName:对应 DockerHub 仓库名,一定要是符合正则[a-z0-9-_.]的,否则构建不会成功 - 可以直接指定:**${project.groupId}/${project.artifactId}** - {imageTag}:镜像标签,相当于标签或者版本,latest。 - {baseImage}: 指定基础镜像,等同 FROM 指令,例如:java,当然可以不用,直接在dockerfile文件中生成。 - {endpoint}:// 等同于 ENTRYPOINT 指令,例如: ["java","-jar","app.jar"] > 这里是复制 jar 包到 docker 容器指定目录配置,也可以写到 Dockerfile中 - {project.build.directory}:指定要复制的根目录,${project.build.directory} 表示 target 目录。 - {project.build.finalName}:指定要复制的文件,${project.build.finalName}.jar 指打包后的 jar 文件。 - resources.resource.targetPath:将打包后的资源文件复制到该目录; - resources.resource.directory:需要复制的文件所在目录,maven打包的应用jar包保存在target目录下面; - resources.resource.include:需要复制的文件,打包好的应用jar包。 > **读取 Dockerfile 文件就不必指定 baseImage 和 entrypoint** - 指定要读取的Dockerfile文件: ```` ${project.basedir}/src/main/docker ```` #### 创建Dockerfile > \src\main\docker ![](https://oscimg.oschina.net/oscnet/up-4b2d1072e04bd031005d09ba54876498f59.png) ##### 内容如下 ```` FROM java:8 VOLUME /tmp ADD admin-service-80-0.0.1-SNAPSHOT.jar admin-service-80.jar RUN bash -c 'touch /admin-service-80.jar' EXPOSE 80 ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","${project.build.finalName}.jar"] ```` ##### 执行以下命令构建 Docker 镜像 > **mvn clean package docker:build** ```` [INFO] --- docker-maven-plugin:1.0.0:build (default-cli) @ mavenDemo --- [INFO] Building image mavendemo Step 1/5 : FROM java ---> d23bdf5b1b1b Step 2/5 : MAINTAINER docker_maven docker_maven@email.com ---> Using cache ---> 2faf180d4a50 Step 3/5 : WORKDIR /ROOT ---> Using cache ---> 862210f7956a Step 4/5 : ENTRYPOINT java -jar mavenDemo.jar ---> Running in 96bbe83de6ec ---> c29009c88993 Removing intermediate container 96bbe83de6ec Step 5/5 : CMD java -version ---> Running in f69b8d2a75b1 ---> bc8d54014325 Removing intermediate container f69b8d2a75b1 Successfully built bc8d54014325 ```` ![](https://oscimg.oschina.net/oscnet/up-21150a195e57d0bba686bf78d467d4910a5.png) 执行 docker images 查看刚才构建的镜像 #### 执行命令 - mvn clean package docker:build:只执行 build 操作 - mvn clean package docker:build -DpushImage 执行 build 完成后 push 镜像 - mvn clean package docker:build -DpushImageTag 执行 build 并 push 指定 tag 的镜像 > **注意:这里必须指定至少一个 imageTag,它可以配置到POM 中,也可以在命令行指定**。 #### 命令行指定如下: **mvn clean package docker:build -DpushImageTags -DdockerImageTags=imageTag_1 -DdockerImageTags=imageTag_2**,POM 文件中指定配置如下: ```` ... ... imageTag_1imageTag_2 ... ```` ### 绑定Docker 命令到 Maven 各个阶段 - **可以绑定 Docker 命令到 Maven 各个阶段,我们可以把 Docker 分为 build、tag、push,然后分别绑定 Maven 的 package、deploy 阶段。** - **只需要执行mvn deploy就可以完成整个 build、tag、push操作了,当我们执行mvn build就只完成 build、tag 操作**。 - 除此此外,当我们想跳过某些步骤或者只执行某个步骤时,不需要修改 POM 文件,只需要指定跳过 docker 某个步骤即可。比如当我们工程已经配置好了自动化模板了,但是这次我们只需要打镜像到本地自测。 - 不想执行 push 阶段,那么此时执行要指定参数-DskipDockerPush就可跳过 push 操作了。 > 以上示例,当我们执行mvn package时,执行 build、tag 操作,当执行mvn deploy时,执行build、tag、push 操作。如果我们想跳过 docker 某个过程时,只需要: - -DskipDockerBuild 跳过 build 镜像 - -DskipDockerTag 跳过 tag 镜像 - -DskipDockerPush 跳过 push 镜像 - -DskipDocker 跳过整个阶段 > **例如:我们想执行 package 时,跳过 tag 过程,那么就需要mvn package -DskipDockerTag。** ``` com.spotifydocker-maven-plugin1.0.0mavendemojavadocker_maven docker_maven@email.com/ROOT["java", "-version"]["java", "-jar", "${project.build.finalName}.jar"]/ROOT${project.build.directory}${project.build.finalName}.jarbuild-imagepackagebuildtag-imagepackagetagmavendemo:latest docker.io/wanyang3/mavendemo:${project.version}push-imagedeploypushdocker.io/wanyang3/mavendemo:${project.version} ```` **docker-maven-plugin 插件还提供了很多很实用的配置,稍微列举几个参数吧。** ![](https://oscimg.oschina.net/oscnet/up-0fb6804bcda73bb288983de45b90db66283.png) ### 安全认证配置 > **当我们 push 镜像到 Docker 仓库中时,不管是共有还是私有,经常会需要安全认证,登录完成之后才可以进行操作。当然,我们可以通过命令行 `docker login -u user_name -p password docker_registry_host ` 登录,但是对于自动化流程来说,就不是很方便了。使用 docker-maven-plugin 插件我们可以很容易实现安全认证**。 > **首先在 Maven 的配置文件 setting.xml 中增加相关 server 配置,主要配置 Docker registry用户认证信息**。 ```` my-docker-registrywanyang312345678wanyang3@mail.com ```` 然后只需要在 pom.xml 中使用 server id 即可。 ```` com.spotifydocker-maven-plugin1.0.0registry.example.com/wanyang3/mavendemo:v1.0.0 ... my-docker-registry ```` ### 使用私有Docker仓库地址 > **实际工作环境中,我们需要 push 镜像到我们私有 Docker 仓库中,使用d ocker-maven-plugin 插件我们也是很容易实现,有几种方式实现**: #### 修改 POM 文件 imageName 操作 ```` {privateImageHubUrl}/imageName/tag ... ```` 以以上的格式进行输出即可。 #### 修改 POM 文件中 newName 操作 ```` mavendemo ... tag-imagepackagetagmavendemo {privateImageHubUrl}/imageName/tag ```` #### 重新启动Docker服务 ```` systemctl stop docker systemctl start docker ```` #### 开启防火墙的Docker构建端口 > **firewall-cmd --zone=public --add-port=2375/tcp --permanentfirewall-cmd --reload**
上一篇:mysql事件之修改事件(ALTER EVENT)&禁用事件(DISABLE)&启用事件(ENABLE)&事件重命名&数据库事件迁移


下一篇:Jenkins Ci系列目录