1. 前言
《Ubuntu系统批量自动安装》一文中,配置好了PXE服务器,也通过它安装了几台机器。每个机器都重新配置好了IP,已经可以远程访问了。现在新的问题来了,每个机器的主机名都相同,需要修改;每个机器的sources.list都有问题,需要替换。以后,肯定也有很多其他需要批量操作的问题,比如批量安装ganglia,总不能上百台机器一个个手动操作吧!
本文,就研究下linux批量操作的相关方法和工具,重点研究下pssh。
2. 批量操作思路
首先定义两个概念:管理机和客户机,本文中的管理机是指管理其他服务器的服务器,客户机是指普通服务器。
管理机IP为192.168.56.101,客户机IP为192.168.56.102-104,用户名都是test。
2.1. 思路一
说到批量操作,最容易想到的,肯定是在管理机写一个脚本,里面有个循环语句,挨个连接客户机进行操作。
而循环语句里面,主要是ssh
,然后执行交互命令。参考 shell实现SSH自动登陆 、 关于SSH 远程执行命令你要知道的二三事 和 shell脚本实现同时多台远程主机执行命令的代码分享。
但是,这种方式很难并行处理,比较浪费时间。
2.2. 思路二
另一个简单的思路,是在管理机写一个在客户机执行的脚本,然后推送给客户机,再在客户机里执行脚本。主要参考SSH 远程执行任务。
这种方式同样很难并行处理,比较浪费时间。如果非要并行处理,那么就只能牺牲反馈信息。
2.3. 思路三
最后一种思路就是借助工具,比如mussh、pdsh、pssh等等。
3. pssh
3.1. pssh简介
pssh是一个python编写可以在多台服务器上执行命令的工具,同时支持拷贝文件,是同类工具中很出色的。类似pdsh,但是相对pdsh更为简便,使用前必须在各个服务器上配置好密钥认证访问。参考pssh命令和pssh HOWTO。
3.2. 安装
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 | echo "alias pscp=parallel-scp" >> ~/.bashrc && . ~/.bashrc |
其中,pscp把文件并行地复制到多个客户机;prsync使用rsync协议从管理机同步到客户机;pslurp将文件从客户机复制到管理机;pnuke并行地在客户机杀进程。
3.3. 命令格式
命令格式:pssh [OPTIONS] command [...]
选项:
1 | --version:查看版本 |
4. 实践篇
4.1. 添加密钥认证访问
参考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'
,成功。
4.2. 获取每台机器的uptime
1、在管理机上新建hosts.txt,内容为:
1 | test@192.168.56.102 |
2、执行uptimepssh -h hosts.txt -i uptime
3、保存执行结果pssh -h hosts.txt -i -o /tmp/pssh/ uptime
ll /tmp/pssh
cat /tmp/pssh
4.3. 批量修改hostname
参考Linux批量修改多台服务器的主机名(hostname),我们把客户机的主机名改为vk102、vk103和vk104。
1、新建hosts文件,内容为:
1 | 192.168.56.102 vk102 |
2、新建hostname.sh文件,内容为:
1 |
|
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.shpssh -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'
执行成功。
4.4. 批量替换sources.list
1、新建sources.list,内容为:
1 | deb http://mirrors.aliyun.com/ubuntu/ trusty main restricted universe multiverse |
2、客户机备份原sources.listpssh -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'
4.5. 批量安装ganglia
参考Ubuntu14.04安装配置Ganglia,假设我们已经配置好了ganglia主节点。
1、把ganglia主节点的/etc/ganglia/gmond.conf
文件拷贝到管理机当前目录。
2、编写ganglia安装脚本install-gmond.sh(不要照抄,下面有修改版)
1 |
|
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 |
|
6、查看运行状态pssh -h hosts.txt -i -o /tmp/pssh/ 'ps aux | grep ganglia'
4.6. 批量修改密码
参考shell实现SSH自动登陆 和 6个Expect脚本示例,使用expect命令。
1、管理机上新建chpasswd.sh脚本,内容如下:
1 | #!/usr/bin/expect |
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'
4.7. 批量杀进程
假设需要杀死的进程为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
5. 后记
以上实践,已经包含了pssh的最常见用法。更高级的用法,就在需要时再去学习吧!