首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

大型企业 Unix 服务器的自动化运维 (1)

大型企业 Unix 服务器的自动化运维 (1)

采用自动化脚本进行企业服务器运维的原因传统 Unix 主机服务器手工运维方式的问题大型企业的 IT 基础设施中,Unix 主机服务器占据重要的地位。在日常运维工作中,经常需要登录并以 root 方式执行系统操作。如果在主机数量少的情况下,手工方式登录并执行运维工作的效率尚可,但如果主机数量庞大(如笔者运维的国外客户服务器数量达 2000+),依次一台台服务器的登录和操作工作量巨大,且出错的概率随服务器数量的增加的递增。
采用自动化脚本进行运维的特点及好处在大数量 Unix 企业服务器情况下,为了提高运维工作效率,减低手工操作而出错的风险,采用自动化脚本进行运维是一个很好的方式。通过向脚本提供主机列表,用户名账户名密码等输入参数方式,让其自动登录远程目标主机并执行相应的运维操作,批量处理所有涉及的企业服务器主机。该方式下系统管理及运维人员只需要在自动化脚本中提供一次系统运维操作的步骤命令,设定主机列表及正确的帐号密码输入参数,利用 nohup 方式后台运行该脚本,在完成后监控该脚本的输出日志就可以完成上千台服务器的重复运维工作,并大大减轻了系统管理及运维人员的工作量,降低了重复操作中出错的风险。
本文介绍了利用 shell 管道,Java SSHD 开源包,Expect 脚本三种方式实现自动登录并执行系统运维操作的案例。三种方式分别适用于不同的场景,如 shell 管道方式适用于 Telnet/FTP 协议登录的普通账户,SSHD 开源包适用于 ssh1/ssh2 安全登录协议下的登录运维,Expect 脚本适用于 SSHD 协议且需要 sudo 切换到 root 帐号权限的运维操作。
自动化脚本运维的具体实现利用 shell 管道进行自动化运维在企业 Unix 服务器上如果开放了 telnet 或者 FTP 协议,通常可以利用 shell 的 EOF 和 << 管道功能将后续的输入作为子命令或子 Shell 的输入,直到遇到 EOF 为止,再返回到主调 Shell,当 s h e l l 看到 < < 的时候,它就会知道下一个词是一个分界符。在该分界符以后的内容都被当作输入,直到 shell 又看到该分界符 ( 位于单独的一行 )。这个分界符可以是你所定义的任何字符串
例如:
<<EOF
(你需要执行的操作内容)
EOF
利用该功能,可以将需要 ftp 或者 telnet 登录的运维操作做成自动化脚本,将本来需要交互式输入的帐号和密码及登录后需要的操作指令包在 EOF 和 << 管道符中,以实现自动化 ftp 或者 telnet 到多台服务器并执行。
考虑如下场景:一批客户的 Unix 服务器主机要打 patch,需要将 patch 包用 ftp 上载到服务器指定目录,服务器数量巨大(超过 1000+),单个手工的上载操作是不现实的,因此我们使用 shell EOF 和管道功能编写自动化 ftp 脚本
autoftp 脚本示例如下:
清单 1. autoftp.sh 脚本示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#!/bin/bash
# 指定 ftp 服务器的 i
serverip=192.168.1.159
# 指定 ftp 服务器的 ftp 用户
ftpuser=ftptest
# 指定 ftp 服务器的 ftp 用户密码
ftppwd=123456
# 指定 client 主机本地下载文件存放的目录
localdir=/home/xiutuo/ftp
# 指定 server 主机的 ftp 目录
remotedir=/opt/IBM/DB2/
# 登录 server 主机的
ftp -v -n $serverip << EOF  > /tmp/autoftp.log.2010.XX.XX 2>&1
set head off
set echo off
set wrap off
# 指定 ftp 用户和密码
$ftpuser
$ftppwd
# 指定 server 主机的 ftp 目录和本地目录
lcd $localdir
cd $remotedir
bin
# 上传 patch 包文件至 server 主机的指定目录
put patchXXX.tar.gz
EOF




