背景
项目中用 Jenkins 实现自动化部署,背后用 maven 的 wagon-plugin 插件,打包完成后自动完成上传操作。这样的好处就 Jenkins 的部署脚本不用写繁琐的部署命令了,直接通过调用 mvn wagon:upload-single wagon:sshexec
就可以完成了,相当简单。
本周修改了打包配置,需要重新发布到一台新机器上,Jenkins 执行完打包后,在构建脚本运行过程中一直报一个异常:
js
RSA key fingerprint is 63:3a:30:bb:eb:fd:69:d1:a0:10:41:c5:17:2d:cb:8a.
Are you sure you want to continue connecting?(yes/no):The authenticity of host '192.168.xx.xx'can't
be established.
RSA key fingerprint is 63:3a:30:bb:eb:fd:69:d1:a0:10:41:c5:17:2d:cb:8a.
Are you sure you want to continue connecting?(yes/no):The authenticity of host '192.168.xx.xx'can't
be established.
......
Jenkins 任务日志输出文本一直刷上面的信息,构建不结束,构建任务的 builds 目录日志文件多达20G,实际一次也没有构建成功过。
排查过程
我知道这个异常是因为 ssh 连接的目标主机未添加到当前主机的信任主机列表,所以手动在 jenkins 所在的机器上执行了 ssh 连接,并添加了可信任主机,但是任务依旧报错。
接着,怀疑是 ssh 连接问题,修改目标主机的 ssh 策略文件 /etc/ssh/ssh_config 添加 StrictHostKeyChecking no 配置,也不对。同时将 Jenkins 的 ssh 密钥 Key 发送到目标主机的 authorized_keys 中,能直接免密登录。
上面的操作执行完成后,任务构建过程中通过 wagon-plugin 插件命令执行SSH 上传的时候依旧报错。
修改脚本,直接用 scp 命令上传的话,任务构建能够成功了。所以想到了直接到 Jenkins 的任务的源码目录下执行 mvn wagon:upload-single 命令,也弹出上面的提示信息,输入 yes 后,再去构建任务就成功了。
问题:Jenkins 构建脚本中如果调用 mvn wagon 插件命令完成自动发布的话,如何避免首次发布时出现上面的连接提示信息呢?总不能每次都到源码目录下先手动执行一次吧,肯定有解决办法的。
解决方案
搜到了一篇
在 maven 的setting.xml
配置服务器 SSH 账号密码时,可以额外添加一个 StrictHostKeyChecking=no
配置、不弹出提示:
xml
<server>
<id>linux-server-44</id>
<configuration>
<StrictHostKeyChecking>no</StrictHostKeyChecking>
</configuration>
<username>root</username>
<password><![CDATA[xxx]]></password>
</server>
这样每次发布到新机器时就不会出现本文的问题了。
启示录
为什么在机器上已经设置了免密登录,wagon-plugin 插件还是在首次执行时弹出不信任主机提示信息呢?
我的思考:wagon-plugin 插件使用的 jsch 包实现 ssh 远程上传和命令执行的,它跟 Jenkins 所在机器的 ssh 服务不是同一个,它的本质也是一个 ssh 服务,所以它自己维护了可信任主机列表。
下面是一个常见的插件配置:
xml
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>wagon-maven-plugin</artifactId>
<version>2.0.2</version>
<configuration>
<serverId>${server-id}</serverId>
<fromFile>target/${project.artifactId}-${project.version}.jar</fromFile>
<url>scp://${IP}${Path}/</url>
<!-- 在服务器执行的命令集合 -->
<commands>
<!-- 1、所有需要执行的命令,必须放在一个 command 中,不同 command 属于不同的 ssh session,上一个 command 的 cd 对下一个命令无效了 -->
<!-- 2、远程执行shell脚本时,不会自动加载环境变量,会报java: command not found,所以需要执行一次环境变量加载-->
<command><![CDATA[cd ${Path}/bin; pwd; source /etc/profile;sh xx.sh]]></command>
</commands>
<!-- 显示运行命令的输出结果 -->
<displayCommandOutputs>true</displayCommandOutputs>
</configuration>
</plugin>
最后,再总结一下使用 wagon-plugin 插件需要注意地方:
- 插件用的密码如果
包含特殊字符
,必须在 maven 的 setting.xml 配置。 - url 配置 scp://IP/ 这个是固定语法,
scp 后面两个双斜杠
。 - commands 命令集合,不同 command 节点单独创建一个 Session,会话内容不共享,如果命令集之间有关联关系,
必须放在一个 command 标签中
,还需要注意环境变量的加载问题。 - 为避免本文出现的 Are you sure you want to continue connecting?(yes/no) 提示信息,可使用StrictHostKeyChecking 配置,scp 操作中加该配置也可以的。