前言:在基于Jenkins的自动化部署场景中,“跳板机转发+内网服务器部署”是常见架构。近期我在维护这类任务时,遇到了:Jenkins构建时SCP/SSH命令执行异常,但手动执行正常 的问题,最终通过加载环境变量得以解决。现将整个排查过程整理为博客,供大家参考。
一、问题现象:构建失败,手动执行却正常
我的部署场景是:Jenkins以普通用户(jenkins)运行,任务需要先通过跳板机(<跳板机用户>@<跳板机IP>),再连接内网目标服务器(如<目标机用户>@<目标机IP>),执行scp传包和ssh启动应用。
但Jenkins构建时,控制台频繁报SCP/SSH命令执行失败,可我切换到jenkins用户手动执行相同命令时,却能正常完成跳板机转发和部署。
二、场景分析:Jenkins的“非交互式shell”环境陷阱
Jenkins的“执行shell”构建步骤,本质是非交互式shell,它不会自动加载用户的~/.bashrc或~/.profile等环境配置文件。
而我手动执行命令时,是交互式shell(通过终端登录),会自动加载~/.bashrc中的环境变量(比如PATH、命令别名、SSH客户端的隐式配置等)。这就导致了“手动正常,构建异常”的差异——Jenkins执行环境缺失了关键的环境变量依赖。
三、原因深挖:source ~/.bashrc的关键作用
为了让Jenkins的非交互式shell也能加载完整的环境变量,我在构建脚本开头添加了:
source ~/.bashrc
这行命令的作用是强制加载jenkins用户的bash环境配置,补全以下关键依赖:
- 自定义的
PATH(确保scp、ssh等命令的路径可识别); - SSH客户端的隐式配置(如私钥路径、代理转发规则等);
- 系统级工具的初始化脚本(如
/etc/profile.d下的环境变量)。
四、解决步骤:加载环境变量+验证
步骤1:修改Jenkins构建脚本
在原有部署脚本的开头,添加source ~/.bashrc,示例完整脚本如下:
# 加载jenkins用户的bash环境变量,补全非交互式shell的环境缺失
source ~/.bashrc
# 通用参数定义
app_port=<应用端口> # 如8080
app_path=<目标机应用路径> # 如/home/appuser/app/
archive_path=<目标机归档路径> # 如/home/appuser/archive/app/target
app_jar=<应用jar包名> # 如app-service-1.0.0.jar
# SCP通过跳板机传包(跳板机端口为<跳板机端口>)
scp -o 'ProxyJump <跳板机用户>@<跳板机IP> -p <跳板机端口>' ${WORKSPACE}/target/*.jar <目标机用户>@<目标机IP>:$archive_path/
# SSH通过跳板机执行部署命令
ssh -tt -J <跳板机用户>@<跳板机IP>:<跳板机端口> <目标机用户>@<目标机IP> << eeooff
cd $app_path
# 复制归档文件到应用目录
cp $archive_path/$app_jar $app_path
# 停止旧进程(根据端口筛选)
pgrep -f $app_port | xargs kill -9
# 启动新进程(后台运行并输出日志)
nohup java -jar -server -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=$app_path/heapdump -Xms1g -Xmx1g $app_jar --server.port=$app_port --spring.profiles.active=<环境标识> 2>&1 &>> $app_path/log.txt &
exit
eeooff
# 等待启动完成
sleep 10
步骤2:验证构建结果
重新触发Jenkins构建,观察控制台日志:
- 若
scp成功传包、ssh成功执行部署命令,且最终构建状态为“SUCCESS”,则说明环境变量加载生效。
五、延伸:.ssh/config的小插曲(可选优化)
在排查过程中,还遇到过.ssh/config配置项错误的问题(如Bad configuration option)。这类问题的解决思路是:
- 登录Jenkins节点,切换到
jenkins用户,检查~/.ssh/config的语法; - 修正拼写错误或不兼容的配置项(如将错误的
ignoreusernownhosts改为合法配置),确保SSH客户端能正常解析。
六、总结
在Jenkins通过跳板机部署的场景中,“环境变量缺失”是“手动正常、构建异常”的常见诱因。通过source ~/.bashrc强制加载环境变量,可快速补全非交互式shell的依赖,保障自动化流程的稳定性。
同时,若涉及SSH配置文件(.ssh/config),需注意语法规范性,避免因配置错误中断流程。希望这篇博客能帮助大家少走弯路~

6962

被折叠的 条评论
为什么被折叠?