如上可以看到 FTP 登录和上传不再需要手工与每台 server 交互。读者可以修改该脚本,让服务器主机 IP 或主机名通过读配置文件循环获得,从而实现对多台服务器主机的操作。也可以修改 ftp 用户 / 密码部分代码,改成读取输入参数,以增强安全性。
Java SSHD 开源包自动化运维上述的 Ftp,telnet 管道方式的运维是简单可行的,但是现在业界大型的企业处于安全性的考虑,逐步淘汰此类协议的登陆方式,而改用基于公钥体系的 SSHD 登陆协议。关于 SSHD 协议具体内容已超出本文涉及的范围,请各位感兴趣的读者参考 。
在 SSHD 下的登陆是不允许 shell 管道方式的(如果允许的话意味着 ssh 跟 telnet,ftp 一样丧失了安全性),在此种情况下如果系统管理员要进行自动化运维操作,可以采用 Java 开源的 SSHD 包来进行。
Java ganymed 开源包是成熟的 SSHD 客户端,采用封装 socket 编程方式进行底层的 ssh 通信协议,用户调用其 API 与自己使用 SSHD 命令行登陆服务器的步骤和方法都一致,很容易理解和掌握。开源包的很多 Demo 实例,使即使对 Java 编程不熟悉的系统管理人员,也可以通过简单的修改 demo 代码来实现自身需求的自动化运维操作。
考虑如下案例:一个企业的所有服务器需要将 /etc/services 文件备份至 /usr/local/etc/ 特定逻辑卷目录,企业服务器都采用 SSH2 安全协议,不允许 telnet,ftp 登录。
用 ganymed 的 SSH2 开源包编写自动化登陆脚本,以管理员账号和密码登陆企业 Unix 服务器,执行 cp 操作进行备份。
ganymed 的 Java 代码示例如下:
清单 2. AutoCp.java 类代码示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

import ch.ethz.ssh2.Connection;
import ch.ethz.ssh2.Session;
import ch.ethz.ssh2.StreamGobbler;

public class AutoCopy
{
public static void main(String[] args)
{
String hostname = "9.212.XXX.XXX;
String username = "SolarisAdmin";
String password = "********";

try
{
  /* 创建 SSH2 连接实例 */

  Connection conn = new Connection(hostname);

  /* 打开主机 ssh 端口连接(默认 22) */

  conn.connect();

  /* 认证方式为 user/passwd */

  boolean isAuthenticated = conn.authenticateWithPassword(username, password);

  if (isAuthenticated == false)
   throw new IOException("Authentication failed.");

  /* 已连接到远程主机,打开 session 会话 */

  Session sess = conn.openSession();

    /* 执行备份操作 */
  sess.execCommand(\
  "cp /etc/services /usr/local/etc/services; \
  ls -lt /usr/local/etc/|grep -i services  >&2");

   /* 远程主机输入输出流 */
  InputStream stdout = new StreamGobbler(sess.getStdout());
  InputStream stderr = new StreamGobbler(sess.getStderr());

  BufferedReader stdoutReader = new BufferedReader(new InputStreamReader(stdout));
  BufferedReader stderrReader = new BufferedReader(new InputStreamReader(stderr));
   
  System.out.println("process result on remote server:");

  while (true)
  {
   String line = stdoutReader.readLine();
   if (line == null)
    break;
   System.out.println(line);
  }

  System.out.println("Process error from remote server:");
   
  while (true)
  {
   String line = stderrReader.readLine();
   if (line == null)
    break;
   System.out.println(line);
  }
   
  /* 关闭会话 */

  sess.close();

  /* 关闭连接 */

  conn.close();

}
catch (IOException e)
{
  e.printStackTrace(System.err);
  System.exit(2);
}
}
}




以上可以看到,ganymed 的 SSH2 开源包使用简单,建立 connection 并打开会话 session 后,都是普通的对 session 的 IO 操作,读操作则可以获取服务器端的输出,而写操作则对应对服务器端的敲入命令,一目了然,简便实用。
熟悉 Java 编程的系统管理员可以很快上手,即使是没有 Java 基础的管理员也可简单的修改示例中的 sess.execCommand("cp /etc/services /usr/local/etc/services; ls -lt /usr/local/etc/|grep -i services  >&2"); 行操作代码来实现自己的业务需求。
返回列表