使用PSSH批量管理Linux

文章目录
  1. 1. 前言
  2. 2. 批量操作思路
    1. 2.1. 思路一
    2. 2.2. 思路二
    3. 2.3. 思路三
  3. 3. pssh
    1. 3.1. pssh简介
    2. 3.2. 安装
    3. 3.3. 命令格式
  4. 4. 实践篇
    1. 4.1. 添加密钥认证访问
    2. 4.2. 获取每台机器的uptime
    3. 4.3. 批量修改hostname
    4. 4.4. 批量替换sources.list
    5. 4.5. 批量安装ganglia
    6. 4.6. 批量修改密码
    7. 4.7. 批量杀进程
  5. 5. 后记

前言

《Ubuntu系统批量自动安装》一文中,配置好了PXE服务器,也通过它安装了几台机器。每个机器都重新配置好了IP,已经可以远程访问了。现在新的问题来了,每个机器的主机名都相同,需要修改;每个机器的sources.list都有问题,需要替换。以后,肯定也有很多其他需要批量操作的问题,比如批量安装ganglia,总不能上百台机器一个个手动操作吧!

本文,就研究下linux批量操作的相关方法和工具,重点研究下pssh。

批量操作思路

首先定义两个概念:管理机和客户机,本文中的管理机是指管理其他服务器的服务器,客户机是指普通服务器。
管理机IP为192.168.56.101,客户机IP为192.168.56.102-104,用户名都是test。

思路一

说到批量操作,最容易想到的,肯定是在管理机写一个脚本,里面有个循环语句,挨个连接客户机进行操作。
而循环语句里面,主要是ssh,然后执行交互命令。参考 shell实现SSH自动登陆关于SSH 远程执行命令你要知道的二三事shell脚本实现同时多台远程主机执行命令的代码分享

但是,这种方式很难并行处理,比较浪费时间。

思路二

另一个简单的思路,是在管理机写一个在客户机执行的脚本,然后推送给客户机,再在客户机里执行脚本。主要参考SSH 远程执行任务

这种方式同样很难并行处理,比较浪费时间。如果非要并行处理,那么就只能牺牲反馈信息。

思路三

最后一种思路就是借助工具,比如mussh、pdsh、pssh等等。

pssh

pssh简介

pssh是一个python编写可以在多台服务器上执行命令的工具,同时支持拷贝文件,是同类工具中很出色的。类似pdsh,但是相对pdsh更为简便,使用前必须在各个服务器上配置好密钥认证访问。参考pssh命令pssh HOWTO

安装

1、ubuntu安装pssh,sudo apt-get install pssh

2、ubuntu安装完pssh后,输入pssh,也许会提示:No command ‘pssh’ found, did you mean:…

解决办法参考Why pssh command is not working?,一条命令解决:
echo "alias pssh=parallel-ssh" >> ~/.bashrc && . ~/.bashrc,其中&& . ~/.bashrc代表立即生效。

3、设置相关命令
安装完pssh后,实际上还安装了pscp、prsync、pnuke和pslurp。和pssh命令无效的问题相同,它们默认也只能使用全名,不能只用简称。需要执行如下命令:

1
2
3
4
echo "alias pscp=parallel-scp" >> ~/.bashrc && . ~/.bashrc
echo "alias prsync=parallel-rsync" >> ~/.bashrc && . ~/.bashrc
echo "alias pnuke=parallel-nuke" >> ~/.bashrc && . ~/.bashrc
echo "alias pslurp=parallel-slurp" >> ~/.bashrc && . ~/.bashrc

其中,pscp把文件并行地复制到多个客户机;prsync使用rsync协议从管理机同步到客户机;pslurp将文件从客户机复制到管理机;pnuke并行地在客户机杀进程。

命令格式

命令格式:pssh [OPTIONS] command [...]

选项:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
--version:查看版本
--help:查看帮助,即此信息
-h:主机文件列表,内容格式"[user@]host[:port]"
-H:主机字符串,内容格式"[user@]host[:port]"
-l:登录使用的用户名
-p:并发的线程数【可选】
-o:输出的文件目录【可选】
-e:错误输入文件【可选】
-t:TIMEOUT 超时时间设置,0无限制【可选】
-O:SSH的选项
-v:详细模式
-A:手动输入密码模式
-x:额外的命令行参数使用空白符号,引号,反斜线处理
-X:额外的命令行参数,单个参数模式,同-x
-i:每个服务器内部处理信息输出
-P:打印出服务器返回信息

