大型企业服务器的自动化运维(转载)

企业主机服务器日常运维工作中,经常需要登录并以 root 方式执行系统操作,如果在主机数量少的情况下,手工方式登录并执行效率尚可,但如果主机数量庞大(如笔者运维的国外客户服务器数量达 2000+),依次对一台台服务器进行手工操作工作量巨大且出错概率与主机数量成线性增大。 本文分析了在大数量企业服务器情况下,利用 shell 管道,Java SSHD 开源包,Expect 脚本三种方式实现自动登录并执行系统运维操作,三种方式分别适用于不同的场景,可以满足绝大多数企业主机服务器自动化运维的工作内容,大大减轻了系统管理员的工作量,同时降低了操作失误的风险。 本文中的三种方式的代码示例稍作修改,即可直接用于实际的生产主机的运维工作。

采用自动化脚本进行企业服务器运维的原因

传统 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

利用该功能,可以将需要 ftp 或者 telnet 登录的运维操作做成自动化脚本,将本来需要交互式输入的帐号和密码及登录后需要的操作指令包在 EOF 和 << 管道符中,以实现自动化 ftp 或者 telnet 到多台服务器并执行。

考虑如下场景:一批客户的 Unix 服务器主机要打 patch,需要将 patch 包用 ftp 上载到服务器指定目录,服务器数量巨大(超过 1000+),单个手工的上载操作是不现实的,因此我们使用 shell EOF 和管道功能编写自动化 ftp 脚本

autoftp 脚本示例如下:

清单 1. autoftp.sh 脚本示例

#!/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 协议具体内容已超出本文涉及的范围,请各位感兴趣的读者参考open-ssh 官方网站

在 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 类代码示例

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"); 行操作代码来实现自己的业务需求。

具体的 ganymed API 请参考ganymed project 官方网站

Expect 脚本自动化运维

考虑如下案例情况:有一批客户服务器需要做一个变更,将 sudoer 配置文件从 /etc/sudoer 目录搬移备份到 /usr/local/etc/sudoer 目录,由于该配置文件比较重要,需要 root 权限才能执行搬移操作,该客户服务器也采用 SSHD 协议,不允许 ftp/telnet 等的登录。

该情况下上文所提到的第二种方式 Java 开源包已不适用,因在 shell 进程下当切换用户尤其是 sudo 到 root 时,会 fork 一个新的进程,sudo 到 root 的会话在新的进程中进行,而 Java 开源包是限定在一个会话中的,执行 sudo 操作后,新的进程已经脱离了 Java 开源包的控制,这时候再试图用 Java 开源来执行后续命令,将会报错。

此类需要切换用户的情况下我们采用 Expect 脚本来进行模拟交互。

在这里将 Expect 脚本简介如下:

Expect 使用 Tcl 作为语言核心。不仅如此,不管程序是交互和还是非交互的,Expect 都能运用。这是一个小语言和 Unix 的其他工具配合起来产生强大功能的经典例子。Expect 是一个控制交互式程序的工具。它解决了上述需要用户角色转换的问题,用非交互的方式实现了所有交互式的功能。

Expect 被设计成专门针和交互式程序的交互。一个 Expect 程序员可以写一个脚本来描述程序和用户的对话。接着 Expect 程序可以非交互的运行“交互式”的程序。写交互式程序的脚本和写非交互式程序的脚本一样简单。Expect 还可以用于对对话的一部分进行自动化,因为程序的控制可以在键盘和脚本之间进行切换。

简单的说,Expect 脚本是用一种解释性语言写的。( 也有 C 和 C++ 的 Expect 库可供使用,但这超出了本文的范围 ).Expect 提供了创建交互式进程和读写它们的输入和输出的命令。它是在 Tcl 基础上创建起来的,并提供了一些 Tcl 所没有的命令。

编写 Expect 脚本的基本方式如下:

表 1. Expect 脚本基本使用示例

Expect 命令 作用 使用示例
spawn 激活一个 Unix 程序来进行交互式的运行 . spawn ssh 192.168.1.2
send 向进程发送字符串 send "sudo -s\r"
set 给 Expect 脚本中的变量赋值 set username “joe”
expect 等待进程收到的远程主机的输出,并匹配对应的字符串 , 一旦匹配,执行后续的操作 expect { "yes/no" send "yes" ;}

