Ansible⼊门教程
简介
Ansible是⼀款简单的运维⾃动化⼯具,只需要使⽤ssh协议连接就可以来进⾏系统管理,⾃动化执⾏命令,部署等任务。
Ansible的特点
1、ansible不需要单独安装客户端,也不需要启动任何服务
2、ansible是中的⼀套完整的⾃动化执⾏任务模块
3、ansible playbook 采⽤yaml配置,对于⾃动化任务执⾏过⼀⽬了然
Ansible组成结构
是Ansible的命令⼯具,核⼼执⾏⼯具;⼀次性或临时执⾏的操作都是通过该命令执⾏。
Ansible Playbook
任务剧本(⼜称任务集),编排定义Ansible任务集的配置⽂件,由Ansible顺序依次执⾏,yaml格式。
Inventory
Ansible管理主机的清单,默认是/etc/ansible/hosts⽂件。
Modules
Ansible执⾏命令的功能模块,Ansible2.3版本为⽌,共有1039个模块。还可以⾃定义模块。
Plugins
插件,模块功能的补充,常有连接类型插件,循环插件,变量插件,过滤插件,插件功能⽤的较少。
API
提供给第三⽅程序调⽤的应⽤程序编程接⼝,提供⼀个功能强⼤,操作性强的Web管理界⾯和REST API接⼝---- AWX平台。
安装
1)配置epel源
[root@ansible ~]# wget -O /pos.po mirrors.aliyun/po
[root@ansible ~]# yum clean all
[root@ansible ~]# yum makecache
2)安装ansible
sudo yum install epel-release
sudo yum install ansible
ansible --version
Ansible Inventory⽂件
Inventory⽂件通常⽤于定义要管理的主机的认证信息,例如ssh登录⽤户名、密码以及key相关信息。可以同时操作⼀个组的多台主机,组与主机组之间的关系都是通过inventory⽂件配置。配置⽂件路径为:/etc/ansible/hosts
配置连接
基于密码连接
> vim /etc/ansible/hosts
# ⼀、主机+端⼝+密码
[webserver]  #定义分组 webserver,可以定义多个分组
192.168.1.31 ansible_ssh_port=22 ansible_ssh_user=root ansible_ssh_pass="123456"
192.168.1.32 ansible_ssh_port=22 ansible_ssh_user=root ansible_ssh_pass="123456"
192.168.1.33 ansible_ssh_port=22 ansible_ssh_user=root ansible_ssh_pass="123456"
# ⼆、主机+端⼝+密码
[webserver]
192.168.1.3[1:3] ansible_ssh_user=root ansible_ssh_pass="123456"
基于秘钥连接
基于秘钥连接需要先创建公钥和私钥,并发送给被管理机器;
1)⽣成公私钥
ssh-keygen
# ssh-copy-id 将本机的公钥复制到远程机器的authorized_keys⽂件中,ssh-copy-id也能让远程机器的home, ~./ssh , 和 ~/.ssh/authorized_keys的权利
for i in {1,2,3,6}; do ssh-copy-id -i 192.168.1.3$i ; done
2)配置连接
vim /etc/ansible/hosts
# ⼀、主机+端⼝+密钥
[webserver]
192.168.1.31:22
192.168.1.32
192.168.1.33
192.168.1.36
# ⼆、别名主机+端⼝+密钥
[webserver]
node1 ansible_ssh_host=192.168.1.31 ansible_ssh_port=22
node2 ansible_ssh_host=192.168.1.32 ansible_ssh_port=22
node3 ansible_ssh_host=192.168.1.33 ansible_ssh_port=22
主机组的使⽤
主机组变量名+主机+密码
[apache]
192.168.1.36
192.168.1.33
[apache.vars]
ansible_ssh_pass='123456'
主机组变量名+主机+密钥
[nginx]
192.168.1.3[1:2]
把⼀个组当另外⼀个组的组员
[webserver:children]  #webserver组包括两个⼦组:apache nginx
perl下载安装教程apache
nginx
完整⽂件
shell > vim /etc/ansible/hosts
www.abc    # 定义域名
192.168.1.100  # 定义 IP
192.168.1.150:37268  # 指定端⼝号
[WebServer]          # 定义分组
192.168.1.10
192.168.1.20
192.168.1.30
[DBServer]            # 定义多个分组
192.168.1.50
192.168.1.60
Monitor ansible_ssh_port=12378 ansible_ssh_host=192.168.1.200  # 定义别名
# ansible_ssh_host 连接⽬标主机的地址
# ansible_ssh_port 连接⽬标主机的端⼝,默认 22 时⽆需指定
# ansible_ssh_user 连接⽬标主机默认⽤户
# ansible_ssh_pass 连接⽬标主机默认⽤户密码
# ansible_ssh_connection ⽬标主机连接类型,可以是 local 、ssh 或 paramiko
# ansible_ssh_private_key_file 连接⽬标主机的 ssh 私钥
# ansible_*_interpreter 指定采⽤⾮ Python 的其他脚本语⾔,如 Ruby 、Perl 或其他类似 ansible_python_interpreter 解释器
[webservers]        # 主机名⽀持正则描述
www[01:50].example
[dbservers]
db-[a:f].example
Inventory内置参数
其他配置⽂件
/etc/ansible/ansible.cfg #主配置⽂件,配置ansible⼯作特性
/etc/ansible/hosts #主机清单(将要连接操控的主机IP地址写在此配置⽂件的最下⽅)
/etc/ansible/roles/ #存放⾓⾊的⽬录
程序
/usr/bin/ansible    #主程序,临时命令执⾏⼯具
/usr/bin/ansible-doc #查看配置⽂档,模块功能查看⼯具
/usr/bin/ansible-galaxy #下载/上传优秀代码或Roles模块的官⽹平台
/usr/bin/ansible-playbook #定制⾃动化任务,编排剧本⼯具/
/
usr/bin/ansible-pull #远程执⾏命令的⼯具
/usr/bin/ansible-vault #⽂件加密⼯具
/usr/bin/ansible-console #基于Console界⾯与⽤户交互的执⾏⼯具
ansible命令格式
ansible <;需要执⾏命令的⽬标主机或组> <ansible命令选项,指定模块> <;需要使⽤的模块,shell命令模块> <ansible命令选项,指定模块中要⽤到的参数> <;模块中的参数(shell命令)>参数
参数可以有多个,如果不加-m,执⾏的是command模式,也就是shell命令;-a必须添加
ansible all    #对所有主机执⾏
ansible group --list    #输出组中的主机
ansible 'a:!n' -m ping -o      #匹配a组中有,但是n组中没有的所有主机
ansible 'apache:&nginx' -m ping -o    #匹配a组和n组中都有的机器(并集)
ansible-doc -l    # 列出 Ansible ⽀持的模块
ansible-doc ping  #查看指定模块(ping)帮助⽤法
ansible-doc –s ping #查看指定模块(ping)帮助⽤法
测试ansible
shell > ansible Client -m ping    # 操作 Client 组 ( all 为操作 hosts ⽂件中所有主机 ),-m 指定执⾏ ping 模块,下⾯是返回结果
192.168.12.129 | SUCCESS => {
"changed": false,
"ping": "pong"
}
# -i          指定 hosts ⽂件位置
# -u username 指定 SSH 连接的⽤户名
# -k          指定远程⽤户密码
# -f          指定并发数
# -s          如需要 root 权限执⾏时使⽤ ( 连接⽤户不是 root 时 )
# -K          -s 时,-K 输⼊ root 密码
ansible常⽤模块
shell > ansible-doc -l    # 列出 Ansible ⽀持的模块
shell > ansible-doc ping  # 查看该模块帮助信息
远程命令模块(command / script / shell)
command
command 作为 Ansible 的默认模块,可以运⾏远程权限范围所有的 shell 命令,不⽀持管道符。
shell > ansible Client -m command -a "free -m"              # 查看 Client 分组主机内存使⽤情况
script 的功能是在远程主机执⾏主控端存储的 shell 脚本⽂件,相当于 scp + shell 组合。
shell > ansible Client -m script -a "/home/test.sh 12 34"    # 远程执⾏本地脚本
shell
shell模块基本和command相同,但是shell⽀持管道符
shell > ansible Client -m shell -a "/home/test.sh"          # 执⾏远程脚本
copy模块
实现主控端向⽬标主机拷贝⽂件,类似于 scp 功能
shell > ansible Client -m copy -a "src=/home/test.sh dest=/tmp/ owner=root group=root mode=0755"  # 向 Client 组中主机拷贝 test.sh 到 /tmp 下,属主、组为 root ,权限为 0755
stat模块
获取远程⽂件状态信息,atime/ctime/mtime/md5/uid/gid 等信息
shell > ansible Client -m stat -a "path=/f"
get_url
实现在远程主机下载指定 URL 到本地,⽀持 sha256sum ⽂件校验
shell > ansible Client -m get_url -a "url=www.baidu dest=/tmp/index.html mode=0440 force=yes"
yum
软件包管理
shell > ansible Client -m yum -a "name=curl state=latest"
corn
远程主机 crontab 配置
shell > ansible Client -m cron -a "name='check dirs' hour='5,2' job='ls -alh > /dev/null'"
效果:
* 5,2 * * * ls -alh > /dev/null
mount
远程主机分区挂载
shell > ansible Client -m mount -a "name=/mnt/data src=/dev/sd0 fstype=ext4 opts=ro state=present"
service
远程主机系统服务管理
shell > ansible Client -m service -a "name=nginx state=stoped"
shell > ansible Client -m service -a "name=nginx state=restarted"
shell > ansible Client -m service -a "name=nginx state=reloaded"
user
远程主机⽤户管理
shell > ansible Client -m user -a "name=wang comment='user wang'"
shell > ansible Client -m user -a "name=wang state=absent remove=yes"    # 添加删除⽤户
PlayBook执⾏过程
使⽤ansible的-vvv或-vvvv分析执⾏过程。以下是⼀个启动远程192.168.100.61上httpd任务的执⾏过程分析。其中将不必要的信息都是⽤"....."替换了。
# 读取配置⽂件,然后开始执⾏对应的处理程序。
Using /etc/ansible/ansible.cfg as config file
META: ran handlers
# 第⼀个任务默认都是收集远程主机信息的任务。
# 第⼀个收集任务,加载setup模块
Using module file /usr/lib/python2.7/site-packages/ansible/modules/system/setup.py
# 建⽴连接,获取被控节点当前⽤户的家⽬录,⽤于存放稍后的临时任务⽂件,此处返回值为/root。
# 在-vvv的结果中,第⼀⾏属于描述性信息,第⼆⾏为代码执⾏段,第三⾏类似此处的<host_node>(,,,,,)为上⼀段代码的返回结果。后同
<192.168.100.61> ESTABLISH SSH CONNECTION FOR USER: None
<192.168.100.61> SSH: EXEC ssh -C ..........................
<192.168.100.61> (0, '/root\n', '')
# 再次建⽴连接,在远端创建临时任务⽂件的⽬录,临时⽬录由配置⽂件中的remote_tmp指令控制
<192.168.100.61> ESTABLISH SSH CONNECTION FOR USER: None
<192.168.100.61> SSH: EXEC ssh -C .......................... '/bin/sh -c '"'"'( umask 77 && mkdir -p "` echo /root/.ansible/tmp/ansible-tmp-1495977564.58-40718671162202 `" && echo ansible-tmp-1495977564.58-4071867116 <192.168.100.61> (0, 'ansible-tmp-1495977564.58-40718671162202=/root/.ansible/tmp/ansible-tmp-1495977564.58-40718671162202\n', '')
# 将要执⾏的任务放到临时⽂件中,并使⽤sftp将任务⽂件传输到被控节点上
<192.168.100.61> PUT /tmp/tmpY5vJGX TO /root/.ansible/tmp/ansible-tmp-1495977564.58-40718671162202/setup.py
<192.168.100.61> SSH: EXEC sftp -b - -C ............. '[192.168.100.61]'
<192.168.100.61> (0, 'sftp> put /tmp/tmpY5vJGX /root/.ansible/tmp/ansible-tmp-1495977564.58-40718671162202/setup.py\n', '')
# 建⽴连接,设置远程任务⽂件其所有者有可执⾏权限
<192.168.100.61> ESTABLISH SSH CONNECTION FOR USER: None
<192.168.100.61> SSH: EXEC ssh -C ......................... '/bin/sh -c '"'"'chmod u+x /root/.ansible/tmp/ansible-tmp-1495977564.58-40718671162202/ /root/.ansible/tmp/ansible-tmp-1495977564.58-40718671162202/setup.py <192.168.100.61> (0, '', '')
# 建⽴连接,执⾏任务,执⾏完成后⽴即删除任务⽂件,并返回收集到的信息给ansible。到此为⽌,setup收集任务结束,关闭共享连接
<192.168.100.61> ESTABLISH SSH CONNECTION FOR USER: None
<192.168.100.61> SSH: EXEC ssh -C ............ '/bin/sh -c '"'"'/usr/bin/python /root/.ansible/tmp/ansible-tmp-1495977564.58-40718671162202/setup.py; rm -rf "/root/.ansible/tmp/ansible-tmp-1495977564.58-407186711622 <192.168.100.61> (0, '\r\n{"invocation": {"...........', 'Shared connection to 192.168.100.61 closed.\r\n')
# 进⼊下⼀个任务,此处为服务管理任务,所以加载service模块
<192.168.100.61> ESTABLISH SSH CONNECTION FOR USER: None
<192.168.100.61> SSH: EXEC ssh -C .........................
<192.168.100.61> (0, '/root\n', '')
# 建⽴连接,将要执⾏的任务放⼊到临时⽂件中,并传输到远程⽬录
<192.168.100.61> ESTABLISH SSH CONNECTION FOR USER: None
<192.168.100.61> SSH: EXEC ssh -C .............. '/bin/sh -c '"'"'( umask 77 && mkdir -p "` echo /root/.ansible/tmp/ansible-tmp-1495977564.97-137863382080241 `" && echo ansible-tmp-1495977564.97-137863382080241 <192.168.100.61> (0, 'ansible-tmp-1495977564.97-137863382080241=/root/.ansible/tmp/ansible-tmp-1495977564.97-137863382080241\n', '')
<192.168.100.61> PUT /tmp/tmpn5uZhP TO /root/.ansible/tmp/ansible-tmp-1495977564.97-137863382080241/service.py
<192.168.100.61> SSH: EXEC sftp -b - -C .............. '[192.168.100.61]'
<192.168.100.61> (0, 'sftp> put /tmp/tmpn5uZhP /root/.ansible/tmp/ansible-tmp-1495977564.97-137863382080241/service.py\n', '')
# 建⽴连接,设置远程任务⽂件其所有者有可执⾏权限
<192.168.100.61> ESTABLISH SSH CONNECTION FOR USER: None
<192.168.100.61> SSH: EXEC ssh -C ........................ '/bin/sh -c '"'"'chmod u+x /root/.ansible/tmp/ansible-tmp-1495977564.97-137863382080241/ /root/.ansible/tmp/ansible-tmp-1495977564.97-137863382080241/servic <192.168.100.61> (0, '', '')
# 建⽴连接,执⾏任务,执⾏完成后⽴即删除任务⽂件,并将执⾏的结果返回到ansible端。到此为⽌,service模块任务执⾏结束,关闭共享连接
<192.168.100.61> ESTABLISH SSH CONNECTION FOR USER: None
<192.168.100.61> SSH: EXEC ssh -C .............. '/bin/sh -c '"'"'/usr/bin/python /root/.ansible/tmp/ansible-tmp-1495977564.97-137863382080241/service.py; rm -rf "/root/.ansible/tmp/ansible-tmp-1495977564.97-137863382将上⾯的进⾏总结,执⾏过程将是这样的:
读取配置⽂件
加载inventory⽂件。包括主机变量和主机组变量
执⾏第⼀个任务:收集远程被控节点的信息
建⽴连接,获取家⽬录信息
将要执⾏的收集任务放到临时⽂件中
将临时任务⽂件传输到被控节点的临时⽬录中
ssh连接到远端执⾏收集任务
删除任务⽂件
将收集信息返回给ansible端
关闭连接
执⾏第⼆个任务,此为真正的主任务
建⽴连接,获取家⽬录信息
将要执⾏的任务放到临时⽂件中
将临时任务⽂件传输到被控节点的临时⽬录中
ssh连接到远端执⾏任务
删除任务⽂件
将执⾏结果返回给ansible端,ansible输出到屏幕或指定⽂件中
关闭连接
执⾏第三个任务
执⾏第四个任务
如果是多个被控节点,那么将同时在多个节点上并⾏执⾏每⼀个任务,例如同时执⾏信息收集任务。不同节点之间的任务没有先后关系,主要依赖于性能。每⼀个任务执⾏完毕都会⽴即将
结果返回给ansible端,所以可以通过ansible端结果的输出顺序和速度判断执⾏完毕的先后顺序。
如果节点数太多,ansible⽆法⼀次在所有远程节点上执⾏任务,那么将先在⼀部分节点上执⾏⼀个任务(每⼀批节点的数量取决于fork进程数量),直到这⼀批所有节点上该任务完全执⾏完毕
才会接⼊下⼀个批节点(数量取决于fork进程数量),直到所有节点将该任务都执⾏完毕,然后重新回到第⼀批节点开始执⾏第⼆个任务。依次类推,直到所有节点执⾏完所有任务,ansible端
才会释放shell。这是默认的同步模式,也就是说在未执⾏完毕的时候,ansible是占⽤当前shell的,任务执⾏完毕后,释放shell了才可以输⼊其他命令做其他动作。
如果是异步模式,假如fork控制的并发进程数为5,远程控制节点为24个,则ansible⼀开始会将5个节点的任务扔在后台,并每隔⼀段时间去检查这些节点的任务完成情况,当某节点完成不
会⽴即返回,⽽是继续等待直到5个进程都空闲了,才会将这5个节点的结果返回给ansible端,ansible会继续将下⼀批5个节点的任务扔在后台并每隔⼀段时间进⾏检查,依次类推,直到完
成所有任务。
在异步模式下,如果设置的检查时间间隔为0,在将每⼀批节点的任务丢到后台后都会⽴即返回ansible,并⽴即将下⼀批节点的任务丢到后台,直到所有任务都丢到后台完成后,会返回
ansible端,ansible会⽴即释放占⽤的shell。也就是说,此时ansible是不会管各个节点的任务执⾏情况的,不管执⾏成功还是失败。
因此,在轮训检查时间内,ansible仍然正在运⾏(尽管某批任务已经被放到后台执⾏了),当前shell进程仍被占⽤处于睡眠状态,只有指定的检查时间间隔为0,才会尽快将所有任务放到后台
并释放shell。
需要注意3点:
1. 按批(例如每次5台全部完成⼀个任务才进⼊下⼀批的5台)完成任务的模式在ansible
2.0版本之后可以通过修改ansible的执⾏策略来改变(见),改变后会变成"前赴后继"的执⾏模式:当⼀
个节点执⾏完⼀个任务会⽴即接⼊另⼀个节点,不再像默认情况⼀样等待这⼀批中的其他节点完成该任务。
2. 上⾯执⾏过程是默认的执⾏过程,如果开启了pipelining加速ansible执⾏效率,会省去sftp到远端的过程。
3. 信息收集任务是默认会执⾏的,但是可以设置禁⽤它。
Ansible并发和异步
上⾯已经对ansible的执⾏过程进⾏了很详细的分析,也解释了同步和异步的模式是如何处理任务的。所以此处简单举⼏个例⼦。
ansible默认只会创建5个进程并发执⾏任务,所以⼀次任务只能同时控制5台机器执⾏。如果有⼤量的机器需要控制,例如20台,ansible执⾏⼀个任务时会先在其中5台上执⾏,执⾏成功后
再执⾏下⼀批5台,直到全部机器执⾏完毕。使⽤ -f 选项可以指定进程数,指定的进程数量多⼀些,不仅会实现全并发,对异步的轮训poll也会有正⾯影响。
ansible默认是同步阻塞模式,它会等待所有的机器都执⾏完毕才会在前台返回。可以采取异步执⾏模式。
异步模式下,ansible会将节点的任务丢在后台,每台被控制的机器都有⼀个job_id,ansible会根据这个job_id去轮训该机器上任务的执⾏情况,例如某机器上此任务中的某⼀个阶段是否完
成,是否进⼊下⼀个阶段等。即使任务早就结束了,但只有轮训检查到任务结束后才认为该job结束。可以指定任务检查的时间间隔,默认是10秒。除⾮指定任务检查的间隔为0,否则会等
待所有任务都完成后,ansible端才会释放占⽤的shell。
如果指定时间间隔为0,则ansible会⽴即返回(⾄少得连接上⽬标主机,任务发布成功之后⽴即返回),并不会去检查它的任务进度。
ansible centos -B200 -P 0 -m yum -a "name=dos2unix" -o -f 6
192.168.100.61 | SUCCESS => {"ansible_job_id": "986026954359.9166", "changed": true, "finished": 0, "results_file": "/root/.ansible_async/986026954359.9166", "started": 1}
192.168.100.59 | SUCCESS => {"ansible_job_id": "824724696770.9431", "changed": true, "finished": 0, "results_file": "/root/.ansible_async/824724696770.9431", "started": 1}
192.168.100.60 | SUCCESS => {"ansible_job_id": "276581152579.10006", "changed": true, "finished": 0, "results_file": "/root/.ansible_async/276581152579.10006", "started": 1}
192.168.100.64 | SUCCESS => {"ansible_job_id": "237326453903.72268", "changed": true, "finished": 0, "results_file": "/root/.ansible_async/237326453903.72268", "started": 1}
192.168.100.63 | SUCCESS => {"ansible_job_id": "276700021098.73070", "changed": true, "finished": 0, "results_file": "/root/.ansible_async/276700021098.73070", "started": 1}
192.168.100.65 | SUCCESS => {"ansible_job_id": "877427488272.72032", "changed": true, "finished": 0, "results_file": "/root/.ansible_async/877427488272.72032", "started": 1}
关于同步、异步以及异步时的并⾏数、轮训间隔对ansible的影响,通过以下⽰例说明:
当有6个节点时,仅就释放shell的速度⽽⾔,以下⼏种写法:
# 同步模式,⼤约10秒返回。
ansible centos -m command -a "sleep 5" -o
# 异步模式,分两批执⾏。⼤约10秒返回。
ansible centos -B200 -P 1 -m command -a "sleep 5" -o -f 5
# 异步模式,和上⼀条命令时间差不多,但每次检查时间长⼀秒,所以可能会稍有延迟。⼤约11-12秒返回。
ansible centos -B200 -P 2 -m command -a "sleep 5" -o -f 5
# 异步模式,⼀批就执⾏完,⼤约5-6秒返回。
ansible centos -B200 -P 1 -m command -a "sleep 5" -o -f 6
# 异步模式,⼀批就完成,⼤约5-6秒完成。
ansible centos -B200 -P 2 -m command -a "sleep 5" -o -f 6
# 异步模式,⼀批执⾏完成,但检查时间超过睡眠时间,因此⼤约10秒返回。
ansible centos -B200 -P 10 -m command -a "sleep 5" -o -f 6
在异步执⾏任务时,需要注意那些有依赖性的任务。对于那些对资源要求占有排它锁的任务,如yum,不应该将Poll的间隔设置为0。如果设置为0,很可能会导致资源阻塞。
总结来说,⼤概有以下⼀些场景需要使⽤到ansible的异步特性:
某个task需要运⾏很长的时间,这个task很可能会达到ssh连接的timeout
没有任务是需要等待它才能完成的,即没有任务依赖此任务是否完成的状态
需要尽快返回当前shell
当然也有⼀些场景不适合使⽤异步特性:
这个任务是需要运⾏完后才能继续另外的任务的
申请排它锁的任务
当然,对于有任务依赖性的任务,也还是可以使⽤异步模式的,只要检查它所依赖的主任务状态已完成就可以。例如,要配置nginx,要求先安装好nginx,在配置nginx之前先检查yum安装的状态。
- name: 'YUM - fire and forget task'
yum: name=nginx state=installed
async: 1000
poll: 0
register: yum_sleeper
- name: 'YUM - check on fire and forget task'
async_status: jid={{ yum_sleeper.ansible_job_id }}
register: job_result
until: job_result.finished
retries: 30
ansible的 -t 选项妙⽤
ansible的"-t"或"--tree"选项是将ansible的执⾏结果按主机名保存在指定⽬录下的⽂件中。
有些时候,ansible执⾏起来的速度会⾮常慢,这种慢体现在即使执⾏的是⼀个⽴即返回的简单命令(如ping模块),也会耗时很久,且不是因为ssh连接慢导致的。如果使⽤-t选项,将第⼀次执⾏得到的结果按inventory中定义的主机名保存在⽂件中,下次执⾏到同⼀台主机时速度将会变快很多,即使之后不再加上-t选项,也可以在⼀定时间内保持迅速执⾏。即使执⾏速度正常(如执⾏⼀个Ping命令0.7秒左右),使⽤-t选项也可以在此基础上变得更快。
除了使⽤-t选项,使⽤重定向将结果重定向到某个⽂件中也是⼀样的效果。⾄于为何会如此,我也不知道,是在⽆意中测试出来的。有必要指出:我在CentOS 6.6上遇到过这样的问题,但并不是总会如此,且在CentOS 7上正常。因此,如果你也出现了这样的问题,可以参考这种偏⽅。
以CentOS 6.6安装的ansible 2.3为例,正常执⾏ansible会⾮常慢,使⽤-t可以解决这个问题。如下。
没有使⽤-t时:移除dos2unix包所需时间为13秒多。
time ansible centos -B200 -P 0 -m yum -a "name=dos2unix state=removed" -o -f 6
192.168.100.60 | SUCCESS => {"ansible_job_id": "987125400759.10653", "changed": true, "finished": 0, "results_file": "/root/.ansible_async/987125400759.10653", "started": 1}
192.168.100.63 | SUCCESS => {"ansible_job_id": "735153954362.74074", "changed": true, "finished": 0, "results_file": "/root/.ansible_async/735153954362.74074", "started": 1}
192.168.100.61 | SUCCESS => {"ansible_job_id": "192721090554.9813", "changed": true, "finished": 0, "results_file": "/root/.ansible_async/192721090554.9813", "started": 1}
192.168.100.64 | SUCCESS => {"ansible_job_id": "494724112239.73269", "changed": true, "finished": 0, "results_file": "/root/.ansible_async/494724112239.73269", "started": 1}
192.168.100.59 | SUCCESS => {"ansible_job_id": "2259915341.10078", "changed": true, "finished": 0, "results_file": "/root/.ansible_async/2259915341.10078", "started": 1}
192.168.100.65 | SUCCESS => {"ansible_job_id": "755223232484.73025", "changed": true, "finished": 0, "results_file": "/root/.ansible_async/755223232484.73025", "started": 1}
real    0m13.746s
user    0m1.288s
sys    0m1.417s
使⽤-t选项后:安装dos2unix只需1.9秒左右。
time ansible centos -B200 -P 0 -m yum -a "name=dos2unix state=installed" -o -f 6 -t /tmp/a
real    0m1.933s
user    0m0.398s
sys    0m0.900s
之后即使不再使⽤-t选项,对同样的主机进⾏操作,速度也会变得⾮常快。
time ansible centos -B200 -P 0 -m yum -a "name=dos2unix state=removed" -o -f 6
real    0m1.730s
user    0m0.892s
sys    0m0.572s
⾄于保存的内容为何?实际上仅仅只是保存了普通的输出内容⽽已。
ll /tmp/a/
total 24
-rw-r--r-- 1 root root 145 May 28 15:54 192.168.100.59
-rw-r--r-- 1 root root 145 May 28 15:54 192.168.100.60
-rw-r--r-- 1 root root 143 May 28 15:54 192.168.100.61
-rw-r--r-- 1 root root 143 May 28 15:54 192.168.100.63
-rw-r--r-- 1 root root 145 May 28 15:54 192.168.100.64
-rw-r--r-- 1 root root 145 May 28 15:54 192.168.100.65
cat /tmp/a/192.168.100.59
{"ansible_job_id": "659824383578.10145", "changed": true, "finished": 0, "results_file": "/root/.ansible_async/659824383578.10145", "started": 1}
优化ansible速度
最初,ansible的执⾏效率和saltstack(基于zeromq消息队列的⽅式)相⽐要慢的多的多,特别是被控节点量很⼤的时候。但是ansible发展到现在,它的效率得到了极⼤的改善。在被控节点不太多的时候,默认的设置已经够快,即使被控节点数量巨⼤的时候,也可以通过⼀些优化,极⼤的提⾼其执⾏效率。
前⾯"-t"选项也算是⼀种提速⽅式,但算是"bug"式的问题,所以没有通⽤性。
设置ansible开启ssh长连接
ansible天然⽀持openssh,默认连接⽅式下,它对ssh的依赖性⾮常强。所以优化ssh连接,在⼀定程度上也在优化ansible。其中⼀点是开启ssh的长连接,即长时间保持连接状态。
要开启ssh长连接,要求ansible端的openssh版本⾼于或等于5.6。使⽤ssh -V可以查看版本号。然后设置ansible使⽤ssh连接被控端的连接参数,此处修改/etc/ansible/ansible.cfg,在此⽂件中启动下⾯的连接选项,其中ControlPersist=5d是控制ssh连接会话保持时长为5天。
ssh_args = -C -o ControlMaster=auto -o ControlPersist=5d
除此之外直接设置/etc/ssh/ssh_config(不是sshd_config,因为ssh命令是客户端命令)中对应的长连接项也是可以的。开启长连接后,在会话过期前会⼀直建⽴连接,在netstat的结果中会看到ssh连接是⼀直established状态,且会在当前⽤户家⽬录的".ansible/cp"⽬录下⽣成⼀些socket⽂件,每个会话⼀个⽂件。例如:执⾏⼀次ad-hoc操作。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。