You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过SSH从Jenkins Worker节点在远程主机执行多条命令?

Jenkins声明式流水线通过SSH执行远程多命令方案

问题场景

需要在Jenkins声明式流水线的部署阶段,从指定Worker节点通过SSH连接Docker宿主机,顺序执行以下部署命令:

cd myDirectory
docker stack deploy --compose-file docker-compose.yml foo

当前已实现单条SSH命令执行,但多命令执行配置运行失败,错误配置如下:

pipeline {
  agent { label 'onlyMyHost' }
  stages {
    stage("checkout"){...}

    stage("build"){...}

    stage("deploy") {
      steps {
        sshagent(credentials: ['my-sshKey']){
          sh 'ssh -o StrictHostKeyChecking=no myUser@foo.bar.com hostname'
          sh ("""
            ssh -o StrictHostKeyChecking=no myUser@foo.bar.com 'bash -s' < "cd MyDirectory && docker stack deploy --composefile docker-compose.yml foo"
          """)
        }
      }
    }
  }
}

失败根因

  1. bash -s用法错误:bash -s从标准输入读取待执行脚本,当前写法中<后接的是命令字符串而非本地脚本文件路径,SSH无法获取到要执行的完整内容
  2. 命令存在拼写错误:docker stack deploy的参数为--compose-file,配置中误写为--composefile;目标目录名大小写不匹配(原目录为myDirectory,配置中写为MyDirectory)
  3. 引号嵌套逻辑错误:双引号包裹的命令内容会被本地shell提前解析,无法完整传递到远程主机执行

可行实现方案

方案1:单行拼接多命令(适合短命令场景,配置最简单)

SSH原生支持在连接参数后直接携带远程执行命令,多条命令用&&拼接即可,无需额外调用bash -s,注意统一使用外层双引号包裹远程命令、路径写绝对路径避免工作目录不确定问题:

stage("deploy") {
  steps {
    sshagent(credentials: ['my-sshKey']){
      sh 'ssh -o StrictHostKeyChecking=no myUser@foo.bar.com "cd /data/app/myDirectory && docker stack deploy --compose-file docker-compose.yml foo"'
    }
  }
}

方案2:here-doc传递多行脚本(适合多步命令场景,可读性强)

如果需要执行的命令较多,挤在单行可读性差,可以用here-doc语法将多行脚本通过标准输入传给远程bash执行,注意<< 'EOF'的单引号不能省略,避免本地shell提前解析脚本内的变量:

stage("deploy") {
  steps {
    sshagent(credentials: ['my-sshKey']){
      sh '''
        ssh -o StrictHostKeyChecking=no myUser@foo.bar.com bash -s << 'EOF'
          cd /data/app/myDirectory
          # 可按需添加更多顺序执行的命令
          docker stack deploy --compose-file docker-compose.yml foo
        EOF
      '''
    }
  }
}

方案3:上传脚本后远程执行(适合复杂部署逻辑场景,易维护)

如果部署逻辑涉及条件判断、多文件操作等复杂流程,可以先在代码仓库中维护独立的部署脚本,构建阶段先通过scp将脚本传到远程主机,再SSH调用执行:

stage("deploy") {
  steps {
    sshagent(credentials: ['my-sshKey']){
      // 给本地部署脚本加执行权限后传到远程临时目录
      sh 'chmod +x ./script/deploy.sh && scp -o StrictHostKeyChecking=no ./script/deploy.sh myUser@foo.bar.com:/tmp/'
      // 执行远程脚本
      sh 'ssh -o StrictHostKeyChecking=no myUser@foo.bar.com "/tmp/deploy.sh"'
    }
  }
}

对应的deploy.sh脚本内容示例:

#!/bin/bash
set -e # 任意命令执行失败则退出,避免后续逻辑异常
cd /data/app/myDirectory
docker stack deploy --compose-file docker-compose.yml foo

注意事项

  • 远程执行cd操作时必须使用绝对路径,不要依赖SSH登录后的默认工作目录,避免路径不存在报错
  • 提前确认SSH登录的远程用户myUser具备docker操作权限(属于docker用户组),否则会出现docker命令权限不足错误
  • -o StrictHostKeyChecking=no参数仅建议在内网测试环境使用,生产环境建议提前将远程主机的SSH指纹录入Jenkins Worker节点的known_hosts文件,降低安全风险

内容的提问来源于stack exchange,提问作者Human

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.02 04:06:31