Jenkins服务器更新密钥后任务构建不了的排查实录与解决方案

 更新时间:2026年05月22日 09:15:13   作者:Linux运维技术栈  
在一次生产环境的 SSH 密钥轮换中,我遇到了一个极其令人困惑的问题:在 Jenkins 服务器上手动执行 ssh -i 命令测试新密钥到目标服务器,直接报 Permission denied,本文记录了完整的排查过程,希望能帮助遇到类似故障的运维人员快速定位问题,需要的朋友可以参考下

前言:在一次生产环境的 SSH 密钥轮换中,我遇到了一个极其令人困惑的问题:在 Jenkins 服务器上手动执行 ssh -i 命令测试新密钥到目标服务器,直接报 Permission denied;将同样的命令放入 Jenkins 任务脚本中,同样失败。 在排除了文件权限、换行符、known_hosts 等所有常见原因后,最终发现是 ssh-agent 缓存的老密钥在“作祟”,而解决方法是在 ~/.ssh/config 中为堡垒机单独配置 IdentitiesOnly yes

本文记录了完整的排查过程,希望能帮助遇到类似“幽灵”故障的运维人员快速定位问题。

一、现象:手动测试失败,Jenkins 任务也失败

在 Jenkins 服务器上执行以下命令手动测试新密钥:

ssh -i ~/.ssh/id_ed25519_new -J user@bastion_ip:22222 target_ip "echo '连通'"

结果:Permission denied

再将同样的命令放入 Jenkins 任务脚本中:

scp -i ~/.ssh/id_ed25519_new -o 'ProxyJump user@bastion_ip:22222' ...

结果: Jenkins 控制台同样输出 Permission denied

手动与脚本表现一致——说明问题不在 Jenkins 任务执行环境,而在基础的 SSH 连接链路本身。

二、排查:绕过的弯路

  1. 检查服务器端 authorized_keys:确认新公钥已正确添加,权限为 600,文件末尾有换行符。
  2. 重置 known_hostsssh-keygen -R bastion_ip,无效。
  3. 在脚本中增加参数-o StrictHostKeyChecking=no,依然报 Permission denied
  4. 清空 ssh-agent 缓存ssh-add -D,依然无效。

这些操作均无法解决问题,说明问题不在表面,而在 SSH 认证的深层机制。

三、真相:SSH 的密钥优先级顺序

经过反复验证,发现 SSH 在认证时的密钥优先级是:

  1. 最高优先级ssh-agent 中缓存的密钥。
  2. 中间优先级:命令行 -i 参数指定的密钥。
  3. 最低优先级:~/.ssh/id_rsa 等默认密钥。

在 Jenkins 节点上,后台进程悄悄地启动了 ssh-agent,并将旧的 id_rsa 密钥加载了进去。

当我们在手动测试或 Jenkins 脚本中执行 ssh -i ~/.ssh/id_ed25519_new ... 时,SSH 客户端会优先问 ssh-agent:“你有能用的钥匙吗?”

ssh-agent 回答:“有,我这里有 id_rsa。”

于是 SSH 尝试用 旧密钥 id_rsa 去连接堡垒机。此时,堡垒机上的老公钥已被删除,认证失败,连接被服务端直接切断。切断后,SSH 根本没机会再去尝试你 -i 指定的新密钥。

这就是为什么手动测试和 Jenkins 任务都失败的根本原因。

四、终极解决方案:配置~/.ssh/config

在 Jenkins 节点上,修改 ~/.ssh/config 文件,为堡垒机添加强制隔离配置

Host bastion_ip
    IdentitiesOnly yes
    IdentityFile ~/.ssh/id_ed25519_new
    StrictHostKeyChecking no
    UserKnownHostsFile /dev/null

核心参数解析:

  • bastion_ip:指构建任务时的目标服务器的ip,这里可以配制多个,用空格隔开,比如10.0.0.1 10.0.0.2 10.0.0.3
  • IdentitiesOnly yes:强制 SSH 客户端只使用 IdentityFile 指定的密钥,完全忽略 ssh-agent 中缓存的所有密钥。这是解决“-i 参数失效”的关键。
  • IdentityFile:指定要使用的新密钥文件。
  • StrictHostKeyChecking no & UserKnownHostsFile /dev/null:跳过主机指纹校验,避免 SSH 在自动化环境中卡住。

五、验证与成果

添加配置后,再次执行手动测试命令(不再需要 -i 参数):

