如何配置GitLab Shell Runner通过SSH在私有服务器执行命令
解决GitLab CI命令未在SSH目标服务器执行的问题
我来帮你搞定这个问题!核心问题是你当前的CI脚本写法只是建立了SSH连接,但后续的命令并没有在远程服务器上执行——它们依然会在GitLab Runner本地运行。咱们一步步修正配置:
先理清错误原因
你当前的脚本里:
ssh -A <user>@<remotehost>这行只是尝试启动一个交互式SSH会话,但CI环境是非交互式的,这个会话会立刻退出,后面的hostname等命令自然就回到Runner本地执行了。ssh-agent bash -c '...'这种写法是在本地的ssh-agent进程里启动bash执行命令,完全和远程服务器没关系,所以找不到PHP配置文件很正常。
正确的配置方式
1. 修正SSH密钥的加载步骤(避免Runner本地无密钥文件的问题)
原来的ssh-add < ~/.ssh/id_rsa可能有问题,因为Runner环境里不一定存在这个文件。咱们直接用CI变量SSH_PRIVATE_KEY生成临时密钥:
before_script: - echo "Before script section" # 安装ssh-agent及依赖(Docker环境用apt,CentOS替换为yum) - 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )' # 启动ssh-agent - eval $(ssh-agent -s) # 将CI变量中的私钥写入临时文件 - echo "$SSH_PRIVATE_KEY" | tr -d '\r' > ~/.ssh/id_rsa # 设置密钥文件权限(SSH要求必须是600) - chmod 600 ~/.ssh/id_rsa # 将密钥添加到agent - ssh-add ~/.ssh/id_rsa # 添加远程主机到known_hosts,避免首次连接的确认提示 - ssh-keyscan <remotehost> >> ~/.ssh/known_hosts - chmod 644 ~/.ssh/known_hosts
2. 在SSH命令中直接传递要执行的远程命令
要让命令在远程服务器执行,你需要把命令作为参数传递给ssh命令,或者用**here-doc( heredoc)**来写多行命令,可读性更好。
方式一:单条/多条命令用引号包裹
适合命令较少的场景:
build1: stage: build script: - echo "Pulling on Dev\n" # 用&&串联多个远程命令,所有命令都会在目标服务器执行 - ssh <user>@<remotehost> 'hostname && awk "NR==1{print;exit}" /etc/php7/php.ini'
方式二:用Heredoc写多行远程命令
适合需要执行多条命令的场景,注意要加'EOF'避免本地变量替换:
build1: stage: build script: - echo "Pulling on Dev\n" # 通过Heredoc传递多行命令到远程服务器 - ssh <user>@<remotehost> << 'EOF' echo "当前远程服务器主机名:" hostname echo "PHP配置文件第一行内容:" awk "NR==1{print;exit}" /etc/php7/php.ini # 这里可以继续添加你需要在远程执行的命令,比如拉代码、重启服务等 EOF
关键注意事项
- 确保远程服务器的
<user>账号有权限执行你要运行的命令(比如读取/etc/php7/php.ini)。 - 如果需要sudo权限,可以在远程命令前加
sudo,但要确保该用户无需输入密码即可sudo(可以在远程服务器的/etc/sudoers里配置免密)。 - 用
'EOF'而不是EOF是为了防止CI脚本把本地变量替换到远程命令里,如果你需要传递CI变量到远程,可以去掉单引号,但要注意转义。
内容的提问来源于stack exchange,提问作者til
相关产品推荐
相关产品推荐

