java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > Jenkins更新密钥后任务无法构建解决

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

作者: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

核心参数解析:

五、验证与成果

添加配置后,再次执行手动测试命令(不再需要 -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更新密钥后任务无法构建解决的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文