在具有去耦、冗余和异步的远程服务器上执行命令



我有一些服务器需要在其他服务器上执行命令。例如,Bitbucket服务器在另一台服务器上执行git pull的接收后挂钩。另一个例子是CI服务器拉取一个新的docker映像并重新启动另一台服务器上的实例。

我通常会使用ssh,专门为权限有限的作业创建一个用户/组。

ssh:的几个缺点

  • 同步ssh调用意味着git push将不得不等待直到完成
  • 如果由于任何原因无法联系到主机,则ssh命令将失败
  • 维护密钥、用户和sudoers权限可能会变得很难

少数可能性:

  • 找到一个开箱即用的开源解决方案(到目前为止,我尝试过,但没有成功)
  • 在每台服务器上设置一个REST API,接受具有某种类型身份验证的调用,例如POSThttps://server/git/pull/?apikey=a1b2c3
  • 设置Python/Celery以在每个主机的不同队列上执行任务。这意味着每台服务器上都有一个celery工作程序,可以执行命令,也可能有一个接受REST API调用的服务,将它们转换为celery任务

这个问题有好的解决办法吗?

定义问题

  1. 您希望能够在不等待远程任务完成的情况下触发该任务

这可以通过多种方式实现,包括SSH。您可以通过关闭或重定向所有I/O流来执行远程命令,而无需等待它完成,例如:

ssh user@host "/usr/bin/foobar </dev/null >/dev/null 2>&1"
  1. 如果主机当前不可用,您希望能够推迟任务

这需要某种排队/重试系统。您还需要决定目标主机是在查询消息("pull"),还是从其他地方向目标主机发送消息("push")。

  1. 您希望尽可能简化访问控制

没有办法完全避免这个问题。一种解决方案是将大部分身份验证逻辑放在集中式任务服务器中。这将问题分为两部分:在任务服务器中配置访问权限,以及在任务服务器和目标主机之间配置身份验证。

示例解决方案

  • 主机尝试使用上面的异步方法通过SSH启动任务。若主机不可用,则将任务写入本地文件。Cron作业定期重试发送失败的任务。通过SSH密钥进行访问控制。

  • 主机通过向SFTP服务器上的文件写入命令来添加任务。目标主机上的Cron作业定期检查新命令,并在发现时执行这些命令。通过SFTP服务器上的SSH密钥管理访问控制。

  • 主机将任务发布到REST API,后者将任务添加到队列中。每个目标主机上的Celery守护进程使用from队列并执行任务。访问主要由发送到任务队列服务器的凭据管理。

  • 主机将任务发布到API,后者将任务添加到队列。任务使用者节点从队列中提取任务,并将请求发送到目标主机上的API。身份验证由附加到请求的发件人的加密签名管理,由目标主机上的任务服务器验证。

您还可以查看一些工具,这些工具可以开箱即用地执行某些或所有必需的功能。例如,一些谷歌搜索产生了Rundeck,它似乎具有一些作业调度功能和RESTneneneba API。您还应该考虑是否可以利用系统中现有的任何自动化部署或管理工具。

结论

最终,这个问题没有一个正确的答案。这真的取决于你的特殊需求。问问自己:你想花多少时间和精力来创建这个系统?维护怎么办?它需要多可靠?它需要多少才能扩展?等等,无限。。。

最新更新