实践篇

添加密钥认证访问

参考Linux之SSH密钥认证ssh使用密钥进行认证,在管理机上制作密钥对,将公钥添加给客户机,然后通过ssh免密登录。

1、确认管理机和客户机都安装了ssh。
ps aux | grep ssh

2、在管理机上创建密钥对
ssh-keygen
所有的提示按enter键即可,完成后在home目录执行ll .ssh,即可看到创建好的id_rsa和id_rsa.pub文件。

3、把公钥拷贝到所有客户机中
ssh-copy-id -i .ssh/id_rsa.pub -p 22 test@192.168.56.102

4、测试登录
上一步拷贝完成后,会提示使用ssh -p '22' 'test@192.168.56.102'测试登录。

在管理机中,使用ssh test@192.168.56.102测试登录,我们发现已经不需要输入密码了。

5、查看公钥
登录102客户机,ll .ssh,我们发现有一个authorized_keys文件,文件的内容和管理机的id_rsa.pub相同。

5、测试命令
ssh test@192.168.56.102 '/sbin/ifconfig'

返回了102客户机的ifconfig执行结果,测试成功。

6、设置sudo命令免密码
ssh test@192.168.56.102 'sudo iptables --list'
报错:sudo: no tty present and no askpass program specified

这个问题,需要在每个客户机下进行sudo免密设置。
进入客户机之后,sudo vim /etc/sudoers,添加:

1
test ALL = NOPASSWD: ALL

再次执行ssh test@192.168.56.102 'sudo iptables --list',成功。

获取每台机器的uptime

1、在管理机上新建hosts.txt,内容为:

1
2
3
test@192.168.56.102
test@192.168.56.103
test@192.168.56.104

2、执行uptime
pssh -h hosts.txt -i uptime

3、保存执行结果
pssh -h hosts.txt -i -o /tmp/pssh/ uptime

ll /tmp/pssh

cat /tmp/pssh

批量修改hostname

参考Linux批量修改多台服务器的主机名(hostname),我们把客户机的主机名改为vk102、vk103和vk104。

1、新建hosts文件,内容为:

1
2
3
192.168.56.102    vk102
192.168.56.103 vk103
192.168.56.104 vk104

2、新建hostname.sh文件,内容为:

1
2
3
4
5
6
7
#!/bin/bash
ip=`ifconfig eth0 | grep 'inet' | awk '{print $2}' | tr -d 'addr:'`
hostname=`cat /home/test/hosts | grep $ip | awk '{print $2}'`
echo $ip
echo $hostname
hostnamectl set-hostname --static $hostname
hostname $hostname

3、发送到hosts和hostname.sh到客户机/home/test目录下
pscp -h hosts.txt ./hosts /home/test
pscp -h hosts.txt ./hostname.sh /home/test

4、批量授予hostname.sh可执行权限
pssh -h hosts.txt -i 'chmod +x /home/test/hostname.sh'

5、批量执行hostname.sh
pssh -h hosts.txt -i 'sudo sh /home/test/hostname.sh'
报错:Stderr: hostname: you must be root to change the host name
命令修改为:pssh -h hosts.txt -i 'sudo sh /home/test/hostname.sh'
执行成功。

批量替换sources.list

1、新建sources.list,内容为:

1
2
3
4
5
6
7
8
9
10
deb http://mirrors.aliyun.com/ubuntu/ trusty main restricted universe multiverse  
deb http://mirrors.aliyun.com/ubuntu/ trusty-security main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ trusty-updates main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ trusty-proposed main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ trusty-backports main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ trusty main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ trusty-security main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ trusty-updates main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ trusty-proposed main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ trusty-backports main restricted universe multiverse

2、客户机备份原sources.list
pssh -h hosts.txt -i 'sudo mv /etc/apt/sources.list /etc/apt/sources.list.bak'

3、复制新的sources.list到客户机
pscp -h hosts.txt sources.list /home/test/
pssh -h hosts.txt 'sudo mv /home/test/sources.list /etc/apt/'

