likes
comments
collection
share

Jenkins + wagon 自动化打包 Java 应用排坑记

作者站长头像
站长
· 阅读数 3

背景

项目中用 Jenkins 实现自动化部署,背后用 maven 的 wagon-plugin 插件,打包完成后自动完成上传操作。这样的好处是 Jenkins 的部署脚本不用写繁琐的部署命令了,直接通过调用 mvn wagon:upload-single wagon:sshexec 就可以完成了,相当简单。

本周修改了打包配置,需要重新发布到一台新机器上,Jenkins 执行完打包后,在构建脚本运行过程中一直报一个异常:

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 插件命令完成自动发布的话,如何避免首次发布时出现上面的连接提示信息呢?总不能每次都到源码目录下先手动执行一次吧,肯定有解决办法的。

解决方案

搜到了一篇

Jenkins + wagon 自动化打包 Java 应用排坑记

在 maven 的setting.xml 配置服务器 SSH 账号密码时,可以额外添加一个 StrictHostKeyChecking=no 配置、不弹出提示:

<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 服务,所以它自己维护了可信任主机列表。

下面是一个常见的插件配置:

<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 插件需要注意地方:

  1. 插件用的密码如果包含特殊字符,必须在 maven 的 setting.xml 配置。
  2. url 配置 scp://IP/ 这个是固定语法, scp 后面两个双斜杠
  3. commands 命令集合,不同 command 节点单独创建一个 Session,会话内容不共享,如果命令集之间有关联关系, 必须放在一个 command 标签中 ,还需要注意环境变量的加载问题。
  4. 为避免本文出现的 Are you sure you want to continue connecting?(yes/no) 提示信息,可使用StrictHostKeyChecking 配置,scp 操作中加该配置也可以的。