ssh -J user@bastion_ip:22222 target_ip "echo '连通'"

结果: 成功输出 连通

直接重跑 Jenkins 任务——构建成功,密钥轮换完成

六、经验总结:下次轮换密钥该怎么做?

  1. 不要依赖脚本里的 -i 参数:在 Jenkins 这种有 ssh-agent 的环境里,单独指定 -i 往往不可靠,因为 ssh-agent 的优先级更高。
  2. 善用 ~/.ssh/config:为跳板机或目标服务器单独配置 IdentitiesOnly yesIdentityFile,可以做到“一劳永逸”。
  3. 清理服务器端的旧公钥:确保新公钥是唯一可用的。
  4. 后续轮换:下次更新密钥时,你只需要修改 ~/.ssh/config 里的 IdentityFile 路径,所有 Jenkins 任务会自动切换到新密钥,无需修改任何 Jenkins 脚本。

希望这篇博客能帮你快速定位这类 Jenkins 密钥更新后的连接失败问题。如果你也遇到过类似的“幽灵”报错,不妨试试在 ~/.ssh/config 里加上 IdentitiesOnly yes,或许能节省数小时的不必要排查。

以上就是Jenkins服务器更新密钥后任务构建不了的排查实录与解决方案的详细内容,更多关于Jenkins更新密钥后任务无法构建解决的资料请关注脚本之家其它相关文章!

相关文章

  • springMVC常见视图组件与RESTFul编程风格详解

    springMVC常见视图组件与RESTFul编程风格详解

    本文给大家介绍springMVC常见视图组件与RESTFul编程风格,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2026-02-02
  • 浅谈@RequestMapping注解的注意点

    浅谈@RequestMapping注解的注意点

    这篇文章主要介绍了浅谈@RequestMapping注解的注意点,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-02-02
  • 简述Java编程之关系操作符

    简述Java编程之关系操作符

    这篇文章主要介绍了简述Java编程中的关系操作符,同时对比较类作了简单介绍,需要的朋友可以参考下
    2017-09-09
  • Spring 5.0集成log4j2日志管理的示例代码

    Spring 5.0集成log4j2日志管理的示例代码

    本篇文章主要介绍了Spring 5.0集成log4j2日志管理的示例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-12-12
  • Spring核心容器之BeanDefinition解析

    Spring核心容器之BeanDefinition解析

    这篇文章主要介绍了Spring核心容器之BeanDefinition解析,Spring 将管理的对象称之为 Bean,容器会先实例化 Bean,然后自动注入,实例化的过程就需要依赖 BeanDefinition,需要的朋友可以参考下
    2023-11-11
  • Java语法关于泛型与类型擦除的分析

    Java语法关于泛型与类型擦除的分析

    泛型没有其看起来那么深不可测,它并不神秘与神奇,泛型是Java 中一个很小巧的概念,但同时也是一个很容易让人迷惑的知识点,它让人迷惑的地方在于它的许多表现有点违反直觉
    2021-09-09
  • Java实现对华北、华南、华东和华中四个区域的划分

    Java实现对华北、华南、华东和华中四个区域的划分

    在Java中,通过定义枚举类、编写主程序和进行测试,本文详细介绍了如何划分华北、华南、华东和华中四个区域,首先定义枚举类标识区域,然后通过主程序接收用户输入并返回相应区域,最后通过测试用例确保正确性,文章还介绍了甘特图和饼状图的使用
    2024-09-09
  • Java 确保某个Bean类被最后执行的几种实现方式

    Java 确保某个Bean类被最后执行的几种实现方式

    这篇文章主要介绍了Java 确保某个BeanDefinitionRegistryPostProcessor Bean被最后执行的几种实现方式,帮助大家更好的理解和学习使用Java,感兴趣的朋友可以了解下
    2021-03-03
  • SpringBoot整合Ip2region获取IP地址和定位的详细过程

    SpringBoot整合Ip2region获取IP地址和定位的详细过程

    ip2region v2.0 - 是一个离线IP地址定位库和IP定位数据管理框架,10微秒级别的查询效率,提供了众多主流编程语言的 xdb 数据生成和查询客户端实现 ,这篇文章主要介绍了SpringBoot整合Ip2region获取IP地址和定位,需要的朋友可以参考下
    2023-06-06
  • Maven项目打包成可执行Jar文件步骤解析

    Maven项目打包成可执行Jar文件步骤解析

    这篇文章主要介绍了Maven项目如何打包成可执行Jar文件,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-05-05

最新评论