4、更新安装源
pssh -h hosts.txt -i 'sudo apt-get update'

批量安装ganglia

参考Ubuntu14.04安装配置Ganglia,假设我们已经配置好了ganglia主节点。

1、把ganglia主节点的/etc/ganglia/gmond.conf文件拷贝到管理机当前目录。

2、编写ganglia安装脚本install-gmond.sh(不要照抄,下面有修改版)

1
2
3
4
5
6
#!/bin/bash
sudo apt-get -y install ganglia-monitor rrdtool && \
sudo mv /etc/ganglia/gmond.conf /etc/ganglia/gmond.conf.bak && \
sudo mv /home/test/gmond.conf /etc/ganglia/ && \
sudo /etc/init.d/ganglia-monitor restart && \
sudo rm -rf /home/test/install-gmond.sh

3、拷贝gmond.conf和install-gmond.sh到客户机
pscp -h hosts.txt gmond.conf /home/test/
pscp -h hosts.txt install-gmond.sh /home/test/

4、添加执行权限
pssh -h hosts.txt -i 'chmod +x /home/test/install-gmond.sh'

5、执行安装
pssh -h hosts.txt -i 'sudo apt-get update'

pssh -h hosts.txt -i 'sudo sh /home/test/install-gmond.sh'

脚本虽然顺利执行了,但是报错:Stderr: debconf: unable to initialize frontend: Dialog
解决办法是修改脚本为:

1
2
3
4
5
6
7
#!/bin/bash
export DEBIAN_FRONTEND=noninteractive DEBCONF_NONINTERACTIVE_SEEN=true && \
sudo apt-get -y -q install ganglia-monitor rrdtool && \
sudo mv /etc/ganglia/gmond.conf /etc/ganglia/gmond.conf.bak && \
sudo mv /home/test/gmond.conf /etc/ganglia/ && \
sudo /etc/init.d/ganglia-monitor restart && \
sudo rm -rf /home/test/install-gmond.sh

6、查看运行状态
pssh -h hosts.txt -i -o /tmp/pssh/ 'ps aux | grep ganglia'

批量修改密码

参考shell实现SSH自动登陆6个Expect脚本示例,使用expect命令。

1、管理机上新建chpasswd.sh脚本,内容如下:

1
2
3
4
5
6
7
8
9
10
11
#!/usr/bin/expect 
set timeout 3
set user test
set password 123456

spawn sudo passwd $user
expect "Enter new UNIX password:"
send "${password}\r"
expect "Retype new UNIX password:"
send "${password}\r"
expect eof

2、在客户机上安装expect(可以用whereis expect查看是否安装)
pssh -h hosts.txt -i 'sudo apt-get install expect -y'

3、拷贝chpasswd.sh脚本到客户机
pscp -h hosts.txt chpasswd.sh /home/test

5、添加执行权限
pssh -h hosts.txt -i 'sudo chmod a+x /home/test/chpasswd.sh'

5、执行修改密码
pssh -h hosts.txt -i 'sudo /home/test/chpasswd.sh'

6、删除chpasswd.sh脚本
pssh -h hosts.txt -i 'sudo rm -rf /home/test/chpasswd.sh'

批量杀进程

假设需要杀死的进程为gmond。
方法一:
pnuke -h hosts.txt gmond
pssh -h hosts.txt -i 'ps -ef | grep gmond'
这种方法虽然显示success,但是查看进程依然存在,看来存在不确定性。猜测对于sudo启动的进程难以杀死。

方法二:
pssh -h hosts.txt -i 'sudo pkill -9 gmond'
这种方法杀的很彻底,是个好方法。

方法三:
pssh -h hosts.txt 'sudo ps -ef | grep gmond | awk '{print $2}' | xargs kill -9'
这种方法也显示success,但是查看进程依然存在,还是有问题。猜测因为sudo作用在了ps上,所以对于sudo启动的进程难以杀死。

方法四:

1
pssh -h hosts.txt -i 'sudo kill -s 9 `pgrep gmond`'

这种方法杀的很彻底,是个好方法。

PS:启动gmond命令pssh -h hosts.txt -i 'sudo /etc/init.d/ganglia-monitor start

后记

以上实践,已经包含了pssh的最常见用法。更高级的用法,就在需要时再去学习吧!