Apache DolphinScheduler SSH 数据源:RemoteShell 远程执行的核心配置与源码原理
【免费下载链接】dolphinschedulerApache DolphinScheduler is the modern data orchestration platform. Agile to create high performance workflow with low-code项目地址: https://gitcode.com/gh_mirrors/do/dolphinscheduler
SSH 数据源是 Apache DolphinScheduler 中为数不多的非数据库型数据源,它不用于建立 JDBC 连接,而是为RemoteShell(远程 Shell)任务组件提供远程主机鉴权信息,让工作流可以在任意可通过 SSH 访问的机器上执行命令。阅读本文后,你将掌握 SSH 数据源的完整配置项、参数校验规则、连接测试机制,以及从数据源到任务执行的底层调用链,从而在实际项目中正确搭建"远程命令执行"场景。
一、SSH 数据源在 DolphinScheduler 中的定位
在 官方数据源文档 中明确说明:该数据源专用于 RemoteShell 组件,以便在远程主机上执行命令。它与其他数据源(MySQL、Hive、Spark SQL 等)最大的区别在于:
- 其他数据源服务于 SQL 类任务,最终会产出 JDBC URL 与连接;
- SSH 数据源不产生 JDBC 连接——从源码看,SSHDataSourceProcessor 的
getJdbcUrl()、getValidationQuery()、getDatasourceDriver()均返回空字符串,getConnection()直接返回null; - 它承载的是"主机 + 端口 + 用户名 + 密码/公钥"这类 SSH 登录凭证,由 Apache MINA SSHD 客户端库消费。
因此,凡是想在 DolphinScheduler 工作流中对非 Worker 所在机器下发命令的场景(如运维脚本、跨机部署、远程巡检),都可以通过 SSH 数据源 + RemoteShell 任务组合实现。
二、在管理界面创建 SSH 数据源
在 DolphinScheduler Web UI 中,进入"数据源中心"新建数据源,选择类型SSH,表单如下图所示:
各配置项说明如下(继承自官方文档,并补充源码细节):
| 配置项 | 说明 | 源码对应字段 |
|---|---|---|
| 数据源类型(Data Source) | 固定选择SSH | DbType.SSH |
| 数据源名称(Data Source Name) | 自定义名称,用于任务中引用该数据源 | BaseDataSourceParamDTO.name |
| 描述(Description) | 对该数据源的补充说明,可选 | BaseDataSourceParamDTO.note |
| IP 主机名(IP Hostname) | 远程 SSH 服务器地址,支持 IP 或域名 | BaseDataSourceParamDTO.host |
| 端口(Port) | SSH 服务端口,默认值为 22,可在创建时修改 | SSHConnectionParam.port |
| 用户名(Username) | 用于登录远程主机的用户名 | BaseDataSourceParamDTO.userName |
| 密码(Password) | 密码认证方式的登录密码 | BaseDataSourceParamDTO.password |
| 公钥(Public Key) | 密钥认证方式使用的公钥内容 | SSHDataSourceParamDTO.publicKey |
其中publicKey字段是 SSH 数据源特有的扩展字段:SSHDataSourceParamDTO在继承BaseDataSourceParamDTO(dolphinscheduler-datasource-api)的基础上,仅新增了这一个属性。
认证方式的选择
从连接参数模型 SSHConnectionParam 可以看到,最终落库的凭证包含user、password、publicKey、host、port五个字段,支持两种认证方式:
- 密码认证:只填用户名和密码,连接时通过
session.addPasswordIdentity(password)注入密码身份; - 公钥认证:填写用户名与公钥内容,连接时由
KeyPairResourceLoader解析公钥并调用session.addPublicKeyIdentity(keyPair)注入密钥身份。
两种方式可以同时配置,代码会按先后顺序分别注入密码身份与公钥身份(见 SSHUtils.getSession())。
三、参数校验:哪些字段是必填的?
在 SSHDataSourceProcessor.checkDatasourceParam() 中定义了严格的校验逻辑:
if (StringUtils.isEmpty(datasourceParamDTO.getHost()) || StringUtils.isEmpty(datasourceParamDTO.getUserName())) { throw new IllegalArgumentException("ssh datasource param is not valid"); }即IP 主机名(host)与用户名(userName)为必填项,任一为空都会抛出IllegalArgumentException并导致创建失败。端口、密码、公钥则为可选:端口不填时使用默认值 22,密码与公钥可以按认证方式二选一或同时提供。
这一点在单元测试 SSHDataSourceProcessorTest.testCheckDatasourceParam() 中得到了验证:空 DTO 抛异常、只填 host 仍抛异常、补齐 userName 后才通过校验。
四、连接测试:数据源"测试连接"按钮背后的原理
创建或编辑 SSH 数据源时,点击"测试连接"按钮,后端实际执行的是SSHDataSourceProcessor.checkDataSourceConnectivity():
try (SshClientWrapper sshClientWrapper = new SshClientWrapper( baseConnectionParam.getHost(), baseConnectionParam.getPort(), baseConnectionParam.getUser(), baseConnectionParam.getPassword(), baseConnectionParam.getPublicKey())) { return sshClientWrapper.isAuth(); } catch (Exception e) { log.error("ssh test connection failed", e); return false; }其底层实现位于 SshClientWrapper:
- 使用
SshClient.setUpDefaultClient()创建 Apache MINA SSHD 客户端并start(); connect(userName, ip, port)建立会话,连接超时 10 秒;- 分别注入密码身份与公钥身份(公钥通过
SecurityUtils.getKeyPairResourceParser()解析); isAuth()调用clientSession.auth().verify(Duration.ofSeconds(10)).isSuccess()完成实际认证,认证超时同样为 10 秒,认证成功返回true,否则返回false。
测试用例testTestConnection()展示了连接失败返回false以及 mock 认证成功后返回true的两条路径,与该实现一致。
五、数据源唯一标识
DolphinScheduler 为每个数据源生成唯一 ID 用于缓存与去重,SSH 数据源的生成规则位于getDatasourceUniqueId():
return MessageFormat.format("{0}@{1}@{2}@{3}", dbType.getName(), baseConnectionParam.getHost(), baseConnectionParam.getUser(), PasswordUtils.encodePassword(baseConnectionParam.getPassword()));即格式为ssh@主机@用户名@加密密码,密码在拼接前会经过PasswordUtils.encodePassword()处理。测试用例testGetDatasourceUniqueId()验证了ssh@localhost@root@123456这一输出形式。
六、RemoteShell 任务如何消费 SSH 数据源
SSH 数据源的直接消费者是 RemoteShell 任务。在 RemoteExecutor 中可以看到完整的调用链:
- 任务运行时从数据源取出
SSHConnectionParam,构造RemoteExecutor; getSession()复用 SSHUtils.getSession() 建立并认证ClientSession;- 通过
ChannelExec在远程主机上执行 Shell 命令,并借助 SFTP(SftpFileSystem)完成脚本文件传输; - 远程脚本工作目录固定为
/tmp/dolphinscheduler-remote-shell-%s/(按任务实例格式化),任务状态通过DOLPHINSCHEDULER-REMOTE-SHELL-TASK-STATUS-标记回传,执行状态轮询间隔为 5000ms。
此外,SSHUtils.getSession()中还设置了会话心跳:session.setSessionHeartbeat(HeartbeatType.IGNORE, Duration.ofSeconds(3)),每 3 秒发送一次心跳以防止空闲会话被服务端断开,这对长时间运行的远程命令尤为重要。
因此整个链路可以概括为:SSH 数据源(凭证模型SSHConnectionParam)→ RemoteShell 任务(RemoteExecutor)→ Apache MINA SSHD(SshClient/ClientSession)→ 远程主机 Shell。
七、实践建议与注意事项
- 优先使用密钥认证:相比密码,公钥认证更安全且便于在目标主机统一维护。公钥内容直接粘贴到"公钥(Public Key)"字段即可,支持标准 OpenSSH 公钥格式(如测试用例中的
ssh-rsa AAAAB...)。 - 注意端口一致性:SSH 数据源默认端口为 22,若远程主机使用非标准端口(如 2222),务必在创建时显式填写,否则连接测试会失败。
- 连接超时阈值:连接与认证的超时时间在源码中为 5~10 秒级别(
SSHUtils连接 verify 为 5000ms,SshClientWrapper连接与认证为 10 秒)。对网络抖动较明显的环境,应确保目标主机可达、防火墙放行对应端口。 - 复用连接与心跳保活:RemoteShell 任务会复用会话,且设置了 3 秒心跳,长时间任务无需担心空闲断连;但大量并发远程任务会占用较多 SSH 连接资源,需结合集群规模合理规划。
- 主机名解析:
checkDatasourceParam仅做非空校验,不校验主机是否真实可达;请确保 Worker(执行 RemoteShell 任务的节点)能解析并访问该主机地址。
八、进一步阅读
- 数据源官方文档:docs/docs/en/guide/datasource/ssh.md
- SSH 数据源插件源码:dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-ssh
- SSH 数据源单元测试:SSHDataSourceProcessorTest.java
- RemoteShell 任务实现:RemoteExecutor.java
【免费下载链接】dolphinschedulerApache DolphinScheduler is the modern data orchestration platform. Agile to create high performance workflow with low-code项目地址: https://gitcode.com/gh_mirrors/do/dolphinscheduler
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考