Expect 还能理解一些特殊情况,如超时和遇到文件尾。 :set timeout 60 ;expect eof

我们以上述的实例作为例子,来看看 Expert 脚本如何实现自动化登陆并 sudo 到 root,然后搬移文件的功能。

Expect 脚本 autoMove 示例如下:

清单 3. autoMove.sh 脚本示例

#!/usr/bin/expect
# 导入 Expect 类库
set hostname [lindex $argv 0]
# 设置操作的远程主机,$argv 类似 Shell 函数中的接收参数 [lindex $argv 0]
# 则表示第一个接收参数 , 例如 expectExample.sh host1
set username [lindex $argv 1]
# 同上,第二个接收参数为登陆用户名
set passwd [lindex $argv 2]
# 同上,第三个接收参数为登陆用户密码
set timeout 60
# 设置等待超时为 60 秒
spawn ssh [email protected]$hostname
# 使用 spawn 命令来激活 ssh 程序,模拟终端的输出将能够被 Expect 所读取,模拟终端也能从 send 输入到远程主机
expect {
"yes/no" {send "yes ";exp_continue}
"Password:" {send "$passwd ";}
}
#Expect 语句等待远程主机的字符串匹配,当匹配到了“yes/no”
#则执行后面的操作 .expect 搜索模式"*password:",其中 * 允许匹配
# 任意输入,所以对于避免指定所有细节而言是非常有效的。如果远程主机没有 action,
#所以 Expect 检测到该模式后就继续运行。 一旦接收到提示后,下一行就就把密码送给当前进程。
send "sudo -s\r"
expect "Password:" {send "$newpasswd\r"}
# 执行 sudo 用户角色转换操作
send "copy /etc/sudoers /usr/local/etcsudoers\r"
# 执行实际运维操作
send "exit\r "
send "exit\r "
expect eof {exit 1}

由上我们可以看出 Expect 使用伪终端来和派生的进程相联系。伪终端提供了终端语义以便程序认为他们正在和真正的终端进行 I/O 操作。使用 Expect 等待远程主机的响应并匹配需要的字符串,当匹配到后执行 send 操作向远程主机发送命令,set 操作为赋值,脚本的编写于通常的 Shell 脚本很类似,相当简洁和实用。

在 AIX ,Solairs 的 Unix 平台环境下 Expect 是默认安装的,Linux 需要安装对应的 rpm 包。

总结和展望

以上分析了大型企业服务器的自动化脚本运维,通过不同的案例分别介绍了 shell 管道,Java SSHD 开源包和 Expect 脚本三种方式的自动化运维。三种方式针对不同的业务需求及客户服务器实际环境,有很强的实用性和操作性。可以满足绝大多数企业服务主机的自动化运维工作内容,三种方式的代码示例稍作修改,即可直接用于实际的生产主机日常运维工作中。

如今随着 IT 运维管理工作的复杂度和难度的大大增加,将纯粹的人工操作变为一定程度的自动化管理是一个必然趋势。未来的 IT 自动化运维必将更加专业化、标准化和流程化。通过自动化运维监控,系统能及时发现故障隐患,主动的告诉用户需要关注的资源,以达到防患于未然。通过自动化运维诊断,能最大限度地减少维修时间,提高服务质量。

原文如下:http://www.ibm.com/developerworks/cn/aix/library/1107_tangqy_serverautomain/index.html?ca=drs-

时间: 2024-10-12 19:53:29

大型企业服务器的自动化运维(转载)的相关文章

自动化运维工具Ansible详细部署 (转载)

自动化运维工具Ansible详细部署 标签:ansible 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://sofar.blog.51cto.com/353572/1579894 ========================================================================================== 一.基础介绍 ===========================

企业实战脚本案例3:批量管理自动化运维100台小规模服务器

批量管理自动化运维100台小规模服务器 目录 1.脚本背景介绍 2.脚本技术需求分析 2.1 SSH免登陆认证 2.2 Expect实现key分发 2.2 PSSH家族命令详解 3.脚本功能及实现过程 3.1 脚本运行环境介绍 3.2 脚本功能介绍 3.3 脚本编写思路 3.4 脚本编写案例 一.脚本背景介绍 在企业中经常会用遇到小规模的集群服务器,在日常的管理中经常会遇到重复性的动作,如更新备上百台服务器上的ssh公钥.备份上百台服务器上的/etc/passwd配置文件等等,通常情况下采用专用

