你好 我是懂java的测试
前言
前段时间开发了一款自动化检测工具,主要针对Swift集群新加入服务器进行对象存储基本功能、配置文件、服务器时间同步、Swift集群网络连通性等方面的验证。
工具开发的背景
Swift是什么?云计算OpenStack项目里关键的对象存储技术,也是公司云产品之一,目前线上50+台服务器集群,有时遇到业务高峰期,扩容至少10台服务器才能缓解,为了让这10台服务器融入到整个Swift服务集群中,每台服务器必须进行Swift组件安装、下发配置文件和网络连通性的检查。由于服务器较多,又加上手工肉眼检查服务器相关信息,难免会有遗漏之处,造成生产问题频发。
为了解决这么一个问题,我用Java语言、Testng框架等技术开发了一款线上自动化检测工具,主要针对新加入Swift集群的每个服务器,进行以下几个方面检测,
过程很曲折,收获却很多,目前已投入使用,既丰富了线上验证的内容,也提高了新服务器交付的效率。
近期打算用几篇文章详细聊聊开发这款工具遇到的问题和解决方案,希望对大家开发工具有所帮助,后期也会考虑开源这个工具源码。
怎么获取服务器相关的数据?
1到6项,自动化检测工具必须要先登录新交付服务器,获取相关的数据,才能进行检测,但是怎么登录呢?第一个方案是提前配置好待测服务器的账号、密码,使用ganymed-ssh2 jar包,登录服务器,代码如下:
public static Connection getConn(String ip, String userName, String pwd, int port) {
Connection conn = new Connection(ip);
boolean blag = true;
try {
conn.connect();
blag = conn.authenticateWithPassword(userName, pwd);
if (!blag) {
throw new IOException("Authentication failed.文件scp到数据服务器时发生异常");
}
} catch (IOException e) {
e.printStackTrace();
}
if (blag) {
return conn;
} else {
return null;
}
}
但是,让线上服务器的密码明文裸奔多少有点不讲究,要是被人拿到线上服务器的账号、密码,进行非法操作,必将是一场生产灾难,于是采用了第二种方案SSH免密登录。
SSH免密登录是什么?
SSH免密登录是什么意思?简单说两台服务器之间不输入密码,用ssh+对方的ip就能登录,这个就得详细聊一聊ssh登录的原理,一般服务器用户目录使用以下命令ssh-keygen -t rsa会生成几个文件。
id_rsa(私钥)
服务器上经过RSA算法生成的私钥。
id_rsa.pub(公钥)
服务器上经过RSA算法生成的公钥,和私钥是一对的密钥对,用于连接其他服务器用,例如:将主机名001的id_rsa.pub内容追加到主机名002的authorized_keys文件中,这样001主机就能用ssh 002的ip登录。
known_hosts
ssh会把你每个你访问过计算机的公钥(public key)都记录在~/.ssh/known_hosts。当下次访问相同计算机时,OpenSSH会核对公钥。如果公钥不同,OpenSSH会发出警告, 避免你受到DNS Hijack之类的攻击
SSH远程连接是什么原理?
工具自动化登录服务器源码长啥样?
部分源码如下:host 是要登录服务器ip,userName要登录服务器的用户名
public static Session getSession(String host, String userName) throws JSchException {
Session session = null;
#privateKeyPath 本地私钥路径。
String privateKeyPath ="~/.ssh/id_rsa";
JSch jsch = new JSch();
jsch.addIdentity(privateKeyPath);
session = jsch.getSession(userName, host, 22);
session.setConfig("PreferredAuthentications", "publickey,keyboard-interactive,password");
Properties config = new Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
session.connect();
return session;
}
command :是登录服务器要执行的命令;
public static String printInfo(Session session, String command) throws IOException, JSchException {
Channel channel = session.openChannel("exec");
((ChannelExec) channel).setPty(false);
((ChannelExec) channel).setCommand(command);
channel.setInputStream(null);
((ChannelExec) channel).setErrStream(System.err);
channel.connect();
//打印成功信息
InputStream in = channel.getInputStream();
String result = "";
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
String buf;
while ((buf = reader.readLine()) != null) {
result += new String(buf.getBytes(StandardCharsets.UTF_8)) + ",";
}
log.info("result" + result.length());
channel.disconnect();
log.info("返回的结果:" + result);
if (result.length() <= 0) {
return "";
}
return result.substring(0, result.length() - 1);
}
返回的result是命令执行的结果。
总结
本篇文章主要分享了SSH密码登录的原理、Java代码中自动登录服务器的两种方法,Python中paramiko库也可以远程操控服务器。
代码自动登录服务器,执行linux命令或上传、下载文件,可以在一些自动化场景中帮我们解决很多问题。
加我微信lvceshikaifa,免费面试辅导、学习资料、简历模板获取、加入学习群。