如何通过外部脚本监控和实现高能所集群的自动化工作
时间:2021-8-19 14:58 作者:JourinTown 分类: 计算机技术
1 利用spawn
和expect
实现ssh的自动登录
1.1 安装spawn和expect
在这里,笔者以Ubuntu 18.4LTS为例,spawn需要tcl软件包,expect需要的软件包同名。
$ apt install tcl tclx tcl_dev expect
安装完成后如果无法打开expect或是在expect中无法使用spawn,请确认tcl软件包的版本,以及tcl_dev是否安装,目前很多新的系统对于该软件包的版本要求较高。另外在使用spawn时,要注意看好教程对应的系统或是软件版本,部分系统的spawn是可以外部调用的,但是其他多数系统需要在expect环境中才能调用,请注意区分!
1.2 spawn和expect的使用简介和一个简单的应用
在使用前,我们先来简单的瞭解一下我们是怎么使用这两个语句的,spawn
后面通常是接上一句shell的语句,该shell语句的输出将会被监听。expect{}
是对于spawn语句得到的输出的反应,可以监听某些输出并返回或是进行某些输入操作,比如我们在调试BOSS软件时有时遇到错误会问”Do you want to continue?(yes/no)”的时候,集群总是会自动帮我们输入no,其实就是利用expect监听了这句话并作出的反应,试想一下如果没有这样的工具,如果你的job出错或是存在没有预料的输出时就可能永远卡在那里,除了杀掉进程也别无选择。
那么在确认安装无误后,让我们来写第一个自动登录的程序吧!
expect -c "set timeout 5; spawn ssh xxx@lxslc7.ihep.ac.cn; expect { {Are you sure you want to continue connecting *} {send -- yes\r;exp_continue;} {*password:} {send -- $password\r;exp_continue;} };"
上方的代码逻辑是很简单的,第一步设置spawn命令的超时时间,防止由于网络原因长时间ssh失败,之后利用spawn来运行我们ssh的程序,在expect中,如果我们是第一次登陆,或是在.ssh等的config文件中修改了ssh的设置,通常会问你是否把这个地址加入信任的列表,那么通过探测”Are you sure you want to continue connecting”就可以判断这句话的存在,然后利用send语句来输入yes和回车”\r”。同样的,我们检测”password:”来判断现在是否是输入密码的时机并返回密码。这样,我们就可以发现我们已经成功的登录了高能所的集群。只需要通过在ssh后加入需要在集群上执行的命令、或是在expect后利用send输入命令,就可以完成一个脚本的自动化工作并得到相应的输出,这一输出可以继续利用expect来监听和处理,也可以通过本地的脚本利用pipe接力来处理,这里就自由让各位来决定了!
2 网页联动
2.1 网页查看工作情况
首先,你需要有一台配置好了nginx(或apache)以及PHP5.6以上的服务器(如果你是纯小白,没有自己的服务器,也不知道我之前说的这个是什么,我非常推荐大家直接在一台个人电脑上安装类似花生壳这样的工具并安装宝塔控制面板,自己百度一下什么是内网透传然后按着提示完成宝塔面板的配置,那你现在四舍五入也拥有了一台适合接下来介绍要求的服务器),首先需要在PHP的配置文件中解禁exec(或shell_exec)函数的使用,这个函数就是帮助我们在php文件中运行本地的脚本文件。
那么既然都说到可以直接运行本地脚本了,相信聪明的你也明白该怎么做了,现在我们只需要一个文本框来记录用户名并利用1.2节说到的方法,通过hep_q -u username
就可以直接得到最后的结果了!
那么首先,我们需要一个输入参数就可以运行的shell脚本,!!!注意,这个脚本一定要放在服务器中一个安全的地方(即一个未共享的目录中),直接暴露在联网的磁盘中是很危险的,如果被不法分子盯上了可能通过文件权限的漏洞篡改并登录进高能所集群,危害大家工作的安全!!!,以下是一个例子:
#checkjob.sh expect -c "set timeout 5; spawn ssh yourusername@lxslc7.ihep.ac.cn hep_q -u $1; expect { {Are you sure you want to continue connecting *} {send -- yes\r;exp_continue;} {*password:} {send -- yourpasswordhere\r;exp_continue;} };"
这样,我们在本地应该就可以通过source checkjob.sh xxx
实现所有所查找对象job的输出,不过别忘了通过chmod给予nginx(apache同理)运行这个脚本的权限,至于确定nginx的用户名,可以通过查询php进程执行者的用户名,一般为"www"或者是"wwwroot"。接下来,只需要让exec
函数来帮我们做这件事就行了。在这里,我们先通过html来做一个表单来把用户输入的用户名传给php
<!--job.html--> <html><head><meta charset="utf-8"><title>Job Check@IHEP</title></head><body> <center><h1>Job Check@IHEP</h1><hr/> <form action="job.php" method="post"><!--输入用户名的表单,采用post方式,目标是job.php--> <label>User Name</label> <input type="text" name="urname"><br><!--输入用户名的文本框--> <input type="submit" name="submit" value="Submit"><!--提交按钮--> </form><hr/>Developed by Benhao Tang From Nankai University(2021)</center></body></html>
这样,我们获取用户名的表单就做好了,接下来让我们用exec
函数来运行这个脚本吧!
<!--job.php--> <html><head><meta charset="utf-8"><title>Job Check@IHEP</title></head><body> <center><h1>Job Check@IHEP</h1><hr/> <?php if(isset($_POST['urname'])){ $name = $_POST['urname']; $result=exec("/bin/bash /path/to/testssh.sh $name"); echo "For user ".$name.", there are still ".$result."<br/><a href=\"job.html\"><<Return</a>";} ?> <hr/>Developed by Benhao Tang From Nankai University(2021)</center></body></html>
这样,当我们在文本框中输入用户名的时候,就可以查到目前工作的情况了,通过$result=exec()
只能获取最后一行,可以通过exec
自带返回方法或是写log的方法获得更多结果,这里就不再赘述。
3 尾声
不知道这篇文章是否激发了您的一些思考?通过远程控制可以实现更多对集群有趣的自动化控制,比如定时git同步,作业接力,IFTTT的联动,作业跑完的邮件提醒,甚至是远程获得ROOT绘制的图像。在接下来几天,我还将分享更多远程与高能所集群联动的案例,欢迎订阅网站的RSS持续跟踪!
标签: 集群