Apache DolphinScheduler SSH 数据源配置指南:为 RemoteShell 远程任务打通免代理执行通道
2026/9/15 7:23:43 网站建设 项目流程

Apache DolphinScheduler SSH 数据源配置指南:为 RemoteShell 远程任务打通免代理执行通道

【免费下载链接】dolphinschedulerApache DolphinScheduler is the modern data orchestration platform. Agile to create high performance workflow with low-code项目地址: https://gitcode.com/GitHub_Trending/dol/dolphinscheduler

SSH 数据源是 Apache DolphinScheduler 中一类特殊的非关系型数据源,专门服务于 RemoteShell(远程 Shell)任务组件,让工作流能够在不部署任何 Agent、不经过 Worker 本地进程的情况下,通过标准 SSH/SFTP 协议把脚本推送到远端主机并以nohup方式执行。本文以官方文档 SSH Data Source 为骨架,结合仓库中dolphinscheduler-datasource-sshdolphinscheduler-task-remoteshell两个插件的真实源码,完整讲解 SSH 数据源的字段含义、密码/公钥双认证机制、连接校验原理、插件激活方式以及 RemoteShell 任务消费该数据源的底层调用链,读完即可在集群中创建并正确使用 SSH 数据源完成远程命令编排。

SSH 数据源是什么:为远程命令执行而生

与 MySQL、PostgreSQL 等以 JDBC 建连的数据库数据源不同,SSH 数据源在 DolphinScheduler 中承担的是"远程主机连接凭据"的角色。官方文档开宗明义地指出:

This data source is used for RemoteShell component to execute commands remotely.

也就是说,创建 SSH 数据源的目的只有一个——供RemoteShell(远程 Shell)任务使用,让任务在执行时通过 SSH 连接一台远端主机,把脚本上传并在其上运行。这一设计规避了传统 Shell 任务"脚本必须在 Worker 所在节点本地执行"的约束,使工作流可以直接操作任意可达的服务器(如生产环境的应用主机、堡垒机后方的内网机器等),从而实现"编排平台与执行目标解耦"的远程执行能力。

从代码结构上看,SSH 数据源的能力边界非常清晰:SSHDataSourceProcessor不提供 JDBC URL、驱动或java.sql.Connection,其getJdbcUrlgetConnection均返回空/nullSSHDataSourceChannelcreatePooledDataSourceClientcreateAdHocDataSourceClient一律抛出UnsupportedOperationException(见 SSHDataSourceProcessor.java、SSHDataSourceChannel.java)。因此它不能像关系型数据源那样被 SQL 类任务消费,它唯一的职责就是向 RemoteShell 任务提供 SSH 连接参数。

创建 SSH 数据源:字段逐项说明

在 DolphinScheduler Web UI 中依次进入数据源中心 → 创建数据源,在类型下拉框中选择SSH,即可看到如下表单(对应仓库文档 ssh.md 所列字段,表单截图见 docs/img/new_ui/dev/datasource/ssh.png):

