Bendi新闻
>
Ansible 你快点:Ansible 执行过程分析、异步、效率优化
Ansible 你快点:Ansible 执行过程分析、异步、效率优化
6月前
链接:https://www.cnblogs.com/f-ck-need-u/p/17718504.html
Ansible你快点:Ansible执行过程分析、异步、效率优化
11.1 测量任务执行速度:profile_tasks插件
(1). profile_tasks
:该回调插件用于计时每个任务的执行时长(2). profile_roles
插件用于计时每个Role的执行时长(3). timer
插件用于计时每个play执行时长
callback_whitelist
中加入各插件。如下:1
2
3[defaults]
callback_whitelist = profile_tasks
# callback_whitelist = profile_tasks, profile_roles, timer
profile_tasks
插件。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19---
- name: test for timer
hosts: timer
gather_facts: no
tasks:
- name: only one debug
debug:
var: inventory_hostname
- name: shell
shell:
cp /etc/fstab /tmp/
loop: "{{ range(0, 100)|list }}"
- name: scp
copy:
src: /etc/hosts
dest: /tmp/
loop: "{{ range(0, 100)|list }}"
profile_tasks
后在屏幕中输出的计时信息:1
2
3
4
5
6
7
8$ ansible-playbook -i timer.host timer.yml
...................
......省略输出......
...................
=========================================
scp ------------------------------------ 57.96s
shell ---------------------------------- 42.78s
only one debug ------------------------- 0.07s
11.2 Ansible执行流程分析
-vvv
选项,会输出很多调试信息,包括建立的连接、发送的文件等等。-vvv
去执行一个任务并观察输出信息,同时可与我所做的注释做比较。需注意:不同版本的Ansible为每个任务建立的连接数量不同,Ansible 2.9为每个任务建立7次ssh连接。有的资料或书籍中介绍时说只建立二次、三次、四次ssh连接都是有可能的,版本不同确实是有区别的。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37# 1.第一个连接:获取用户家目录,此处为/root
<node1> ESTABLISH SSH CONNECTION FOR USER: None
<node1> SSH: EXEC ssh -vvv ....... '/bin/sh -c '"'"'echo ~ && sleep 0'"'"''
<node1> (0, '/root\n', ......)
# 2.第二个连接:在家目录下创建临时目录,临时目录由配置文件中remote_tmp指令控制
<node1> ESTABLISH SSH CONNECTION FOR USER: None
<node1> SSH: EXEC ssh -vvv ...... '/bin/sh -c '"'"'( umask 77 && mkdir -p "` echo /root/.ansible/tmp/ansible-tmp-1575542743.85-116022411851390 `" && ...... `" ) && sleep 0'"'"''
# 3.第三个连接:探测目标节点的平台和python解释器的版本信息
<node1> Attempting python interpreter discovery
<node1> ESTABLISH SSH CONNECTION FOR USER: None
<node1> SSH: EXEC ssh -vvv ......
# 4.第四个连接:将要执行的模块相关的代码和参数放到本地临时文件中,并使用sftp将任务文件传输到被控节点的临时文件中
<node1> ESTABLISH SSH CONNECTION FOR USER: None
<node1> SSH: EXEC ssh -vvv ......
Using module file /usr/lib/python2.7/site-packages/ansible/modules/system/ping.py
......
<node1> SSH: EXEC sftp ......
<node1> (0, 'sftp> put /root/.ansible/tmp/ansible-local-78628na2FKL/tmpaE1RbJ /root/.ansible/tmp/ansible-tmp-1575542743.85-116022411851390/AnsiballZ_ping.py\n', ......
# 5.第五个连接:对目标节点上的任务文件授以执行权限
<node1> ESTABLISH SSH CONNECTION FOR USER: None
<node1> SSH: EXEC ssh -vvv ...... '/bin/sh -c '"'"'chmod u+x /root/.ansible/tmp/ansible-tmp-1575542743.85-116022411851390/ /root/.ansible/tmp/ansible-tmp-1575542743.85-116022411851390/AnsiballZ_ping.py && sleep 0'"'"''
......
# 6.第六个连接:执行目标节点上的任务
<node1> ESTABLISH SSH CONNECTION FOR USER: None
<node1> SSH: EXEC ssh -vvv ...... '/bin/sh -c '"'"'/usr/bin/python /root/.ansible/tmp/ansible-tmp-1575542743.85-116022411851390/AnsiballZ_ping.py && sleep 0'"'"''
<node1> (0, '\r\n{"invocation": {"module_args": {"data": "pong"}}, "ping": "pong"}\r\n',
......
# 7.第七个连接:删除目标节点上的临时目录
<node1> ESTABLISH SSH CONNECTION FOR USER: None
<node1> SSH: EXEC ssh -vvv ...... '/bin/sh -c '"'"'rm -f -r /root/.ansible/tmp/ansible-tmp-1575542743.85-116022411851390/ > /dev/null 2>&1 && sleep 0'"'"''
......
(1).第一个连接:获取远程主机时行目标用户的家目录,此处为/root (2).第二个连接:在远程家目录下创建临时目录,临时目录可由ansible.cfg中 remote_tmp
指令控制(3).第三个连接:探测目标节点的平台和python解释器的版本信息 (4).第四个连接:将待执行模块的相关代码和参数放到本地临时文件中,并使用sftp将任务文件传输到被控节点的临时文件中 (5).第五个连接:对目标节点上的任务文件授以执行权限 (6).第六个连接:执行目标节点上的任务 (7).第七个连接:删除目标节点上的临时目录,并将执行结果返回给Ansible端
(1).进入第一个play,挑选forks=5设置的5个节点 (2).每个节点执行第一个任务,每个节点都会建立7次ssh连接 (3).每个节点执行第二个任务,每个节点都再次建立7次ssh连接 (4).按照相同逻辑执行该play中其它任务... (5).所有节点执行完该play中的所有任务后,进入下一个play (6).按照上面的流程执行完所有play中的所有任务
11.3 回顾Ansible的执行策略
serail
是play级别的指令,用于指定几个节点作为一批去执行该play,该play执行完后才让下一批节点执行该play中的任务。如果不指定serial,则默认的行为等价于将所有节点当作一批。strategy
指令用于指定节点执行任务时的策略,其侧重点在于节点而在于任务,默认情况下其策略为linear
,表示某个节点先执行完一个任务后等待其余所有节点都执行完该任务,才统一进入下一个任务。另一种策略是free
策略,表示某节点执行完一个任务后不等待其它节点,而是毫不停留的继续执行该play中的剩余任务,直到该play执行完成,才释放节点槽位让其它未执行任务的节点开始执行任务。11.4 加大forks的值
11.5 修改执行策略
strategy=free
便能让这些执行任务的节点彻底放飞自我。只是剩余的一部分节点可能会比较悲剧,它们处于调度不公平的一方。但是从整体来说,先让大部分节点快速完成任务是值得的。11.6 使Ansible异步执行任务
11.6.1 async和poll指令
1
2
3
4
5
6
7
8
9
10- name: it is an async task
copy:
src:
dest:
async: 200
poll: 2
- name: a sync task
copy:
src:
dest:
async
指令表示该任务将以异步的模式执行。async指令的值200表示,如果该后台任务200秒还未完成,则认为该任务失败。poll
指令表示该任务丢入后台后,Ansible每隔多久去检查一次异步任务是否已成功、是否报错等,只有检查到已完成后才认为该异步任务执行完成,才会进入下一个任务。-B N
选项指定async功能,N为超时时长,-P N
选项指定poll功能,N为检查后台任务状况的时间间隔。$ ansible inventory_file -B200 -P 0 -m yum -a 'name=dos2unix' -o -f 20
11.6.2 等待异步任务
T1(async) --> T2(sync) --> T3(sync) --> T4(wait T1) --> T5
async_status
模块,该模块接受一个后台任务的job id作为参数,然后获取该后台任务的状态并返回。(1).ansible_job_id:异步任务的job id (2).finished:表示所等待的异步任务是否已执行完成,值为1表示完成,0表示未完成 (3).started:表示所等待的异步任务是否已开始执行,值为1表示已开始,0表示未开始
1
2
3
4
5
6
7
8
9
10
11
12
13
14- name: Asynchronous yum task
yum:
name: nginx
state: present
async: 1000
poll: 0
register: yum_sleeper
- name: Wait for asynchronous job to end
async_status:
jid: '{{ yum_sleeper.ansible_job_id }}'
register: job_result
until: job_result.finished
retries: 30
yum_sleeper
,该变量中包含一个ansible_job_id
的属性。将该属性交给async_status
模块的jid选项,该模块便可以获取该异步任务的状态,并将状态注册到变量job_result
中,结合until
指令不断等待job_result.finished
事件发生,即表示异步任务执行完成。async_status
模块使用loop循环来完成该功能。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29---
- name: test for timer
hosts: timer
gather_facts: no
tasks:
- name: async task 1
shell: sleep 5
async: 200
poll: 0
register: async_task1
- name: async task 2
shell: sleep 10
async: 200
poll: 0
register: async_task2
- name: waiting for all async task
async_status:
jid: "{{item}}"
register: job_result
until: job_result.finished
loop:
- "{{ async_task1.ansible_job_id }}"
- "{{ async_task2.ansible_job_id }}"
- name: after waiting
debug:
msg: "after waiting"
11.6.3 何时使用异步任务
11.7 开启ssh长连接
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命令是客户端命令)中对应的长连接选项也是可以的。ansible centos -m ping
1
2
3
4
5
6
7
8
9
10
11
12
13
14$ netstat -tnalp
Local Address Foreign Address State PID/Program name
0.0.0.0:22 0.0.0.0:* LISTEN 1143/sshd
127.0.0.1:25 0.0.0.0:* LISTEN 2265/master
192.168.200.26:58474 192.168.200.59:22 ESTABLISHED 31947/ssh: /root/.a
192.168.200.26:22 192.168.200.1:8189 ESTABLISHED 29869/sshd: root@pt
192.168.200.26:37718 192.168.200.64:22 ESTABLISHED 31961/ssh: /root/.a
192.168.200.26:38894 192.168.200.60:22 ESTABLISHED 31952/ssh: /root/.a
192.168.200.26:48659 192.168.200.61:22 ESTABLISHED 31949/ssh: /root/.a
192.168.200.26:33546 192.168.200.65:22 ESTABLISHED 31992/ssh: /root/.a
192.168.200.26:54824 192.168.200.63:22 ESTABLISHED 31958/ssh: /root/.a
:::22 :::* LISTEN 1143/sshd
::1:25 :::* LISTEN 2265/master
.ansible/cp
目录下生成一些socket文件,每个ssh连接会话一个文件。1
2
3
4
5
6
7
8$ ls -l ~/.ansible/cp/
total 0
srw------- 1 root root 0 Jun 3 18:26 5c4a6dce87
srw------- 1 root root 0 Jun 3 18:26 bca3850113
srw------- 1 root root 0 Jun 3 18:26 c89359d711
srw------- 1 root root 0 Jun 3 18:26 cd829456ec
srw------- 1 root root 0 Jun 3 18:26 edb7051c84
srw------- 1 root root 0 Jun 3 18:26 fe17ac7eed
control_path_dir
指令决定。11.7.1 开启ssh长连接后的注意事项
root@B
节点后,A会缓存到B节点的ssh连接,如果此时B节点目标用户root修改了密码,A节点借助缓存下来的ssh长连接仍然能够连接到root@B
节点。11.8 开启Pipelining
1
2$ echo 'hostname -I' | ssh [email protected] 'bash'
192.168.200.48
hostname -I
并将其写入到远程主机上的标准输入供bash命令读取,于是bash命令执行读取到的数据。所以,相当于是在远程主机上执行了echo "hostname -I" | bash
。$ echo 'print("hello world")' | ssh [email protected] 'python'
$ echo 'print("hello world")' | python
pipelining=true
,默认是false,即默认Pipelining是禁用状态。1
2$ grep '^pipelining' /etc/ansible/ansible.cfg
pipelining = True
11.8.1 开启Pipelining后的注意事项
1
2
3
4
5
6
7
8
9---
- name: test for timer
hosts: timer
gather_facts: no
become: yes
become_user: root
become_method: sudo
tasks:
- shell: sleep 1
requiretty
将报错:1
2Pseudo-terminal will not be allocated because stdin is not
a terminal.\r\nsudo: sorry, you must have a tty to run sudo
1
2$ grep requiretty /etc/sudoers
Defaults requiretty # 注释此行表示禁用
1
2
3
4
5$ grep 'ssh_args' /etc/ansible/ansible.cfg
ssh_args = -C -o ControlMaster=auto -o ControlPersist=1d -tt
# 或者在命令行中指定
$ ansible-playbook --ssh-extra-args="-tt"" xxxxxx
11.8.2 开启Pipelining后的执行流程
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36TASK [test task] *******************************************
task path: /root/ansible/timer.yml:6
# 第一个SSH连接,用于探测目标节点上支持的Python版本
<192.168.200.48> Attempting python interpreter discovery
<192.168.200.48> ESTABLISH SSH CONNECTION FOR USER: None
<192.168.200.48> SSH: EXEC ssh -C -o ......
<192.168.200.48> (0, b'
PLATFORM\nLinux\nFOUND\n
/usr/bin/python\n
/usr/bin/python3.6\n
/usr/bin/python2.7\n
/usr/bin/python3\n
/usr/bin/python\n
ENDFOUND\n', b'')
# 第二个SSH连接用于探测目标节点操作系统的信息
<192.168.200.48> ESTABLISH SSH CONNECTION FOR USER: None
<192.168.200.48> SSH: EXEC ssh -C -o ......
<192.168.200.48> (0, b'{"osrelease_content":
"NAME=\\"CentOS Linux\\"\\n
VERSION=\\"7 (Core)\\"\\n
ID=\\"centos\\"\\n
ID_LIKE=\\"rhel fedora\\"\\n
VERSION_ID=\\"7\\"\\n
......b'')
# 准备执行任务,加载任务使用的模板文件,且发现开启了Pipelining
Using module file ......ansible/modules/commands/command.py
Pipelining is enabled.
# 第三个SSH连接用于执行任务
<192.168.200.48> ESTABLISH SSH CONNECTION FOR USER: None
<192.168.200.48> SSH: EXEC ssh -C ......
'/bin/sh -c '"'"'/usr/bin/python && sleep 0'"'"''
<192.168.200.48> (目标节点执行任务返回的结果)
11.8.3 开启和不开启Pipelining的效率比较
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19# 开启Pipelining之前
$ ansible-playbook -i timer.host timer.yml
...................
......省略输出......
...................
=========================================
scp ------------------------------------ 57.96s
shell ---------------------------------- 42.78s
only one debug ------------------------- 0.07s
# 开启Pipelining后
$ ansible-playbook -i timer.host timer.yml
...................
......省略输出......
...................
=========================================
scp ------------------------------------ 39.99s
shell ---------------------------------- 20.29s
only one debug ------------------------- 0.07s
11.9 修改facts收集行为
gather_facts: no
关闭收集功能。gather_subset=!all,!any,network
,这样可以减少收集的数据量,从而提升效率。11.10 Shell层次上的优化:将任务分开执行
1
2
3$ ansible-playbook nginx.yml >/tmp/nginx.log &
$ ansible-playbook mysql.yml >/tmp/mysql.log # 被依赖,所以不后台
$ ansible-playbook php.yml >/tmp/php.log
11.11 第三方策略插件:Mitogen for Ansible
(1).linear (2).free (3).host-pinned (4).debug
1
2
3$ wget 'https://networkgenomics.com/try/mitogen-0.2.9.tar.gz'
$ mkdir -p ~/.ansible/plugins
$ tar xf mitogen-0.2.9.tar.gz -C ~/.ansible/plugins/
1
2
3[defaults]
strategy_plugins = ~/.ansible/plugins/mitogen-0.2.9/ansible_mitogen/plugins/strategy
strategy = mitogen_linear
1
2
3
4
5
6$ ls -1 ~/.ansible/plugins/mitogen-0.2.9/ansible_mitogen/plugins/strategy/
__init__.py
mitogen_free.py
mitogen_host_pinned.py
mitogen_linear.py
mitogen.py
(1). mitogen_linear
对应于Ansible自身的linear策略(2). mitogen_free
对应于Ansible自身的free策略(3). mitogen_host_pinned
对应于Ansible自身的host_pinned策略
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19# 开启Pipelining但未使用mitogen插件
$ ansible-playbook -i timer.host timer.yml
...................
......省略输出......
...................
=========================================
scp ------------------------------------ 39.99s
shell ---------------------------------- 20.29s
only one debug ------------------------- 0.07s
# 开启Pipelining且使用mitogen插件
$ ansible-playbook -i timer.host timer.yml
...................
......省略输出......
...................
=========================================
shell -------------------------------- 8.02s
scp ---------------------------------- 3.37s
only one debug ----------------------- 0.33s
(1).原生Ansible允许使用forks设置最大并发节点数量,但mitogen默认固定最多32个连接,需要修改环境变量 MITOGEN_POOL_SIZE
的值来设置最大并发量。(2).mitogen的sudo处理行为和Ansible不一样,所以可能需要单独在目标节点的sudoer配置中加入对应用户的配置。比如 your_ssh_username = (ALL) NOPASSWD:/usr/bin/python -c*
。
END
官方站点:www.linuxprobe.com
Linux命令大全:www.linuxcool.com
刘遄老师QQ:5604215
Linux技术交流群:2636170
(新群,火热加群中……)
想要学习Linux系统的读者可以点击"阅读原文"按钮来了解书籍《Linux就该这么学》,同时也非常适合专业的运维人员阅读,成为辅助您工作的高价值工具书!
微信扫码关注该文公众号作者
来源:Linux就该这么学
相关新闻
Ansible你快点:Ansible执行过程分析、异步、效率优化最新大模型推理优化进展:英伟达、阿里、腾讯和零一万物专家观点解读|AICon央行2月5日起降准0.5个百分点;上海、苏州优化住房限购政策;「宁王」「迪王」业绩亮眼;菜鸟最快于今年Q1在港上市|一周市场盘点三位地方财政局长的开年:清理税收返还、优化支出结构万字综述大模型高效推理:无问芯穹与清华、上交最新联合研究全面解析大模型推理优化小米获独立造车资质;如祺出行港股上市;光伏、锂矿龙头业绩预亏;证监会:进一步推动程序化高频交易降频降速|一周市场盘点Tomcat 调优总结(Tomcat自身优化、Linux内核优化、JVM优化)直播预告丨刘宁荣:半球化、半冷战时代,中国如何应对?智算中心:AI产业化、产业AI化安省中学“技校”化:学理财、做饭、缝纫、换轮胎....头好痒,要长脑子了!3D资产生成领域福音:自动化所、北邮团队联合打造材质生成新范式极氪上市的背后:盈利、国际化和长期主义|氪金 · 大事件央国企数字化转型与智能化发展:现状、挑战与成功经验剖析1.48 亿、信息化大单:潍坊市公立医院改革与高质量发展示范项目Diffusion反馈强势助力CLIP秒变火眼金睛:智源、自动化所联合推出DIVA推翻经济全球化、怀疑自由民主:西方两大秩序的自我否定品牌高位攻势、价值链不断优化,水井坊厂商携手抢占旺季市场关键窗口期1.37 亿大单、业务技术用房信息化:西安市公安局刘彤教授专访:及时准确诊断、迅速个性化治疗,畅谈心脏结节病的临床诊疗及展望 | OCC-WCC 2024Diffusion 反馈强势助力 CLIP 秒变火眼金睛:北京智源研究院、中科院自动化所联合推出 DIVA嘉宾确认 | 罗培新、王振、洪祖运出席首届优化法治营商环境论坛全国数据标准化技术委员会成员公示:腾讯、抖音、百度、华为、阿里巴巴、浪潮、中兴、新华三、奇安信、三六零、清华大学、北京大学等冇心再优化!最新5.4蓝牙耳机,音质出众、性价堪比AirPods~具身智能离现实有多远:热潮、泡沫、技术前沿、商业化 | 峰瑞研究所