Python自动化运维开发之paramiko(远程批量管理服务器)

一:简介 paramiko是用python语言写的一个模块,遵循SSH2协议,支持以加密和认证的方式,进行远程服务器的连接.它仅需要在本地上安装相应的软件(python以及PyCrypto),对远程服务器没有配置要求,对于连接多台服务器,进行复杂的连接操作特别有帮助. 二:安装方法 安装paramiko有两个先决条件,python和另外一个名为PyCrypto的模块.唯一麻烦的就是安装PyCrypto时,需要GCC库编译,如果没有GCC库会报错,会导致PyCrypto以及paramiko无法安装

自动化运维工具Ansible详细部署

原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://sofar.blog.51cto.com/353572/1579894 ========================================================================================== 一.基础介绍 =========================================================

python自动化运维之路~DAY7

python自动化运维之路~DAY7 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.客户端/服务器架构 C/S 架构是一种典型的两层架构,其全称是Client/Server,即客户端服务器端架构,其客户端包含一个或多个在用户的电脑上运行的程序,而服务器端有两种,一种是数据库服务器端,客户端通过数据库连接访问服务器端的数据:另一种是Socket服务器端,服务器端的程序通过Socket与客户端的程序通信. C/S 架构也可以看做是胖客户端架构.因为客户端需要实现绝大多数的业务

自动化运维软件设计实战——互动出版网

这篇是计算机类的优质预售推荐>>>><自动化运维软件设计实战> 编辑推荐 本书适合从事系统运维及运维开发的人员阅读. 内容简介 本书主要讲解采用OSGi技术来设计一款可插拔式的运维软件的方法与思想,为读者提供一种不一样的运维软件设计与自动化运维解决方案.本书分三部分,第一部分讲解开源社区中比较流行的三款集中化运维软件,第二部分与读者一起分享为什么要采用OSGi的技术来设计集中化运维软件,第三部分介绍设计这款运维软件所涉及的技术和一些设计思想. 作译者 吴文豪,运维开发工

关于自动化运维的实践×××

谈起自动化运维,现在已经成为运维工作最热门的词语,关于运维自动化本人早在2012年就已经接触了BMC的ITSM系统,将ITIL运维管理体系和自动化运维工具的有效的结合大幅度的提高了运维工作效率.下图为HP提的统一运维自动化理念和运维手册,从目前企业基础架构层来看,运维人员无关乎关心的如下几个方面的自动化. 要了解运维自动化在企业当中应用场景和是否真正能够解决运维团队工作的问题.那我们则需要站到企业运维人员的角度去考虑问题.那么我首先要知道一个企业或者运维团队在规划运维的时候所需要考虑的问题及面临

云时代IDC自动化运维的几大神器

云时代IDC自动化运维的几大神器 2016年09月18日 10:27:41 天府云创 阅读数:1715 版权声明:本文为EnweiTech原创文章,未经博主允许不得转载. https://blog.csdn.net/English0523/article/details/52572114 自动化运维是数据中心.互联网企业高度重视的方向,数据中心的从纯手工.重复地进行软件部署运维,经历编写脚本运维,再到借助第三方工具高效.方便地部署和运维,在转变的过程中已大大提升了运维的效率和性能.下面给大家推荐

从零到一 | 如何搭建数据库自动化运维体系

需求背景: 随着业务的增长.对运维效率和质量的要求不断提高,对自动化运维体系的需求也不断增强. 目前笔者服务的很多中大型企业客户,运维其实还停留在“刀耕火种”的原始状态. 这里所说的“刀”和“火”就是运维人员的远程客户端,例如 xshell 和Windows 远程桌面. 这种工作模式有很多局限性, 比如服务器.数据库.中间件等的安装.初始化,应用软件部署.服务发布和监控都是通过手动方式来完成的. 这就需要运维人员登录到服务器上,一台一台去管理和维护. 如果有个几十上百台,累就累死人了. 笔者曾运