字段是否必填说明
Data Source数据源类型下拉框,此处选择SSH
Data Source Name数据源名称,全局唯一标识,便于在 RemoteShell 任务中引用
Description数据源描述,说明用途或归属
IP目标 SSH 主机 IP 或域名(文档中称为 IP Hostname)
PortSSH 服务端口,默认值为22
User Name登录 SSH 的用户名(表单默认值root
PasswordSSH 密码,用于密码认证
Public Key私钥内容(PEM 格式),用于公钥认证;与 Password 二选一即可

表单底部提供三个操作按钮:Cancel(取消)Test Connect(测试连接)Confirm(确认)。其中"Test Connect"会实际发起一次 SSH 认证握手,用于在保存前验证凭据是否正确。

从后端参数模型可以印证上述字段的落库结构。SSHConnectionParam(见 SSHConnectionParam.java)定义了userpasswordprivateKeyhostport(默认22)五个连接属性;SSHDataSourceParamDTO(见 SSHDataSourceParamDTO.java)在其基础上扩展了privateKey字段,类型标识为DbType.SSHSSHDataSourceProcessor.createConnectionParams负责把表单 DTO 转换为连接参数对象,并完整映射用户名、密码、主机、端口与私钥。

必填校验与唯一标识

在保存数据源时,SSHDataSourceProcessor.checkDatasourceParam会执行参数合法性校验(源码见 SSHDataSourceProcessor.java):

if (StringUtils.isEmpty(datasourceParamDTO.getHost()) || StringUtils.isEmpty(datasourceParamDTO.getUserName())) { throw new IllegalArgumentException("ssh datasource param is not valid"); }

也就是说,IP 与 User Name 是硬性必填项,缺失任一字段都会直接抛出IllegalArgumentException。而密码与公钥均允许为空——这对应了"密码、公钥至少配置其一即可完成认证"的设计(下文详解)。从源码看,仅当两者都缺失时认证才会在连接阶段失败。

此外,每个 SSH 数据源会通过getDatasourceUniqueId生成形如ssh@{host}@{user}@{加密后的密码}的唯一标识(见 SSHDataSourceProcessor.java),密码在存储前会经过PasswordUtils.encodePassword加密处理,避免凭据以明文形式落库。

双认证机制:密码与公钥的底层实现

SSH 数据源同时支持密码认证公钥认证两种方式,且可叠加配置。其底层基于 Apache MINA SSHD 客户端实现,核心逻辑位于 SSHUtils.java 的getSession方法:

session = client.connect(connectionParam.getUser(), connectionParam.getHost(), connectionParam.getPort()) .verify(5000).getSession(); // add password identity String password = connectionParam.getPassword(); if (StringUtils.isNotEmpty(password)) { session.addPasswordIdentity(password); } // add private key identity String privateKey = connectionParam.getPrivateKey(); if (StringUtils.isNotEmpty(privateKey)) { KeyPairResourceLoader loader = SecurityUtils.getKeyPairResourceParser(); Collection<KeyPair> keyPairCollection = loader.loadKeyPairs(null, null, null, privateKey); for (KeyPair keyPair : keyPairCollection) { session.addPublicKeyIdentity(keyPair); } } session.setSessionHeartbeat(SessionHeartbeatController.HeartbeatType.IGNORE, Duration.ofSeconds(3));

关键细节如下:

  • 连接建立:调用client.connect(user, host, port)并以5 秒为超时执行verify,随后getSession获取客户端会话;
  • 密码身份:只要password非空,就通过addPasswordIdentity注册密码身份;
  • 公钥身份:只要privateKey非空,就会调用SecurityUtils.getKeyPairResourceParser()解析 PEM 私钥,解析出的每个KeyPair都会通过addPublicKeyIdentity注册为公钥身份;解析失败会抛出Failed to add public key identity
  • 会话保活:设置每3 秒一次的IGNORE类型会话心跳,防止长任务执行期间连接被服务端或中间设备空闲断开。

同样的逻辑在SshClientWrapper(见 SshClientWrapper.java)中也有对应实现:构造时校验ipportuserName非空,随后按"先密码、后公钥"的顺序注册认证身份,并在isAuth()中以10 秒超时执行clientSession.auth().verify(...)判断认证是否成功。

实践建议:由于两种身份可以同时注册,即使同时填写了密码与公钥,只要任一种能被远端主机接受即可完成认证。生产环境建议优先使用公钥认证(禁用密码登录),并把私钥粘贴在 Public Key 输入框中。

连接测试(Test Connect)的实现原理

Web UI 上的"Test Connect"按钮在服务端对应SSHDataSourceProcessor.checkDataSourceConnectivity(见 SSHDataSourceProcessor.java):

try ( SshClientWrapper sshClientWrapper = new SshClientWrapper( baseConnectionParam.getHost(), baseConnectionParam.getPort(), baseConnectionParam.getUser(), baseConnectionParam.getPassword(), baseConnectionParam.getPrivateKey())) { return sshClientWrapper.isAuth(); } catch (Exception e) { log.error("ssh test connection failed", e); return false; }

测试流程可概括为:

  1. 用数据源的 host/port/user/password/privateKey 构造SshClientWrapper
  2. createSession中创建默认SshClient客户端并启动,以 10 秒超时发起 TCP 连接获取会话;
  3. 注册密码/公钥身份后,isAuth()执行实际认证握手并返回是否成功;
  4. 使用try-with-resources确保ClientSessionSshClient被正确关闭,不泄漏连接资源。

因此,"Test Connect"并不是简单地测试网络可达性,而是完整走一遍 SSH 认证流程,能够真实反映"能否用当前凭据登录远端主机"。

激活插件:SSH 数据源并非开箱即用

官方文档在 "Native Supported" 一节明确说明:SSH 数据源不在默认发行版的原生支持范围内,需要按伪集群部署文档中 "Download Plugins Dependencies" 一节的说明手动激活。

原因在于:从 3.3.0 版本起,DolphinScheduler 的二进制发行包不再内置各类插件依赖,需要用户按需下载。激活步骤参考 伪集群部署文档:

  1. 执行官方提供的插件安装脚本,下载全部插件依赖:
    bash ./bin/install-plugins.sh 3.3.0
  2. 若只需要部分插件,可编辑conf/plugins_config只保留所需项。该配置文件按--alert-plugins----datasource-plugins----storage-plugins----task-plugins--分段声明插件(见仓库 config/plugins_config)。其中与 SSH 远程执行相关的两行分别是:
    --datasource-plugins-- dolphinscheduler-datasource-ssh

    以及

    --task-plugins-- dolphinscheduler-task-remoteshell

install-plugins.sh(见 script/install-plugins.sh)会读取conf/plugins_config,对每一行插件 artifactId 执行mvnw dependency:get -DgroupId=org.apache.dolphinscheduler -DartifactId=${line} -Dversion=${version} -Dclassifier=shade将带shade分类器的插件包下载到plugins/目录,脚本支持传入自定义版本号(默认dev-SNAPSHOT)。

排错提示:如果未安装插件依赖便启动服务,使用 SSH 数据源或 RemoteShell 任务时会报ClassNotFoundException。官方文档特别提醒,插件依赖包通常不随二进制包分发,遇到该异常应回到对应插件类型的文档检查依赖是否缺失。

RemoteShell 任务如何消费 SSH 数据源

SSH 数据源的最终落脚点是 RemoteShell 任务。以 RemoteShellTask.java 与 RemoteExecutor.java 的源码为依据,任务执行链路如下:

1. 任务初始化(initRemoteShellTask.init解析任务参数为RemoteShellParameters(含rawScript原始脚本、type数据源类型、datasource数据源 ID 三个字段,见 RemoteShellParameters.java),并校验rawScript非空。

2. 按数据源 ID 取连接参数(initRemoteExecutor任务根据配置的数据源 ID,从ResourceParametersHelper中取出数据源参数,再通过DataSourceUtils.buildConnectionParams(DbType.valueOf(type), dbSource.getConnectionParams())还原为SSHConnectionParam,据此构造RemoteExecutor。这正是 SSH 数据源被 RemoteShell 任务引用的方式——数据源 ID 在任务配置中被关联,运行时取出其连接凭据建立 SSH 会话

3. 生成脚本(buildCommand任务把rawScript中的\r\n统一替换为\n,完成参数占位符替换(ParameterUtils.convertParameterPlaceholders),若配置了环境变量则前置拼入,最后加上#!/bin/bash头与echo DOLPHINSCHEDULER-REMOTE-SHELL-TASK-STATUS-$?状态输出指令,写入本地执行目录下的.sh文件。

4. 远端执行(RemoteExecutor.run

  • 通过getTaskPid检查远端是否已有同名任务在跑(ps -ef | grep "<taskId>.sh"),避免重复提交;
  • 使用SFTPSftpClientFactory.instance().createSftpFileSystem)把本地脚本上传到远端/tmp/dolphinscheduler-remote-shell-<user>/<taskId>.sh
  • nohup /bin/bash <script> > <script>.log 2>&1 &方式在远端后台启动任务(见COMMAND.RUN_COMMAND);
  • 5 秒为周期执行tail -n +N <taskId>.log增量拉取远端日志,实时输出到任务日志并解析输出参数;
  • 结束后读取日志末行的状态标记(DOLPHINSCHEDULER-REMOTE-SHELL-TASK-STATUS-<exitCode>)得到退出码,并执行清理命令删除远端的.sh.log临时文件。

5. 取消与进程树清理(kill任务取消时,RemoteExecutor.kill先查询任务 PID,再通过pstree -p <pid>获取整棵进程树并解析出所有子进程 PID,最后以kill -9一次性终止。这意味着RemoteShell 任务具备级联杀进程能力,可以清理远端脚本派生的所有子进程,而非只杀主进程。相应地,远端主机需要预装pstree工具(macOS 为pstree,Fedora/RedHat/CentOS/Ubuntu/Debian 系为psmisc包,官方文档在伪集群部署前置检查中有明确说明)。

常见问题与最佳实践小结

  • SSH 数据源不是 JDBC 数据源:它没有连接池、驱动与 SQL 执行能力,只能被 RemoteShell 任务消费,不要在 SQL、DataX 等任务中尝试使用;
  • 必填项:IP 与 User Name 必须填写,否则保存时报ssh datasource param is not valid;Port 默认22
  • 认证方式:密码与公钥可单独或同时配置;公钥需粘贴 PEM 格式私钥内容,建议生产环境优先公钥认证;
  • 插件激活:3.3.0 起二进制包不再内置插件,需通过install-plugins.sh结合conf/plugins_config下载dolphinscheduler-datasource-sshdolphinscheduler-task-remoteshell
  • 远端环境要求:目标主机需允许 SSH 登录,并具备bashpstree等基础工具;任务脚本与日志存放于/tmp/dolphinscheduler-remote-shell-<user>/目录;
  • 验证手段:创建数据源时使用"Test Connect"按钮,它会真实执行一次 SSH 认证握手(10 秒超时),比单纯 ping 更可靠。

通过上述配置与原理,你可以让 DolphinScheduler 工作流以纯 SSH 方式驱动任意远端主机执行脚本,实现"一处编排、处处执行"的远程命令编排能力。

【免费下载链接】dolphinschedulerApache DolphinScheduler is the modern data orchestration platform. Agile to create high performance workflow with low-code项目地址: https://gitcode.com/GitHub_Trending/dol/dolphinscheduler

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询