使用ansible批量管理远程服务器

使用ansible批量管理远程服务器

背景

本地须要管理远程的一批服务器,主要执行如下任务:html

1) 将本地的文件复制到远端全部服务器;
2) 须要在远程服务器中执行一个个命令;python

远端服务器路径并不是彻底一致,通常访问经过环境变量中定义的变量路径访问;
好比在.bashrc中定义$app_path=/opt/app/bingit

最终选择ansible,使用这个自动化运维工具能够知足个人需求;
下面介绍下对于我这种场景须要使用的ansible的主要模块;
关于ansible是什么以及安装配置请自行百度;github

复制

copy模块

使用copy模块,能够将本地文件一键复制到远程服务器;
-a后跟上参数,参数中指定本地文件和远端路径;shell

ansible myservers -m copy -a "src=/opt/app/bin/transfer.tar dest=~/"

ansible经过ssh登陆到远程服务器后,并不执行.bash_profile来设置用户自定义的环境变量;若是咱们须要管理的目标服务器的路径不一样,就不能直接写绝对路径,也不能写变量替换的路径;api

好比:针对服务器A的目标复制路径为 /opt/app/user1/bin ,服务器B的目标复制路径为/opt/app/user2/bin; 这两个路径在各自的服务器中的路径变量都设置为$bin; 但在copy模块中,咱们不能直接使用dest = $bin/;
路径设置通常放在.bashrc /.bash_profile文件,但ansible模块登陆后并不加载这两个文件;bash

解决方法:
针对这种状况,能够将dest路径设置为~/,都复制到用户目录,后续再经过远程脚本处理;服务器

远程批量命令

须要在远程执行一个个命令来管理远程服务器;app

远程执行命令的模块有command、shell、scripts、以及raw模块;运维

command模块

command模块为ansible默认模块,不指定-m参数时,使用的就是command模块;
comand模块比较简单,常见的命令均可以使用,但其命令的执行不是经过shell执行的,因此,像这些 "<", ">", "|", and "&"操做都不能够,固然,也就不支持管道;
示例:显示远程路径:

ansible myservers  -a 'pwd'
10.6.143.38 | success | rc=0 >>
/home/rduser
10.6.143.53 | success | rc=0 >>
/home/rduser
10.6.143.37 | success | rc=0 >>
/home/rduser

缺点:不支持管道,就无法批量执行命令;

shell模块

使用shell模块,在远程命令经过/bin/sh来执行;因此,咱们在终端输入的各类命令方式,均可以使用;
可是咱们本身定义在.bashrc/.bash_profile中的环境变量shell模块因为没有加载,因此没法识别;若是须要使用自定义的环境变量,就须要在最开始,执行加载自定义脚本的语句;

对shell模块的使用能够分红两块:
1) 若是待执行的语句少,能够直接写在一句话中:

ansible myservers  -a ". .bash_profile;ps -fe |grep sa_q" -m shell

2) 若是在远程待执行的语句比较多,可写成一个脚本,经过copy模块传到远端,而后再执行;但这样就又涉及到两次ansible调用;对于这种需求,ansible已经为咱们考虑到了,script模块就是干这事的;

scripts模块

使用scripts模块能够在本地写一个脚本,在远程服务器上执行:

ansible myservers  -m script -a "/opt/app/target.sh"

这里是命令模块的官方文档:
http://docs.ansible.com/list_of_commands_modules.html

批量执行playbooks

远程批量命令执行的另一种方式是用playbooks;
这里是playbooks的官方文档:http://docs.ansible.com/playbooks.html
这里有ansible的playbooks示例:https://github.com/ansible/ansible-examples

在python中使用ansbile API

以上执行ansible模块的方式都是在命令行中直接调用,若是对返回结果须要进一步处理,能够在程序中经过API调用的方式来使用ansible模块:
好比,以上在命令行中调用scripts的模块的方式在API中调用:

import ansible.runner
results = ansible.runner.Runner(
pattern='myservers', forks=5,
module_name='script', module_args='/opt/app/target.sh',
).run()

这里是官方给出的一个详细示例,直接运行一次,将result所有打印出来,会有直观的了解:

#!/usr/bin/python

import ansible.runner
import sys

# construct the ansible runner and execute on all hosts
results = ansible.runner.Runner(
pattern='*', forks=10,
module_name='command', module_args='/usr/bin/uptime',
).run()

if results is None:
   print "No hosts found"
   sys.exit(1)

print "UP ***********"
for (hostname, result) in results['contacted'].items():
if not 'failed' in result:
print "%s >>> %s" % (hostname, result['stdout'])

print "FAILED *******"
for (hostname, result) in results['contacted'].items():
if 'failed' in result:
print "%s >>> %s" % (hostname, result['msg'])

print "DOWN *********"
for (hostname, result) in results['dark'].items():
print "%s >>> %s" % (hostname, result)

API设计详见:http://docs.ansible.com/developing_api.html

Posted by: 大CC | 26MAY,2015
博客:blog.me115.com [订阅]
微博:新浪微博

相关文章
相关标签/搜索