fabric8io的插件不仅支持通过dockerfile和docker-compose文件进行docker镜像构造(build),镜像推送(push),还支持对容器操作(如run,stop,remove等),也就是说它可以实现对Docker从构建镜像到运行和推送完整的控制流程,这是它独树一帜的地方.
在众多docker-maven插件中,fabric8io的docker-maven-plugin毫无疑问是最强大的.
现在网上相关的教程大多是使用spotify的,本人一开始也是用spotify,但发现使用起来很有局限性,然后就找其他的docker-maven插件,最终挖掘到了fabric8io的插件.简单来说,spotify能做的事,fabric8io都能做,而且fabric8io选择更多,功能更多.
下面用fabric8io和spotify代指其插件
首先,在对比之前,要先认识一个观点,不管使用哪一种docker插件来构造image,都比不上直接用Dockerfile编写简单,而且可复用,不用学习不同插件不同的构造规则.这一点也在spotify的github项目的README文档里有特别强调,为此他们还特地开发了一个dockerfile-maven插件,这个插件强制要求使用Dockerfile,他们认为这才是正途,事实也是如此.
很多人选择用spotify是因为所谓"从Stars、文档易用性以及更新频率三个纬度考虑",那下面我们就先从这三者来做简单的对比.再对比功能.
截至目前(2018年7月),fabric8io的star数是900+,spotify的dockerfile-maven是800+,两者差不多,比较多的是spotify的docker-maven-plugin(1500+),但spotify也说了,用docker-maven-plugin不如用dockerfile-maven简单(不然也不需要多做这个插件出来),所以Stars这里是基本持平的
这里毫无疑问是spotify的文档更容易用,因为不管是docker-maven-plugin还是dockerfile-maven,spotify的所谓文档都只是放在对应github项目的首页,就是一份README的MarkDown文档而已,可读性很强,可以简单上手.相信这也是spotify插件拥有大量Stars的原因.
相比之下,fabric8io的github的README相当于什么都没写,就只是简单粗暴地给了用户手册的访问链接,虽然也有一个简单的"introlmd",但是对于构建项目没有太大的帮助,最后还是得来看用户手册
fabric8io的用户手册内容相当丰富,这也是因为它功能比较强大.所以这里见仁见智.另外,如果使用Dockerfile和docker-compose文件的话,其实可以避开大部分的配置,剩下的配置都是因为它额外的功能,所以其文档虽然复杂,但配置却可以很简单.
截至目前,fabric8io最近一次更新推送是在12天前,spotify的两个项目则是在两个月前.
这才是要比较的重点,也是 fabric8io全面碾压spotify的地方
截至到2019年1月。
spotify才刚刚支持自定义dockerfile文件的位置,在这之前dockerfile必须安装一定的规则放置才行。对于docker-compose.yml文件的支持为零。
fabric8io很早就支持自定义dockerfile文件和docker-compose.yml文件的导入了。不过目前对docker-compose.yml版本不支持3.0及更新。对于我目前来说是够用了,以后希望会更新支持。
对于我这种喜欢把启动参数放在docker-compose文件的人来说,对docker-compose的支持很重要,而且这样就完全剥离了插件对docker构建和运行参数的繁琐配置了。
fabric8io的有两大功能:
也就是说通过fabric8io的docker插件,我们可以实现对Docker从构建镜像到运行和推送完整的控制流程
而包括spotify在内的其他插件则仅有第一部分功能,即构造并推送镜像,而没有实现对容器的控制.这也是我使用fabric8io而不使用spotify的最主要原因.
spotify只支持在本机docker的镜像build、tag、push,而fabric8io可以用于远程主机,这个时候要注意 dockerHost 项的配置。
这里单独先列出来说是因为我在这里被坑了很久。
需要注意一下 dockerHost的配置和docker官方的配置规则不太一样,这里是个坑点
docker可以配置三种不同类型的Socket请求:unix,tcp,和 fd,其中 fd 和 unix 通常用于本机连接, tcp 用于 ip 连接。三者在 /etc/docker/daemon.json 的配置项为 "hosts"
,需要注意不支持 http(https)
fabric8io的 的dockerHost
支持 tcp 和http(https)两种格式
如果使用tcp则只能使用 2375 和 2376端口,分别对应不加密验证和加密验证
这个时候在url里配置其他端口是无效的。
(也就是说,服务器设置了监听 tcp:///0.0.0.0:9999,fabric8io的插件设置 tcp:公网ip:9999,也是无效的,这个时候如果启用了ssl加密的话就只能一起用 2376)
这个时候端口是可以自定义的
即是说直接用 http://公网ip(域名):9999 即可。
端口问题连接时会报错 : Cannot create docker access object
org.apache.http.ProtocolException: The server failed to respond with a valid HTTP response
如果是想要快速启动,可以参考下面的配置
远程Docker的控制和配置可以看这一篇文章:Docker 守护进程+远程连接+安全访问
下面使用Dockerfile完成docker镜像构建,使用docker-compose.yml完成docker容器启动参数控制
<plugin>
<groupId>io.fabric8</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>0.26.0</version>
<!--全局配置-->
<configuration>
<!--这一部分是为了实现对远程docker容器的控制-->
<!--docker主机地址,用于完成docker各项功能,注意是tcp不是http!-->
<dockerHost>tcp://公网IP:2376</dockerHost>
<!--docker远程访问所需证书地址,如果docker远程主机没有启用TLS验证则不需要配证书-->
<certPath>${project.basedir}/docker/ssh</certPath>
<!--这一部分是为了实现docker镜像的构建和推送-->
<!--registry地址,用于推送,拉取镜像,我这里用的是阿里的registry-->
<registry>registry.cn-shenzhen.aliyuncs.com</registry>
<!--认证配置,用于私有registry认证,如果忘记了可以去阿里的registry查看-->
<authConfig>
<push>
<username>这里填registry的用户名</username>
<password>这里填registry的密码</password>
</push>
</authConfig>
<!--镜像相关配置,支持多镜像-->
<images>
<!-- 单个镜像配置 -->
<image>
<!--镜像名(含版本号)-->
<name>命名空间/仓库名称:镜像版本号</name>
<!--别名:用于容器命名和在docker-compose.yml文件只能找到对应名字的配置-->
<alias>${project.name}</alias>
<!--镜像build相关配置-->
<build>
<!--使用dockerFile文件-->
<dockerFile>${project.basedir}/docker/${project.name}</dockerFile>
</build>
<!--配置docker-compose文件-->
<external>
<type>compose</type>
<basedir>${project.basedir}/docker</basedir>
<composeFile>docker-compose.yml</composeFile>
</external>
<!--容器run相关配置-->
<run>
<!--配置运行时容器命名策略为:别名,如果不指定则默认为none,即使用随机分配名称-->
<namingStrategy>alias</namingStrategy>
</run>
</image>
</images>
</configuration>
<dependencies>
<!--该插件需要这个依赖-->
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.11</version>
</dependency>
</dependencies>
</plugin>
可以看到,其实配置是相当简单清晰的,只要你确保Dockerfile和docker-compose.yml符合规范,能够使用,这个插件就可以代替你使用了,而你仅需要给它配置一些最基础的授权信息
maven指令 | 功能 |
---|---|
docker:start | 创建和启动容器 |
docker:stop | 停止并销毁容器 |
docker:build | 构建镜像 |
docker:watch | 自动进行重建和重启 |
docker:push | 将镜像推送到registry |
docker:remove | 从本地docker主机删除镜像 |
docker:logs | 显示容器日志 |
docker:source | 将docker build archive附加到Maven项目 |
docker:save | 将镜像保存到文件 |
docker:volume-create | 创建卷以在容器之间共享数据 |
docker:volume-remove | 删除创建的卷 |
注意,start和run是同义的,可以互相代替,另外,这里的stop和remove和在docker的不一样,docker的stop会保留容器,这里默认是停止并销毁(当然也可以在pom配置或mvn参数里指定keepContainer使其不销毁),但是我认为一般是不会用到暂停的,stop就是为了remove
这里我贴一下我常用的maven指令
这样就可以完成从打包到容器运行的完整流程
mvn clean package docker:stop docker:remove docker:build docker:run
不是每一次运行都要推送的,如果要的话可以单独调用docker:push
mvn docker:push
docker:run 这里有个坑,docker:run是在前台执行,也就是说,它并不能像使用docker一下直接docker start -d
来实现后台运行,所以如果是在命令行下启动的话,按Ctrl+C就直接退出了,方法是命令行下启动的时候使用如下指令包装成后台运行
nohup mvn docker:run &
如果是用IDE控制的话就不用担心,因为IDE只是监控运行日志而已,IDE这里退出不影响其在远程服务器上的运行.
另外,docker:run之后的指令不会运行,因为run之后它会监控Java程序的控制台输出直到运行结束,而一般Java Web程序是作为服务器一直运行的,所以就导致docker:run后面的指令不执行
解决方法有两个,第一,让docker:run放最后,第二,另外单独执行第二条mvn指令
参考:
github项目地址:https://github.com/fabric8io/docker-maven-plugin
用户手册:http://dmp.fabric8.io/